An HTTP 304 (Not Modified) response should be zero length and should contain headers appropriate to the 200 that would have resulted otherwise.
There does not seem to be a way to send a response without either a Content-Length or Content-Type header (neither of which are appropriate for a zero-length response) and either of which could upset the cache content if the cache were to update its headers from this response.
cf. https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
The 304 response MUST NOT contain a message-body
I can see that this relates to the same issue 1102 @r0fls shall I include this status code in there as well?
closing per #1113
Hi, it looks like #1113 still emits a Content-Length header for a 304, but the RFC states at the very least that it SHOULD NOT, and in particular cases that it MUST NOT:
If the conditional GET used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. Otherwise (i.e., the conditional GET used a weak validator), the response MUST NOT include other entity-headers; this prevents inconsistencies between cached entity-bodies and updated headers.
The headers it permits are Date, ETag, Vary, Content-Location, Expires, and Cache-Control.
Have I misread the RFC?
Thanks @mike-hart
Sounds like it should remove these other ones as well for 304 responses, Connection, Keep-Alive and Content-Type
< HTTP/1.1 304 Not Modified
< Connection: keep-alive
< Keep-Alive: 5
< Content-Type: application/json
I'm not sure there should necessarily be an outright removal of things, but perhaps the option of having a user-added-only set of headers for a response would be good. The dev can break as many rules as they please, but the framework won't make that any worse for them :)
Status code 206 for example may be similarly afflicted.
Hmmm... well I guess that removing/adding certain headers per http response is sort of a bigger PR than the one I did, as the one PR I did was basically only covering the content-length mismatch.
Moreover on this topic, I would propose that if a user specifies a Header then it has priority over the ones that sanic will add, and if None is assigned to a header then this will be not added at all to the HTTP Response, therefore following the idea you have of letting the users manipulate the headers as they wish.
i.E.
# just some quick demo code...
@app.route("/")
async def handle(request):
return json({'key': 'value'},
headers={'Connection': 'close', 'ETag': None, 'X-Header': 'my-value'})
This will follow:
close (overriding alive connection)my-valueIf we want to avoid certain headers per status code, at sanic's "default" level then we would need to implement this feature. Either by avoiding headers per status codes or having templates per status codes.
But for this I think we need to align on this... From my side, I'll take some time and read again the whole RFC and try to come up with something more proper to propose, but if you guys have something already in mind well bring it on :)
I guess it's a bigger question of what we should do here. Maybe a good idea to look to some other frameworks.
@r0fls I have created a PR with more updates regarding on this topic. Furthermore, I haven't been able to identify the cases when the Connection, Keep-Alive and Content-Type headers should be removed in a 304 response status, could you please explain me the reasons why they should be removed?
The problem with the status 206 and not including Entity Headers as for the strong validator is that it depends on the IF-Range request header...
If the 206 response is the result of an If-Range request that used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. If the response is the result of an If-Range request that used a weak validator, the response MUST NOT include other entity-headers; this prevents inconsistencies between cached entity-bodies and updated headers. Otherwise, the response MUST include all of the entity-headers that would have been returned with a 200 (OK) response to the same request.
206 (SHOULD/MUST) NOT include entity Headers if IF-Range header in request is present, but if its not then include entity headers.
Maybe to offer a flag?
Will take a look... other day
I'm going to close this since @arnulfojr fixed it in his PR. @mike-hart please feel free to reopen if you still see any issues.
Most helpful comment
Hi, it looks like #1113 still emits a Content-Length header for a 304, but the RFC states at the very least that it SHOULD NOT, and in particular cases that it MUST NOT:
The headers it permits are Date, ETag, Vary, Content-Location, Expires, and Cache-Control.
Have I misread the RFC?