Sha256: 5f2c6c7ebe973a6c1ce136a77e0aed3cf89b482dc6ff2f82515ff70b655fd434

Contents?: true

Size: 1.85 KB

Versions: 1

Compression:

Stored size: 1.85 KB

Contents

module Rack

  # A Rack middleware for providing JSON-P support.
  # 
  # Full credit to Flinn Mueller (http://actsasflinn.com/) for this contribution.
  # 
  class JSONP
  
    def initialize(app)
      @app = app
    end
  
    # 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 <tt>callback</tt> param is specified.
    # 
    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')
      env['QUERY_STRING'] = env['QUERY_STRING'].split("&").delete_if{|param| param =~ /^(_|callback)/}.join("&")
      
      status, headers, response = @app.call(env)
      if callback
        response = pad(callback, response)
        headers['Content-Length'] = response.first.length.to_s
      elsif headers['Content-Type'] =~ /application\/json/
        # 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
  
    # 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.
    # 
    def pad(callback, response, body = "")
      response.each{ |s| body << s }
      ["#{callback}(#{body})"]
    end
    
    def carriage_return(response, body = "")
      response.each{ |s| body << s }
      ["#{body}\n"]
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
cryx-g5k-0.2.11 lib/g5k/rack/jsonp.rb