Skip to content
This repository was archived by the owner on Jan 13, 2021. It is now read-only.

Commit 95002fb

Browse files
committed
Pull headers logic into own function.
This is for use later down the line when we add support for provisional responses.
1 parent 7543d22 commit 95002fb

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

hyper/http20/stream.py

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -228,23 +228,22 @@ def receive_frame(self, frame):
228228
pass
229229

230230
if 'END_HEADERS' in frame.flags:
231+
# Begin by decoding the header block. If this fails, we need to
232+
# tear down the entire connection. TODO: actually do that.
231233
headers = self._decoder.decode(b''.join(self.header_data))
232234

233-
# The header block may be for trailers or headers. If we've already
234-
# received headers these _must_ be for trailers.
235+
# If we're involved in a PUSH_PROMISE sequence, this header block
236+
# is the proposed request headers. Save it off. Otherwise, handle
237+
# it as an in-stream HEADERS block.
235238
if (self.promised_stream_id is None):
236-
if self.response_headers is None:
237-
self.response_headers = headers
238-
elif self.response_trailers is None:
239-
self.response_trailers = headers
240-
else:
241-
# Received too many headers blocks.
242-
raise ProtocolError("Too many header blocks.")
239+
self._handle_header_block(headers)
243240
else:
244241
self.promised_headers[self.promised_stream_id] = headers
245242

243+
# We've handled the headers, zero them out.
246244
self.header_data = None
247245

246+
248247
def open(self, end):
249248
"""
250249
Open the stream. Does this by encoding and sending the headers: no more
@@ -334,6 +333,39 @@ def close(self, error_code=None):
334333
# connection.
335334
self._close_cb(self.stream_id, error_code)
336335

336+
def _handle_header_block(self, headers):
337+
"""
338+
Handles the logic for receiving a completed headers block.
339+
340+
A headers block is an uninterrupted sequence of one HEADERS frame
341+
followed by zero or more CONTINUATION frames, and is terminated by a
342+
frame bearing the END_HEADERS flag.
343+
344+
HTTP/2 allows receipt of up to three such blocks on a stream. The first
345+
is optional, and contains a 1XX response. The second is mandatory, and
346+
must contain a final response (200 or higher). The third is optional,
347+
and may contain 'trailers', headers that are sent after a chunk-encoded
348+
body is sent. This method enforces the logic associated with this,
349+
storing the headers in the appropriate places.
350+
"""
351+
352+
# At this stage we should check for a provisional response (1XX). As
353+
# hyper doesn't currently support such responses, we'll leave that as a
354+
# TODO.
355+
# TODO: Handle 1XX responses here.
356+
357+
# The header block may be for trailers or headers. If we've already
358+
# received headers these _must_ be for trailers.
359+
if self.response_headers is None:
360+
self.response_headers = headers
361+
elif self.response_trailers is None:
362+
self.response_trailers = headers
363+
else:
364+
# Received too many headers blocks.
365+
raise ProtocolError("Too many header blocks.")
366+
367+
self.header_data = None
368+
337369
def _send_chunk(self, data, final):
338370
"""
339371
Implements most of the sending logic.

0 commit comments

Comments
 (0)