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
®istration=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?
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.