Search code examples
pythonwebcorsbottle

Returning HTTPResponse object in bottle loses response headers


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?


Solution

  • 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.