Flask replaces the content of my Location header when building my HTTP response. It change my actual relative URI Location header with an absolute one.
@app.route('/votes', methods=['POST'])
def votes():
return jsonify(), 201, {'location': '/votes/1'}
my test :
def test_vote_creation(self):
response = self.app.post('/votes',
data=json.dumps({
'name': 'Test vote'
}), content_type='application/json')
print(response.headers['location'])
return http://localhost/votes/1
instead of /votes/1
How to return a relative URI Location header with Flask jsonify ?
Edit: According to the current version of the HTTP/1.1 standard, RFC 2616, the value of the Location header must be an absolute URI. But the RCF is going to change to allow relative URIs as well. So I want to change the default behaviour of my API to answer with a relative URI in my location header.
more detail on this post
The HTTP RFC specifies that the Location
header must be an absolute URI:
14.30 Location
The Location response-header field is used to redirect the recipient to a location other than the Request-URI for completion of the request or identification of a new resource. For 201 (Created) responses, the Location is that of the new resource which was created by the request. For 3xx responses, the location SHOULD indicate the server's preferred URI for automatic redirection to the resource. The field value consists of a single absolute URI.
Location = "Location" ":" absoluteURI
As such the Flask / Werkzeug response object converts any relative URL Location
header to an an absolute URL.
You can override this behaviour, although I would not recommend you do so. To override it, set the autocorrect_location_header
attribute of a Response
object to False
. jsonify()
returns a response object, alter that:
@app.route('/votes', methods=['POST'])
def votes():
response = jsonify()
response.status_code = 201
response.headers['location'] = '/votes/1'
response.autocorrect_location_header = False
return response
but note that your WSGI server can still enforce an absolute URL even if Flask doesn't.