Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions httpx/dispatch/http2.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import functools
import typing
import logging

import h2.connection
import h2.events
Expand All @@ -9,6 +10,8 @@
from ..interfaces import BaseReader, BaseWriter, ConcurrencyBackend
from ..models import AsyncRequest, AsyncResponse

logger = logging.getLogger(__name__)


class HTTP2Connection:
READ_NUM_BYTES = 4096
Expand Down Expand Up @@ -62,6 +65,7 @@ async def close(self) -> None:
await self.writer.close()

def initiate_connection(self) -> None:
logger.debug("H2 Connection initiating")
self.h2_state.initiate_connection()
data_to_send = self.h2_state.data_to_send()
self.writer.write_no_block(data_to_send)
Expand All @@ -79,6 +83,7 @@ async def send_headers(
] + [(k, v) for k, v in request.headers.raw if k != b"host"]
self.h2_state.send_headers(stream_id, headers)
data_to_send = self.h2_state.data_to_send()
logger.debug("Stream [%d] - Sending headers: %r", stream_id, data_to_send)
await self.writer.write(data_to_send, timeout)
return stream_id

Expand All @@ -90,6 +95,7 @@ async def send_request_data(
) -> None:
try:
async for data in stream:
logger.debug("Stream [%d] - Sending data chunk: %r", stream_id, data)
await self.send_data(stream_id, data, timeout)
await self.end_stream(stream_id, timeout)
finally:
Expand All @@ -105,11 +111,15 @@ async def send_data(
chunk = data[idx : idx + chunk_size]
self.h2_state.send_data(stream_id, chunk)
data_to_send = self.h2_state.data_to_send()
logger.debug("Stream [%d] - Sending data: %d", stream_id, len(data_to_send))
await self.writer.write(data_to_send, timeout)

async def end_stream(self, stream_id: int, timeout: TimeoutConfig = None) -> None:
self.h2_state.end_stream(stream_id)
data_to_send = self.h2_state.data_to_send()
logger.debug(
"Stream [%d] - Ending request stream with data: %r", stream_id, data_to_send
)
await self.writer.write(data_to_send, timeout)

async def receive_response(
Expand All @@ -120,6 +130,9 @@ async def receive_response(
"""
while True:
event = await self.receive_event(stream_id, timeout)
logger.debug(
"Stream [%d] - Event received for response: %r", stream_id, event
)
# As soon as we start seeing response events, we should enable
# read timeouts, if we haven't already.
self.timeout_flags[stream_id].set_read_timeouts()
Expand All @@ -140,6 +153,7 @@ async def body_iter(
) -> typing.AsyncIterator[bytes]:
while True:
event = await self.receive_event(stream_id, timeout)
logger.debug("Stream [%d] - Event received: %r", stream_id, event)
if isinstance(event, h2.events.DataReceived):
self.h2_state.acknowledge_received_data(len(event.data), stream_id)
yield event.data
Expand All @@ -152,6 +166,7 @@ async def receive_event(
while not self.events[stream_id]:
flag = self.timeout_flags[stream_id]
data = await self.reader.read(self.READ_NUM_BYTES, timeout, flag=flag)
logger.debug("Stream [%d] - Received response events: %r", stream_id, data)
events = self.h2_state.receive_data(data)
for event in events:
if getattr(event, "stream_id", 0):
Expand All @@ -163,6 +178,7 @@ async def receive_event(
return self.events[stream_id].pop(0)

async def response_closed(self, stream_id: int) -> None:
logger.debug("Stream [%d] - Closing response", stream_id)
del self.events[stream_id]
del self.timeout_flags[stream_id]

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def get_packages(package):
"certifi",
"chardet==3.*",
"h11==0.8.*",
"h2==3.*",
"h2>=3.1.1",
"hstspreload",
"idna==2.*",
"rfc3986==1.*",
Expand Down