0

I am working the TinCan API which is sending non-json objects as a JSON request.

An example of the Request Payload in said request :

AWSAccessKeyId=secret
&Authorization=secret
&activityId=61XkSYC1ht2%5Fcourse%5Fid
&Expires=1395864543
&Content%2DType=application%2Fjson
&actor=null
&registration=760e3480%2Dba55%2D4991%2D94b0%2D01820dbd23a2
&stateId=resume
&Signature=ZNYa7WTtO5rWx%2FAs%2FuFxTQkiYdc%3D

Their documentation explains in a paraphrased form that "The data is being sent as described in section 7.8 Cross Origin Requests of the XAPI spec, where all headers and content are being included as form parameters."

Which you can see is true from the Content key in the example above. That key and its children can be decoded and be parsed as JSON.

But because the initial request is application/json, my app runs into a JSON parse error.

That being said, is there some way to set up the server, or my controllers to accept these CORS requests so that I can properly parse them and use their information?

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Trip
  • 26,756
  • 46
  • 158
  • 277
  • 1
    Why would they be sending in non-JSON content tagged as `application/json`? Can you fix the broken implementation? Worst case scenario: Rack handler to identify these malformed requests and twiddle the content-type header accordingly before passing it through to Rails. – tadman Mar 26 '14 at 19:33
  • That worst case scenario is looking like the only-case scenario. Any recommends on going in that direction how I could do that? – Trip Mar 26 '14 at 19:35

1 Answers1

1

If you're up against the wall and have no way of changing the completely broken client, you might want to try and gracefully recover here.

Usually you can add a filter in your config.ru file for your application that will re-write the damaged headers:

use TinCanFixer

Then you write a Rack handler:

class TinCanFixer
  def initialize(app)
    @app = app
  end

  def call(env)
    case (env["CONTENT_TYPE"])
    when "application/json"
      # Check that it's actually JSON
      unless (env["rack.input"].match(/^\{\[/))
        env["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
      end
    end

    @app.call(env)
  end
end

Untested but should, in principle, sniff out non-JSON content and reassign the rack.input header which dictates content type.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • It looks like my calls are getting canceled before I can capture the call within Rack. Would this have to do with the fact that I'm instantiating the TinCanFixer within an initializer and not my config.ru? – Trip Mar 27 '14 at 09:25
  • 1
    ok got it. I do this `Rails.application.config.middleware.insert_before Rack::Lock, TinCanFixer` – Trip Mar 27 '14 at 09:51
  • I noticed that the call overwrite anything isn't working.. for example in your example, when the call passes through, i see that it didn't actually change the request's `CONTENT_TYPE` – Trip Mar 28 '14 at 15:08
  • Did that line trigger? This just illustrates the general idea. In a Rack handler you have an opportunity to manipulate the `env` before passing it along to the next thing in the chain, in this case `@app`. – tadman Mar 28 '14 at 15:49
  • Ah Ok I'm narrowing this down.. to of course another rabbit hole.. you wouldn't know off hand why none of my URL's can be found in the app when the request is coming from an AWS hosted URL.. would you? :D – Trip Mar 28 '14 at 17:22
  • @trip I don't know what you mean by that. AWS EC2? AWS S3? Something else? – tadman Mar 28 '14 at 17:32
  • It's an aws box that is sending these malformed requests. And when I intercept them in rack and rewrite the URL to anything, including routes in my app I know work; whatever I choose, it returns `ActionController::RoutingError (No route matches [POST] "/quizzes/statements"): lib/site_verification.rb:18:in `call'` Bit of a strange response. I was thinking it had something to do with CORS.. I made a new question here.. http://stackoverflow.com/questions/22712663/getting-a-routing-error-when-my-routes-are-clearly-marked .. – Trip Mar 28 '14 at 18:49