#32586: ASGI responses from Django do not provide lowercased HTTP headers as
required by the spec
-----------------------------------------+------------------------
               Reporter:  Andrew Myers   |          Owner:  nobody
                   Type:  Bug            |         Status:  new
              Component:  HTTP handling  |        Version:  3.1
               Severity:  Normal         |       Keywords:
           Triage Stage:  Unreviewed     |      Has patch:  0
    Needs documentation:  0              |    Needs tests:  0
Patch needs improvement:  0              |  Easy pickings:  0
                  UI/UX:  0              |
-----------------------------------------+------------------------
 Every time HTTP headers are talked about in the ASGI spec it always says:
 "Header names must be lowercased."

 They never explain why they should be in lowercase, which maybe is a bug
 in the spec, but it turns out http headers are to be treated case
 insensitively https://stackoverflow.com/questions/5258977/are-http-
 headers-case-sensitive

 Using Django 3.1.7 and uvicorn and adding a ASGI middleware like this:

 {{{
 class SpamMiddleware:
     def __init__(self, app):
         self.app = app

     async def __call__(self, scope, receive, send):
         print(f"start {scope!r}")
         async def send_wrapper(message):
             print(f"send {message!r}")
             return await send(message)
         async def receive_wrapper():
             message = await receive()
             print(f"receive {message!r}")
             return message

         return await self.app(scope, receive_wrapper, send_wrapper)
 }}}

 you can see that django does not follow the spec:

 {{{
 send {'type': 'http.response.start', 'status': 200, 'headers': [(b
 'Content-Type', b'application/javascript; charset="utf-8"'), (b'X-Frame-
 Options', b'DENY'), (b'Vary', b'Cookie'), (b'Content-Length', b'189761')]}
 }}}

 A possible fix (and I would be happy to make a PR) is to add a call to
 {{{.lower()}}} on the header name on
 
https://github.com/django/django/blob/76c0b32f826469320c59709d31e2f2126dd7c505/django/core/handlers/asgi.py#L227

 The upside, beyond being spec compliant, would be that middleware that
 need to filter/modify headers wouldn't need to apply {{{.lower()}}}
 themselves.

 This all came up because I'm attempting to add the zerocopysend extension
 to uvicorn and middleware to translate the X-Sendfile header from django-
 sendfile2 to using zerocopysend.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/32586>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/048.3efc2af7f82400c44227648da2d08f51%40djangoproject.com.

Reply via email to