New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Returning Response and headers causes duplicate headers #3628
Comments
I don't know if we should change this behavior, but if you want to set the default mimetype (e.g. Content-Type value) for JSON response, you should use the app.config['JSONIFY_MIMETYPE'] = 'application/json+somecustomtype' This will work when you use |
I don't think he wants to change it globally. Since duplicate content-type headers make no sense I think it's reasonable to take the one from the return value |
@greyli thanks, we need to support multiple different content-types for JSON in the same app. I think this is pretty common for production APIs that have been around for a while like ours. |
Before we do anything, I want to understand why headers are extended rather than appended right now. I think I was the last one to touch this code, and either it was already like that or I made a decision about it during refactoring. If you want to control the headers, instead of using the shortcut, get the response and set the headers directly: response = jsonify(...)
response.headers.set('Content-Type', 'custom')
return response |
This behavior is explicitly documented in
Changing this is not compatible with that. There is no way to change the shortcut to satisfy all use cases. Some headers should be replaced, some should be extended, but Flask doesn't have insight into those semantics. |
Looking at the history, returning a dict of headers has used |
Given that, return "xyz", {"Content-Type": "text/xml"} returns xml content type despite it actually returning return {}, {"Content-Type": "text/xml"} should return a xml content type as well, despite it actually returning |
@davidism I think you're right, if you use jsonify and headers with a 'Content-Type' that's a programming error and nothing can be done, but I think there is a real issue when returning a dict body. When a str/bytes/bytearray body is returned any returned headers are passed to to response_class and the logic of werkzeug BaseResponse means that if 'Content-Type' is in the headers it is used, in this case the headers are then set to None and so not extended into the response object headers. But if the body returned is a dict, jsonify pass a mimetype argument to werkzeug BaseResponse which will set 'Content-Type', then the headers will be extended and if there is a 'Content-Type' the response object will now have two 'Content-Type' headers. I'm suggesting this behaviour is a bug and the dict body case should act similarly to the str case. From make_response:
|
If we change it the way you're describing, |
I think that is understandable as My corollary is that |
Returning a dict is just a shortcut for calling I definitely recognize there's an issue with the inconsistency. Either the headers should always use I'd be more willing to always use |
@pgjones @ThiefMaster thoughts on using |
I feel like this might even have been unintentional. The original code constructed the response object with those arguments and in that case it would have overwritten the keys and not extended. |
Yes, I wasn't quite sure why the change used |
I think switching to |
I think single value headers are more common than multi-line headers, and based on discussion using |
Expected Behavior
Using
curl -v http://127.0.0.1:5000/
to query the view I expect only oneContent-Type
header >Content-Type: test
Actual Behavior
Duplicate headers are returned
Environment
Context
This issue also effects responses created with make_response when using a dict or jsonify body + the headers argument with a 'Content-Type':
This issue is caused by jsonify adding a 'Content-Type' header then make_response uses
extent
to add the additional headers, thus leading to the duplicate.Returning a str/bytes body does not have this problem as no 'Content-Type' is added by flask, if one is missing it is added by werkzeug.
The reason I came across this issue is we have older code which does
return json.dumps(data), 200, {'Content-Type': 'application/json+somecustomtype'}
and I assumed based on the flask docs that just returning the data and letting flask do the jsonify would be better.The text was updated successfully, but these errors were encountered: