I have a bottle server (whose underlying http server has been swapped out with a multi-threaded CherryPy) in which one of my routes (a 'POST')returns an HTTP response instead of a json dictionary directly, eg:
return HTTPResponse(status=200,body=json.dumps({'body':'my body'})
Now, I have added 'after_request'
hook to my bottle app so that it will set headers on the response to handle CORS, eg, in my after_request
hook I have:
bottle.response.set_header('Access-Control-Allow-Origin', '*')
And I can confirm the after_request
function runs and sets the headers successfully on bottle.response
.
BUT, my route function returns BEFORE the after_request function runs, and so my browser still sees none of those headers in the response message.
However, if I just modify my route function to return a simple json dict, instead of HTTPResponse
, eg:
return json.dumps({'body':'my body'}
Then suddenly, the browser sees the headers set by my after_request hook. Even though the rest of my code is unchanged.
What gives? Why does returning HTTPResponse
makes me lose all the headers, but returning just a simple json does not?
Try setting the headers in the new object that you're returning, like this:
return HTTPResponse(status=200, body=json.dumps({'body': 'my body'}, headers={'Access-Control-Allow-Origin': '*'})
My guess is that the after_request
hook is operating on the "magic" response object that Bottle manages for you - so when you create and return a new one, its headers aren't modified.