def send_request(self, request): http2_headers = [] http2_headers.append( HeaderTuple(':authority', request.headers.pop('Host'))) http2_headers.append(NeverIndexedHeaderTuple(':path', request.url)) http2_headers.append(HeaderTuple(':scheme', self.context.schema)) http2_headers.append(HeaderTuple(':method', request.method)) sensitive_headers = ('apns-topic', 'authorization') for key, value in request.headers.iteritems(): if key.lower() in sensitive_headers: new = NeverIndexedHeaderTuple(key, value) else: new = HeaderTuple(key, value) http2_headers.append(new) self.context.h2_conn.send_headers(self.stream_id, http2_headers, end_stream=not request.body) self.context._flush_to_stream() if request.body: self._pending_body = request.body self.send_body()
def test_non_sensitive_headers_with_header_tuples(self): """ A header field stored in a HeaderTuple emits a representation that allows indexing. """ e = Encoder() result = (b'\x82\x44\x88\x63\xa1\xa9' + b'\x32\x08\x73\xd0\xc7\x40' + b'\x87\x25\xa8\x49\xe9\xea' + b'\x5f\x5f\x89\x41\x6a\x41' + b'\x92\x6e\xe5\x35\x52\x9f') header_set = [ HeaderTuple(':method', 'GET'), HeaderTuple(':path', '/jimiscool/'), HeaderTuple('customkey', 'sensitiveinfo'), ] assert e.encode(header_set, huffman=True) == result
def write_raw_header_frame(self, headers, stream_id=None, end_stream=False, end_headers=False, frame_cls=HeadersFrame): """ Ignores the statemachine of the stream and sends a HEADER frame regardless. Unlike `write_headers`, this does not check to see if a stream is in the correct state to have HEADER frames sent through to it. It will build a HEADER frame and send it without using the H2 Connection object other than to HPACK encode the headers. :param headers: List of (header, value) tuples :param stream_id: Id of stream to send frame on. Will use the request stream ID if None :param end_stream: Set to True to add END_STREAM flag to frame :param end_headers: Set to True to add END_HEADERS flag to frame """ if not stream_id: stream_id = self.request.h2_stream_id header_t = [] for header, value in headers: header_t.append(HeaderTuple(header, value)) with self.h2conn as connection: frame = frame_cls(stream_id, data=connection.encoder.encode(header_t)) if end_stream: self.stream_ended = True frame.flags.add('END_STREAM') if end_headers: frame.flags.add('END_HEADERS') data = frame.serialize() self.write_raw(data)
def write_raw_header_frame(self, headers, stream_id=None, end_stream=False, end_headers=False, frame_cls=HeadersFrame): """This bypasses state checking and such, and sends a header regardless""" if not stream_id: stream_id = self.request.h2_stream_id header_t = [] for header, value in headers: header_t.append(HeaderTuple(header, value)) with self.h2conn as connection: frame = frame_cls(stream_id, data=connection.encoder.encode(header_t)) if end_stream: self.stream_ended = True frame.flags.add('END_STREAM') if end_headers: frame.flags.add('END_HEADERS') data = frame.serialize() self.write_raw(data)
def test_equal_for_different_indexes(self): """ HeaderTuples compare equal to equivalent NeverIndexedHeaderTuples. """ t1 = HeaderTuple('name', 'value') t2 = NeverIndexedHeaderTuple('name', 'value') assert t1 == t2 assert t1 is not t2
def test_unpacks_properly(self): """ HeaderTuple objects unpack like tuples. """ h = HeaderTuple('name', 'value') k, v = h assert k == 'name' assert v == 'value'
def test_header_tuples_are_indexable(self): """ HeaderTuple objects can be indexed. """ h = HeaderTuple('name', 'value') assert h.indexable
def test_is_tuple(self): """ HeaderTuple objects are tuples. """ h = HeaderTuple('name', 'value') assert isinstance(h, tuple)