Class: Rack::JSONP

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

Overview

A Rack middleware for providing JSON-P support.

Adapted from Flinn Mueller (actsasflinn.com/).

Constant Summary collapse

VERSION =
"1.2.0"

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ JSONP

Returns a new instance of JSONP.



12
13
14
15
16
# File 'lib/rack/jsonp.rb', line 12

def initialize(app, options = {})
  @app = app
  @carriage_return = options[:carriage_return] || false
  @callback_param = options[:callback_param] || 'callback'
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.

Changes nothing if no callback param is specified.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rack/jsonp.rb', line 23

def call(env)
  # remove the callback and _ parameters BEFORE calling the backend,
  # so that caching middleware does not store a copy for each value of the callback parameter
  request = Rack::Request.new(env)
  callback = request.params.delete(@callback_param)
  env['QUERY_STRING'] = env['QUERY_STRING'].split("&").delete_if{|param| param =~ /^(_|#{@callback_param})=/}.join("&")

  status, headers, response = @app.call(env)
  if callback && headers['Content-Type'] =~ /json/i
    response = pad(callback, response)
    headers['Content-Length'] = response.first.length.to_s
    headers['Content-Type'] = 'application/javascript'
  elsif @carriage_return && headers['Content-Type'] =~ /json/i
    # add a \n after the response if this is a json (not JSONP) response
    response = carriage_return(response)
    headers['Content-Length'] = response.first.length.to_s
  end
  [status, headers, response]
end

#carriage_return(response, body = "") ⇒ Object



55
56
57
58
# File 'lib/rack/jsonp.rb', line 55

def carriage_return(response, body = "")
  response.each{ |s| body << s.to_s }
  ["#{body}\n"]
end

#pad(callback, response, body = "") ⇒ Object

Pads the response with the appropriate callback format according to the JSON-P spec/requirements.

The Rack response spec indicates that it should be enumerable. The method of combining all of the data into a single string makes sense since JSON is returned as a full string.



50
51
52
53
# File 'lib/rack/jsonp.rb', line 50

def pad(callback, response, body = "")
  response.each{ |s| body << s.to_s }
  ["#{callback}(#{body})"]
end