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 Jul 24, 2020
1 parent f623916 commit ffb0b2b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 0 deletions.
28 changes: 28 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,34 @@
from uvicorn.main import Server


def test_return_close_header():
class App:
def __init__(self, scope):
if scope["type"] != "http":
raise Exception()

async def __call__(self, receive, send):
await send({"type": "http.response.start", "status": 200, "headers": []})
await send({"type": "http.response.body", "body": b"", "more_body": False})

class CustomServer(Server):
def install_signal_handlers(self):
pass

config = Config(app=App, loop="asyncio", limit_max_requests=1)
server = CustomServer(config=config)
thread = threading.Thread(target=server.run)
thread.start()
while not server.started:
time.sleep(0.01)
response = requests.get("http://127.0.0.1:8000", headers={"connection": "close"})
thread.join()
assert response.status_code == 200
assert (
"connection" in response.headers and response.headers["connection"] == "close"
)


def test_run():
class App:
def __init__(self, scope):
Expand Down
3 changes: 3 additions & 0 deletions uvicorn/protocols/http/h11_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def _get_status_phrase(status_code):
STATUS_PHRASES = {
status_code: _get_status_phrase(status_code) for status_code in range(100, 600)
}
CLOSE_HEADER = (b"connection", b"close")

HIGH_WATER_LIMIT = 65536

Expand Down Expand Up @@ -445,6 +446,8 @@ 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(
Expand Down
3 changes: 3 additions & 0 deletions uvicorn/protocols/http/httptools_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def _get_status_line(status_code):
STATUS_LINE = {
status_code: _get_status_line(status_code) for status_code in range(100, 600)
}
CLOSE_HEADER = (b"connection", b"close")

HIGH_WATER_LIMIT = 65536

Expand Down Expand Up @@ -443,6 +444,8 @@ 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(
Expand Down

0 comments on commit ffb0b2b

Please sign in to comment.