Skip to content
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

Uvicorn should handle headers as any iterables, not just lists (ASGI spec compliance) #366

Closed
JerzySpendel opened this issue May 30, 2019 · 2 comments · Fixed by #367
Closed

Comments

@JerzySpendel
Copy link
Contributor

ASGI Specification in the Response Start says that if I send http.response.start, the headers part should be of the following form:

(Iterable[[byte string, byte string]])

A iterable of [name, value] two-item iterables, where name is the header name, and value is the header value. Order must be preserved in the HTTP response. Header names must be lowercased. Optional; defaults to an empty list.

So let's have an ASGI compliant application of the following form:

async def application(scope, receive, send):
    await send(
        {
            "type": "http.response.start",
            "headers": ([b"content-type", b"text/plain"],),
            "status": 200,
        }
    )
    await send({"type": "http.response.body", "body": b"dupa"})

After requesting this I get the following in the console:

ERROR: Exception in ASGI application
Traceback (most recent call last):
  File "/home/jerzy/venv/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py", line 368, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "./asgi.py", line 9, in application
    "status": 200,
  File "/home/jerzy/venv/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py", line 427, in send
    headers = self.default_headers + message.get("headers", [])
TypeError: can only concatenate list (not "tuple") to list

Looks like the headers have to be list of list, not simple iterable of 2-items iterable. Do you think this is important? If we want to be 100% compliant with ASGI spec uvicorn should handle just any iterables. If you agree, do you think I could prepare a patch?

@tomchristie
Copy link
Member

Seems reasonable, yup.
I guess self.default_headers + list(message.get("headers", [])) would do the trick.

@JerzySpendel
Copy link
Contributor Author

Yep, it helps. I've opened PR with the code you suggested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants