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

Revert "Fix ensure http connection is closed" #1354

Merged
merged 1 commit into from Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 15 additions & 8 deletions uvicorn/_handlers/http.py
Expand Up @@ -7,9 +7,6 @@
from uvicorn.server import ServerState


MAX_RECV = 2 ** 16


async def handle_http(
reader: asyncio.StreamReader,
writer: asyncio.StreamWriter,
Expand All @@ -36,13 +33,13 @@ async def handle_http(
# Use a future to coordinate between the protocol and this handler task.
# https://docs.python.org/3/library/asyncio-protocol.html#connecting-existing-sockets
loop = asyncio.get_event_loop()
reader_read = asyncio.create_task(reader.read(MAX_RECV))
connection_lost = loop.create_future()

# Switch the protocol from the stream reader to our own HTTP protocol class.
protocol = config.http_protocol_class( # type: ignore[call-arg, operator]
config=config,
server_state=server_state,
on_connection_lost=reader_read.cancel,
on_connection_lost=lambda: connection_lost.set_result(True),
)
transport = writer.transport
transport.set_protocol(protocol)
Expand All @@ -59,7 +56,7 @@ async def handle_http(

@task.add_done_callback
def retrieve_exception(task: asyncio.Task) -> None:
exc = task.exception() if not task.cancelled() else None
exc = task.exception()

if exc is None:
return
Expand All @@ -77,5 +74,15 @@ def retrieve_exception(task: asyncio.Task) -> None:

# Kick off the HTTP protocol.
protocol.connection_made(transport)
data = await reader_read
protocol.data_received(data)

# Pass any data already in the read buffer.
# The assumption here is that we haven't read any data off the stream reader
# yet: all data that the client might have already sent since the connection has
# been established is in the `_buffer`.
data = reader._buffer # type: ignore
if data:
protocol.data_received(data)

# Let the transport run in the background. When closed, this future will complete
# and we'll exit here.
await connection_lost
4 changes: 0 additions & 4 deletions uvicorn/protocols/http/h11_impl.py
Expand Up @@ -222,10 +222,6 @@ def handle_events(self):
continue
self.cycle.more_body = False
self.cycle.message_event.set()
elif event_type is h11.ConnectionClosed:
break
if self.conn.our_state is h11.MUST_CLOSE and not self.transport.is_closing():
self.transport.close()

def handle_upgrade(self, event):
upgrade_value = None
Expand Down
2 changes: 0 additions & 2 deletions uvicorn/protocols/http/httptools_impl.py
Expand Up @@ -136,8 +136,6 @@ def data_received(self, data):
self.transport.close()
except httptools.HttpParserUpgrade:
self.handle_upgrade()
if data == b"" and not self.transport.is_closing():
self.transport.close()

def handle_upgrade(self):
upgrade_value = None
Expand Down