Provide an alternative to request.META for accessing HTTP headers
|Reported by:||lukeplant||Owned by:||nobody|
|Cc:||marc.tamlyn@…, tom@…, ben@…||Triage Stage:||Accepted|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
From the docs:
A standard Python dictionary containing all available HTTP headers...
With the exception of CONTENT_LENGTH and CONTENT_TYPE, as given above, any HTTP headers in the request are converted to META keys by converting all characters to uppercase, replacing any hyphens with underscores and adding an HTTP_ prefix to the name. So, for example, a header called X-Bender would be mapped to the META key HTTP_X_BENDER.
The question is, why? Why do we have this ridiculous transform? It is pure silliness, whose only explanation is a quirk of CGI, which is now totally irrelevant.
You should be able to look up a header in the HTTP spec and do something very simple to get it from the HTTP request. How about this API:
(for consistency with GET/POST/FILES etc.), or even
Dictionary access should obey HTTP rules about case-sensitivity of the header names.
This also would has the advantage that repr(request) wouldn't have lots of junk you don't need i.e. the entire content of os.environ, which, on a developer machine especially, can have a lot of noise (mine does).
It also future-proofs us for when WSGI is replaced with something more sensible, and the whole silly round trip to os.environ can be removed completely, or if we want to support something else parallel to WSGI and client code wants to access HTTP headers in the same way for both.
This leaves a few things in META that are not derived from an HTTP header, and do not have a way of accessing them from the request object. I think these are just:
- SCRIPT_NAME - this is a CGI leftover, that is only useful in constructing other things, AFAICS
- QUERY_STRING - this can be easily constructed from request.get_full_path() for the rare times that you need the raw query string rather than request.GET
- SERVER_NAME - should use get_host() instead
- SERVER_PORT - use get_host()
- SERVER_PROTOCOL - could use is_secure(), but perhaps it would be nice to have a convenience get_protocol() method.
Change History (15)
comment:12 Changed 2 years ago by aaugustin
- Summary changed from Replace and deprecate request.META for HTTP headers to Provide an alternative to request.META for accessing HTTP headers
- Triage Stage changed from Unreviewed to Accepted