def _build_headers_frames(self, headers, encoder, first_frame): """ Helper method to build headers or push promise frames. """ headers = ((name.lower(), value) for name, value in headers) encoded_headers = encoder.encode(headers) # Slice into blocks of max_outbound_frame_size. Be careful with this: # it only works right because we never send padded frames or priority # information on the frames. Revisit this if we do. header_blocks = [ encoded_headers[i:i+self.max_outbound_frame_size] for i in range( 0, len(encoded_headers), self.max_outbound_frame_size ) ] frames = [] first_frame.data = header_blocks[0] frames.append(first_frame) for block in header_blocks[1:]: cf = ContinuationFrame(self.stream_id) cf.data = block frames.append(cf) frames[-1].flags.add('END_HEADERS') return frames
def _build_headers_frames(self, headers, encoder, first_frame): """ Helper method to build headers or push promise frames. """ # We need to lowercase the header names, and to ensure that secure # header fields are kept out of compression contexts. headers = _lowercase_header_names(headers) headers = secure_headers(headers) encoded_headers = encoder.encode(headers) # Slice into blocks of max_outbound_frame_size. Be careful with this: # it only works right because we never send padded frames or priority # information on the frames. Revisit this if we do. header_blocks = [ encoded_headers[i:i + self.max_outbound_frame_size] for i in range( 0, len(encoded_headers), self.max_outbound_frame_size) ] frames = [] first_frame.data = header_blocks[0] frames.append(first_frame) for block in header_blocks[1:]: cf = ContinuationFrame(self.stream_id) cf.data = block frames.append(cf) frames[-1].flags.add('END_HEADERS') return frames
def _build_headers_frames(self, headers, encoder, first_frame): """ Helper method to build headers or push promise frames. """ # Convert headers to two-tuples. try: headers = headers.items() except AttributeError: headers = headers headers = ((name.lower(), value) for name, value in headers) encoded_headers = encoder.encode(headers) # Slice into blocks of max_outbound_frame_size. Be careful with this: # it only works right because we never send padded frames or priority # information on the frames. Revisit this if we do. header_blocks = [ encoded_headers[i:i + self.max_outbound_frame_size] for i in range( 0, len(encoded_headers), self.max_outbound_frame_size) ] frames = [] first_frame.data = header_blocks[0] frames.append(first_frame) for block in header_blocks[1:]: cf = ContinuationFrame(self.stream_id) cf.data = block frames.append(cf) frames[-1].flags.add('END_HEADERS') return frames
def _build_headers_frames(self, headers, encoder, first_frame): """ Helper method to build headers or push promise frames. """ # We need to lowercase the header names, and to ensure that secure # header fields are kept out of compression contexts. headers = _lowercase_header_names(headers) headers = secure_headers(headers) encoded_headers = encoder.encode(headers) # Slice into blocks of max_outbound_frame_size. Be careful with this: # it only works right because we never send padded frames or priority # information on the frames. Revisit this if we do. header_blocks = [ encoded_headers[i:i+self.max_outbound_frame_size] for i in range( 0, len(encoded_headers), self.max_outbound_frame_size ) ] frames = [] first_frame.data = header_blocks[0] frames.append(first_frame) for block in header_blocks[1:]: cf = ContinuationFrame(self.stream_id) cf.data = block frames.append(cf) frames[-1].flags.add('END_HEADERS') return frames
def build_continuation_frame(self, header_block, flags=[], stream_id=1): """ Builds a single continuation frame out of the binary header block. """ f = ContinuationFrame(stream_id) f.data = header_block f.flags = set(flags) return f
def test_continuation_frame_serializes(self): f = ContinuationFrame(1) f.parse_flags(0x04) f.data = b'hello world' s = f.serialize() assert s == ( b'\x00\x00\x0B\x09\x04\x00\x00\x00\x01' + b'hello world' )
def test_continuation_frame_serializes(self): f = ContinuationFrame(1) f.parse_flags(0x04) f.data = b'hello world' s = f.serialize() assert s == (b'\x00\x00\x0B\x09\x04\x00\x00\x00\x01' + b'hello world')
def test_headers_with_continuation(self): e = Encoder() header_data = e.encode([(':status', 200), ('content-type', 'foo/bar'), ('content-length', '0')]) h = HeadersFrame(1) h.data = header_data[0:int(len(header_data) / 2)] h.flags.add('END_STREAM') c = ContinuationFrame(1) c.data = header_data[int(len(header_data) / 2):] c.flags.add('END_HEADERS') sock = DummySocket() sock.buffer = BytesIO(h.serialize() + c.serialize()) c = HTTP20Connection('www.google.com') c._sock = sock r = c.request('GET', '/') assert set(c.get_response(r).headers.iter_raw()) == set([ (b'content-type', b'foo/bar'), (b'content-length', b'0') ])
def test_headers_with_continuation(self): e = Encoder() header_data = e.encode([ (':status', 200), ('content-type', 'foo/bar'), ('content-length', '0') ]) h = HeadersFrame(1) h.data = header_data[0:int(len(header_data)/2)] h.flags.add('END_STREAM') c = ContinuationFrame(1) c.data = header_data[int(len(header_data)/2):] c.flags.add('END_HEADERS') sock = DummySocket() sock.buffer = BytesIO(h.serialize() + c.serialize()) c = HTTP20Connection('www.google.com') c._sock = sock r = c.request('GET', '/') assert set(c.get_response(r).headers.iter_raw()) == set( [(b'content-type', b'foo/bar'), (b'content-length', b'0')] )
def test_continuation_frame_flags(self): f = ContinuationFrame(1) flags = f.parse_flags(0xFF) assert flags == set(['END_HEADERS'])
def test_repr(self): f = ContinuationFrame(1) assert repr(f).endswith("data=None") f.data = b'hello' assert repr(f).endswith("data=<hex:68656c6c6f>")