Repository: encode/starlette

Issue:
WSGI mount error
When I mount a django application and try to access it

```
ERROR: Exception in ASGI application
Traceback (most recent call last):
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 375, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\applications.py", line 134, in __call__
    await self.error_middleware(scope, receive, send)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\middleware\errors.py", line 178, in __call__
    raise exc from None
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\middleware\errors.py", line 156, in __call__
    await self.app(scope, receive, _send)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\exceptions.py", line 73, in __call__
    raise exc from None
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\exceptions.py", line 62, in __call__
    await self.app(scope, receive, sender)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\routing.py", line 590, in __call__
    await route(scope, receive, send)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\routing.py", line 352, in __call__
    await self.app(scope, receive, send)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\middleware\wsgi.py", line 62, in __call__
    await responder(receive, send)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\middleware\wsgi.py", line 91, in __call__
    await asyncio.wait_for(sender, None)
  File "c:\users\abers\appdata\local\programs\python\python37\Lib\asyncio\tasks.py", line 414, in wait_for
    return await fut
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\middleware\wsgi.py", line 106, in sender
    await send(message)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\exceptions.py", line 59, in sender
    await send(message)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\starlette\middleware\errors.py", line 153, in _send
    await send(message)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 449, in send
    status_code=status_code, headers=headers, reason=reason
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\h11\_events.py", line 47, in __init__
    self.headers, _parsed=_parsed)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\h11\_headers.py", line 75, in normalize_and_validate
    validate(_field_value_re, value, "Illegal header value {!r}", value)
  File "C:\Users\AberS\Documents\Coding\lexiang\lebu\.venv\lib\site-packages\h11\_util.py", line 96, in validate
    raise LocalProtocolError(msg)
h11._util.LocalProtocolError: Illegal header value b' sessionid=""; expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/'
```

This is my minimal implementation code, `lebu` is my django program

```python
from starlette.applications import Starlette
from starlette.middleware.wsgi import WSGIMiddleware
import uvicorn

from lebu.wsgi import application

app = Starlette(debug=True)
app.mount("/api", WSGIMiddleware(application))

if __name__ == "__main__":
    uvicorn.run(app)
```

By the way, starlette version is 0.12.9


Discussion:
Okay, looks like `h11` rejects HTTP headers with leading/trailing whitespace as illegal... https://h11.readthedocs.io/en/latest/changes.html

I think we'll *probably* want to deal with this corner case in `uvicorn`, and ensure that it strips any leading/trailing whitespace from response headers. I'd be interested to know *exactly* how gunicorn handles it.

The issue could also be fixed in Django, since *technically* the header value isn't legal. (But it'd be nice if servers handled it gracefully all the same.)
Yeah, I agree you. But Django seems to be focusing on development 3.0, I think it is more reliable in uvicorn. 
Maybe I can help you, let me first look at uvicorn's handling of this part.

Resolving patch:
diff --git a/starlette/middleware/wsgi.py b/starlette/middleware/wsgi.py
--- a/starlette/middleware/wsgi.py
+++ b/starlette/middleware/wsgi.py
@@ -120,7 +120,7 @@ def start_response(
             status_code_string, _ = status.split(" ", 1)
             status_code = int(status_code_string)
             headers = [
-                (name.encode("ascii"), value.encode("ascii"))
+                (name.strip().encode("ascii"), value.strip().encode("ascii"))
                 for name, value in response_headers
             ]
             self.send_queue.append(


Test patch: