Class: Rack::JSONP

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/rack/contrib/jsonp.rb

Overview

A Rack middleware for providing JSON-P support.

Full credit to Flinn Mueller (actsasflinn.com/) for this contribution.

Constant Summary collapse

VALID_CALLBACK =
/\A[a-zA-Z_$](?:\.?[\w$])*\z/

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ JSONP

Returns a new instance of JSONP.



29
30
31
# File 'lib/rack/contrib/jsonp.rb', line 29

def initialize(app)
  @app = app
end

Instance Method Details

#call(env) ⇒ Object

Proxies the request to the application, stripping out the JSON-P callback method and padding the response with the appropriate callback format if the returned body is application/json

Changes nothing if no callback param is specified.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rack/contrib/jsonp.rb', line 39

def call(env)
  request = Rack::Request.new(env)

  status, headers, response = @app.call(env)

  if STATUS_WITH_NO_ENTITY_BODY.include?(status)
    return status, headers, response
  end

  headers = HEADERS_KLASS.new.merge(headers)

  if is_json?(headers) && has_callback?(request)
    callback = request.params['callback']
    return bad_request unless valid_callback?(callback)

    response = pad(callback, response)

    # No longer json, its javascript!
    headers['Content-Type'] = headers['Content-Type'].gsub('json', 'javascript')

    # Set new Content-Length, if it was set before we mutated the response body
    if headers['Content-Length']
      length = response.map(&:bytesize).reduce(0, :+)
      headers['Content-Length'] = length.to_s
    end
  end

  [status, headers, response]
end