Class: Rack::JSONP
- Inherits:
-
Object
- Object
- Rack::JSONP
- Defined in:
- lib/rack/jsonp.rb
Overview
A Rack middleware for providing JSON-P support.
Adapted from Flinn Mueller (actsasflinn.com/).
Instance Method Summary collapse
-
#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.
- #carriage_return(response, body = "") ⇒ Object
-
#close(io) ⇒ Object
Close original response if it was Rack::BodyProxy (or anything else responding to close, as we’re going to lose it anyway), or it will cause thread failures with newer Rack.
-
#initialize(app, options = {}) ⇒ JSONP
constructor
A new instance of JSONP.
-
#pad(callback, response, body = "") ⇒ Object
Pads the response with the appropriate callback format according to the JSON-P spec/requirements.
Constructor Details
#initialize(app, options = {}) ⇒ JSONP
Returns a new instance of JSONP.
10 11 12 13 14 15 |
# File 'lib/rack/jsonp.rb', line 10 def initialize(app, = {}) @app = app @carriage_return = [:carriage_return] || false @callback_param = [:callback_param] || 'callback' @timestamp_param = [:timestamp_param] || '_' 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 42 43 44 45 46 47 48 49 |
# 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) = request.params.delete(@timestamp_param) env['QUERY_STRING'] = env['QUERY_STRING'].split("&").delete_if{|param| param =~ /^(#{@timestamp_param}|#{@callback_param})=/ }.join("&") env['rack.jsonp.callback'] = callback env['rack.jsonp.timestamp'] = status, headers, response = @app.call(env) if callback && headers['Content-Type'] =~ /json/i response = pad(callback, response) headers['Content-Length'] = response.first.bytesize.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.bytesize.to_s end [status, headers, response] end |
#carriage_return(response, body = "") ⇒ Object
64 65 66 67 68 |
# File 'lib/rack/jsonp.rb', line 64 def carriage_return(response, body = "") response.each{ |s| body << s.to_s } close(response) ["#{body}\n"] end |
#close(io) ⇒ Object
Close original response if it was Rack::BodyProxy (or anything else responding to close, as we’re going to lose it anyway), or it will cause thread failures with newer Rack.
73 74 75 |
# File 'lib/rack/jsonp.rb', line 73 def close(io) io.close if io.respond_to?(:close) 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.
58 59 60 61 62 |
# File 'lib/rack/jsonp.rb', line 58 def pad(callback, response, body = "") response.each{ |s| body << s.to_s } close(response) ["#{callback}(#{body})"] end |