Skip to content

Commit

Permalink
return 'connection: close' header in response
Browse files Browse the repository at this point in the history
According to https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html a
server should return the 'connection: close' header in the response when
a request has that header. Resolves #720
  • Loading branch information
RmStorm committed Jan 25, 2021
1 parent 320fd6d commit 1c32370
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
15 changes: 15 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ async def app(scope, receive, send):
await send({"type": "http.response.body", "body": b"", "more_body": False})


@pytest.mark.asyncio
async def test_return_close_header():
config = Config(app=app, host="localhost", loop="asyncio", limit_max_requests=1)
async with run_server(config):
async with httpx.AsyncClient() as client:
response = await client.get(
"http://127.0.0.1:8000", headers={"connection": "close"}
)

assert response.status_code == 204
assert (
"connection" in response.headers and response.headers["connection"] == "close"
)


@pytest.mark.asyncio
@pytest.mark.parametrize(
"host, url",
Expand Down
5 changes: 5 additions & 0 deletions uvicorn/protocols/http/h11_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def _get_status_phrase(status_code):
status_code: _get_status_phrase(status_code) for status_code in range(100, 600)
}

CLOSE_HEADER = (b"connection", b"close")

HIGH_WATER_LIMIT = 65536

TRACE_LOG_LEVEL = 5
Expand Down Expand Up @@ -452,6 +454,9 @@ async def send(self, message):
status_code = message["status"]
headers = self.default_headers + message.get("headers", [])

if CLOSE_HEADER in self.scope["headers"] and CLOSE_HEADER not in headers:
headers = headers + [CLOSE_HEADER]

if self.access_log:
self.access_logger.info(
'%s - "%s %s HTTP/%s" %d',
Expand Down
5 changes: 5 additions & 0 deletions uvicorn/protocols/http/httptools_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def _get_status_line(status_code):
status_code: _get_status_line(status_code) for status_code in range(100, 600)
}

CLOSE_HEADER = (b"connection", b"close")

HIGH_WATER_LIMIT = 65536

TRACE_LOG_LEVEL = 5
Expand Down Expand Up @@ -454,6 +456,9 @@ async def send(self, message):
status_code = message["status"]
headers = self.default_headers + list(message.get("headers", []))

if CLOSE_HEADER in self.scope["headers"] and CLOSE_HEADER not in headers:
headers = headers + [CLOSE_HEADER]

if self.access_log:
self.access_logger.info(
'%s - "%s %s HTTP/%s" %d',
Expand Down

0 comments on commit 1c32370

Please sign in to comment.