예제 #1
0
파일: test_hyper.py 프로젝트: jjdoor/goods
    def test_read_headers_out_of_order(self):
        # If header blocks aren't decoded in the same order they're received,
        # regardless of the stream they belong to, the decoder state will
        # become corrupted.
        e = Encoder()
        h1 = HeadersFrame(1)
        h1.data = e.encode([(':status', 200), ('content-type', 'foo/bar')])
        h1.flags |= set(['END_HEADERS', 'END_STREAM'])
        h3 = HeadersFrame(3)
        h3.data = e.encode([(':status', 200), ('content-type', 'baz/qux')])
        h3.flags |= set(['END_HEADERS', 'END_STREAM'])
        sock = DummySocket()
        sock.buffer = BytesIO(h1.serialize() + h3.serialize())

        c = HTTP20Connection('www.google.com')
        c._sock = sock
        r1 = c.request('GET', '/a')
        r3 = c.request('GET', '/b')

        assert c.get_response(r3).headers == HTTPHeaderMap(
            [('content-type', 'baz/qux')]
        )
        assert c.get_response(r1).headers == HTTPHeaderMap(
            [('content-type', 'foo/bar')]
        )
예제 #2
0
    def test_read_headers_out_of_order(self):
        # If header blocks aren't decoded in the same order they're received,
        # regardless of the stream they belong to, the decoder state will
        # become corrupted.
        e = Encoder()
        h1 = HeadersFrame(1)
        h1.data = e.encode([(':status', 200), ('content-type', 'foo/bar')])
        h1.flags |= set(['END_HEADERS', 'END_STREAM'])
        h3 = HeadersFrame(3)
        h3.data = e.encode([(':status', 200), ('content-type', 'baz/qux')])
        h3.flags |= set(['END_HEADERS', 'END_STREAM'])
        sock = DummySocket()
        sock.buffer = BytesIO(h1.serialize() + h3.serialize())

        c = HTTP20Connection('www.google.com')
        c._sock = sock
        r1 = c.request('GET', '/a')
        r3 = c.request('GET', '/b')

        assert c.get_response(r3).headers == HTTPHeaderMap(
            [('content-type', 'baz/qux')]
        )
        assert c.get_response(r1).headers == HTTPHeaderMap(
            [('content-type', 'foo/bar')]
        )
예제 #3
0
        def socket_handler(listener):
            sock = listener.accept()[0]

            # Do the handshake: conn header, settings, send settings, recv ack.
            receive_preamble(sock)

            # Now expect some data. One headers frame.
            data.append(sock.recv(65535))

            # Respond!
            h = HeadersFrame(1)
            h.data = self.get_encoder().encode(
                [
                    (':status', 200),
                    ('content-type', 'not/real'),
                    ('content-length', 20),
                ]
            )
            h.flags.add('END_HEADERS')
            sock.send(h.serialize())
            d = DataFrame(1)
            d.data = b'1234567890' * 2
            d.flags.add('END_STREAM')
            sock.send(d.serialize())

            send_event.wait(5)
            sock.close()
예제 #4
0
        def socket_handler(listener):
            sock = listener.accept()[0]

            # Do the handshake: conn header, settings, send settings, recv ack.
            receive_preamble(sock)

            # Now expect some data. One headers frame and one data frame.
            data.append(sock.recv(65535))
            data.append(sock.recv(65535))

            # Respond!
            h = HeadersFrame(1)
            h.data = self.get_encoder().encode([
                (':status', 200),
                ('content-type', 'not/real'),
                ('content-length', 20),
            ])
            h.flags.add('END_HEADERS')
            sock.send(h.serialize())
            d = DataFrame(1)
            d.data = b'1234567890' * 2
            d.flags.add('END_STREAM')
            sock.send(d.serialize())

            sock.close()
예제 #5
0
파일: test_hyper.py 프로젝트: jjdoor/goods
    def test_stream_window_increments_appropriately(self, frame_buffer):
        e = Encoder()
        h = HeadersFrame(1)
        h.data = e.encode([(':status', 200), ('content-type', 'foo/bar')])
        h.flags = set(['END_HEADERS'])
        d = DataFrame(1)
        d.data = b'hi there sir'
        d2 = DataFrame(1)
        d2.data = b'hi there sir again'
        sock = DummySocket()
        sock.buffer = BytesIO(h.serialize() + d.serialize() + d2.serialize())

        c = HTTP20Connection('www.google.com')
        c._sock = sock
        c.request('GET', '/')
        c.streams[1]._in_window_manager.window_size = 1000
        c.streams[1]._in_window_manager.initial_window_size = 1000
        resp = c.get_response()
        resp.read(len(b'hi there sir'))
        resp.read(len(b'hi there sir again'))

        frame_buffer.add_data(b''.join(sock.queue))
        queue = list(frame_buffer)
        assert len(queue) == 3  # one headers frame, two window update frames.
        assert isinstance(queue[1], WindowUpdateFrame)
        assert queue[1].window_increment == len(b'hi there sir')
        assert isinstance(queue[2], WindowUpdateFrame)
        assert queue[2].window_increment == len(b'hi there sir again')
예제 #6
0
        def socket_handler(listener):
            sock = listener.accept()[0]

            receive_preamble(sock)

            data.append(sock.recv(65535))
            send_event.wait(5)

            h = HeadersFrame(1)
            h.data = self.get_encoder().encode(
                [
                    (':status', 200),
                    ('content-type', 'not/real'),
                    ('content-length', 12),
                    ('server', 'socket-level-server')
                ]
            )
            h.flags.add('END_HEADERS')
            sock.send(h.serialize())

            d = DataFrame(1)
            d.data = b'thisisaproxy'
            d.flags.add('END_STREAM')
            sock.send(d.serialize())

            sock.close()
예제 #7
0
    def test_headers_frame_serializes_properly(self):
        f = HeadersFrame(1)
        f.flags = set(['END_STREAM', 'END_HEADERS'])
        f.data = b'hello world'

        s = f.serialize()
        assert s == (b'\x00\x00\x0B\x01\x05\x00\x00\x00\x01' + b'hello world')
예제 #8
0
    def test_stream_window_increments_appropriately(self, frame_buffer):
        e = Encoder()
        h = HeadersFrame(1)
        h.data = e.encode([(':status', 200), ('content-type', 'foo/bar')])
        h.flags = set(['END_HEADERS'])
        d = DataFrame(1)
        d.data = b'hi there sir'
        d2 = DataFrame(1)
        d2.data = b'hi there sir again'
        sock = DummySocket()
        sock.buffer = BytesIO(h.serialize() + d.serialize() + d2.serialize())

        c = HTTP20Connection('www.google.com')
        c._sock = sock
        c.request('GET', '/')
        c.streams[1]._in_window_manager.window_size = 1000
        c.streams[1]._in_window_manager.initial_window_size = 1000
        resp = c.get_response()
        resp.read(len(b'hi there sir'))
        resp.read(len(b'hi there sir again'))

        frame_buffer.add_data(b''.join(sock.queue))
        queue = list(frame_buffer)
        assert len(queue) == 3  # one headers frame, two window update frames.
        assert isinstance(queue[1], WindowUpdateFrame)
        assert queue[1].window_increment == len(b'hi there sir')
        assert isinstance(queue[2], WindowUpdateFrame)
        assert queue[2].window_increment == len(b'hi there sir again')
예제 #9
0
    def test_headers_frame_with_no_length_parses(self):
        # Fixes issue with empty data frames raising InvalidPaddingError.
        f = HeadersFrame(1)
        f.data = b''
        data = f.serialize()

        new_frame = decode_frame(data)
        assert new_frame.data == b''
예제 #10
0
    def test_headers_frame_with_no_length_parses(self):
        # Fixes issue with empty data frames raising InvalidPaddingError.
        f = HeadersFrame(1)
        f.data = b''
        data = f.serialize()

        new_frame = decode_frame(data)
        assert new_frame.data == b''
예제 #11
0
 def add_headers_frame(self, stream_id, headers, end_block=True,
                       end_stream=False):
     frame = HeadersFrame(stream_id)
     frame.data = self.encoder.encode(headers)
     if end_block:
         frame.flags.add('END_HEADERS')
     if end_stream:
         frame.flags.add('END_STREAM')
     self.frames.append(frame)
예제 #12
0
def build_headers_frame(headers, encoder=None):
    f = HeadersFrame(1)
    e = encoder
    if e is None:
        e = Encoder()
        e.huffman_coder = HuffmanEncoder(REQUEST_CODES, REQUEST_CODES_LENGTH)
    f.data = e.encode(headers)
    f.flags.add('END_HEADERS')
    return f
예제 #13
0
def build_headers_frame(headers, encoder=None):
    f = HeadersFrame(1)
    e = encoder
    if e is None:
        e = Encoder()
        e.huffman_coder = HuffmanEncoder(REQUEST_CODES, REQUEST_CODES_LENGTH)
    f.data = e.encode(headers)
    f.flags.add('END_HEADERS')
    return f
예제 #14
0
파일: test_hyper.py 프로젝트: jjdoor/goods
 def add_headers_frame(self, stream_id, headers, end_block=True,
                       end_stream=False):
     frame = HeadersFrame(stream_id)
     frame.data = self.encoder.encode(headers)
     if end_block:
         frame.flags.add('END_HEADERS')
     if end_stream:
         frame.flags.add('END_STREAM')
     self.frames.append(frame)
예제 #15
0
파일: helpers.py 프로젝트: defnull/hyper-h2
 def build_headers_frame(self, headers, flags=[], stream_id=1):
     """
     Builds a single valid headers frame out of the contained headers.
     """
     f = HeadersFrame(stream_id)
     f.data = self.encoder.encode(headers)
     f.flags.add('END_HEADERS')
     for flag in flags:
         f.flags.add(flag)
     return f
예제 #16
0
 def build_headers_frame(self, headers, flags=[], stream_id=1):
     """
     Builds a single valid headers frame out of the contained headers.
     """
     f = HeadersFrame(stream_id)
     f.data = self.encoder.encode(headers)
     f.flags.add('END_HEADERS')
     for flag in flags:
         f.flags.add(flag)
     return f
예제 #17
0
    def test_headers_frame_serializes_properly(self):
        f = HeadersFrame(1)
        f.flags = set(['END_STREAM', 'END_HEADERS'])
        f.data = b'hello world'

        s = f.serialize()
        assert s == (
            b'\x00\x00\x0B\x01\x05\x00\x00\x00\x01' +
            b'hello world'
        )
예제 #18
0
    def start_request(self):
        """
        Open the stream. Does this by encoding and sending the headers: no more
        calls to ``add_header`` are allowed after this method is called.
        The `end` flag controls whether this will be the end of the stream, or
        whether data will follow.
        """
        # Strip any headers invalid in H2.
        #headers = h2_safe_headers(self.request_headers)

        host = self.connection.get_host(self.task.host)

        self.add_header(":method", self.task.method)
        self.add_header(":scheme", "https")
        self.add_header(":authority", host)
        self.add_header(":path", self.task.path)

        default_headers = (':method', ':scheme', ':authority', ':path')
        #headers = h2_safe_headers(self.task.headers)
        for name, value in list(self.task.headers.items()):
            is_default = to_native_string(name) in default_headers
            self.add_header(name, value, replace=is_default)

        # Encode the headers.
        encoded_headers = self._encoder(self.request_headers)

        # It's possible that there is a substantial amount of data here. The
        # data needs to go into one HEADERS frame, followed by a number of
        # CONTINUATION frames. For now, for ease of implementation, let's just
        # assume that's never going to happen (16kB of headers is lots!).
        # Additionally, since this is so unlikely, there's no point writing a
        # test for this: it's just so simple.
        if len(encoded_headers) > FRAME_MAX_LEN:  # pragma: no cover
            raise ValueError("Header block too large.")

        header_frame = HeadersFrame(self.stream_id)
        header_frame.data = encoded_headers

        # If no data has been provided, this is the end of the stream. Either
        # way, due to the restriction above it's definitely the end of the
        # headers.
        header_frame.flags.add('END_HEADERS')
        if self.request_body_left == 0:
            header_frame.flags.add('END_STREAM')

        # Send the header frame.
        self.task.set_state("start send header")
        self._send_cb(header_frame)

        # Transition the stream state appropriately.
        self.state = STATE_OPEN

        self.task.set_state("start send left body")
        if self.request_body_left > 0:
            self.send_left_body()
예제 #19
0
 def test_repr(self):
     f = HeadersFrame(1)
     assert repr(f).endswith(
         "exclusive=False, depends_on=0, stream_weight=0, data=None")
     f.data = b'hello'
     f.exclusive = True
     f.depends_on = 42
     f.stream_weight = 64
     assert repr(f).endswith(
         "exclusive=True, depends_on=42, stream_weight=64, data=<hex:68656c6c6f>"
     )
예제 #20
0
    def test_headers_frame_with_priority_serializes_properly(self):
        # This test also tests that we can receive a HEADERS frame with no
        # actual headers on it. This is technically possible.
        s = (b'\x00\x00\x05\x01\x20\x00\x00\x00\x01' + b'\x80\x00\x00\x04\x40')
        f = HeadersFrame(1)
        f.flags = set(['PRIORITY'])
        f.data = b''
        f.depends_on = 4
        f.stream_weight = 64
        f.exclusive = True

        assert f.serialize() == s
예제 #21
0
파일: test_hyper.py 프로젝트: jjdoor/goods
    def test_incrementing_window_after_close(self):
        """
        Hyper does not attempt to increment the flow control window once the
        stream is closed.
        """
        # For this test, we want to send a response that has three frames at
        # the default max frame size (16,384 bytes). That will, on the third
        # frame, trigger the processing to increment the flow control window,
        # which should then not happen.
        f = SettingsFrame(0, settings={h2.settings.INITIAL_WINDOW_SIZE: 100})

        c = HTTP20Connection('www.google.com')
        c._sock = DummySocket()
        c._sock.buffer = BytesIO(f.serialize())

        # Open stream 1.
        c.request('GET', '/')

        # Check what data we've sent right now.
        originally_sent_data = c._sock.queue[:]

        # Swap out the buffer to get a GoAway frame.
        length = 16384
        total_length = (3 * 16384) + len(b'some more data')
        e = Encoder()
        h1 = HeadersFrame(1)
        h1.data = e.encode(
            [(':status', 200), ('content-length', '%d' % total_length)]
        )
        h1.flags |= set(['END_HEADERS'])

        d1 = DataFrame(1)
        d1.data = b'\x00' * length
        d2 = d1
        d3 = d1
        d4 = DataFrame(1)
        d4.data = b'some more data'
        d4.flags |= set(['END_STREAM'])

        buffer = BytesIO(
            b''.join(f.serialize() for f in [h1, d1, d2, d3, d4])
        )
        c._sock.buffer = buffer

        # Read the response
        resp = c.get_response(stream_id=1)
        assert resp.status == 200
        assert resp.read() == b''.join(
            [b'\x00' * (3 * length), b'some more data']
        )

        # We should have sent only one extra frame
        assert len(originally_sent_data) + 1 == len(c._sock.queue)
예제 #22
0
파일: test_hyper.py 프로젝트: Lukasa/hyper
    def test_incrementing_window_after_close(self):
        """
        Hyper does not attempt to increment the flow control window once the
        stream is closed.
        """
        # For this test, we want to send a response that has three frames at
        # the default max frame size (16,384 bytes). That will, on the third
        # frame, trigger the processing to increment the flow control window,
        # which should then not happen.
        f = SettingsFrame(0, settings={h2.settings.INITIAL_WINDOW_SIZE: 100})

        c = HTTP20Connection('www.google.com')
        c._sock = DummySocket()
        c._sock.buffer = BytesIO(f.serialize())

        # Open stream 1.
        c.request('GET', '/')

        # Check what data we've sent right now.
        originally_sent_data = c._sock.queue[:]

        # Swap out the buffer to get a GoAway frame.
        length = 16384
        total_length = (3 * 16384) + len(b'some more data')
        e = Encoder()
        h1 = HeadersFrame(1)
        h1.data = e.encode(
            [(':status', 200), ('content-length', '%d' % total_length)]
        )
        h1.flags |= set(['END_HEADERS'])

        d1 = DataFrame(1)
        d1.data = b'\x00' * length
        d2 = d1
        d3 = d1
        d4 = DataFrame(1)
        d4.data = b'some more data'
        d4.flags |= set(['END_STREAM'])

        buffer = BytesIO(
            b''.join(f.serialize() for f in [h1, d1, d2, d3, d4])
        )
        c._sock.buffer = buffer

        # Read the response
        resp = c.get_response(stream_id=1)
        assert resp.status == 200
        assert resp.read() == b''.join(
            [b'\x00' * (3 * length), b'some more data']
        )

        # We should have sent only one extra frame
        assert len(originally_sent_data) + 1 == len(c._sock.queue)
예제 #23
0
    def test_headers_frame_with_priority_serializes_properly(self):
        # This test also tests that we can receive a HEADERS frame with no
        # actual headers on it. This is technically possible.
        s = (
            b'\x00\x00\x05\x01\x20\x00\x00\x00\x01' +
            b'\x80\x00\x00\x04\x40'
        )
        f = HeadersFrame(1)
        f.flags = set(['PRIORITY'])
        f.data = b''
        f.depends_on = 4
        f.stream_weight = 64
        f.exclusive = True

        assert f.serialize() == s
예제 #24
0
    def slow_headers(self, conn, h2conn, method="GET"):
        LOGGER.info("SLOW HEADERS ATTACK=============================")
        h2conn.initiate_connection()
        wf = WindowUpdateFrame(0)
        wf.window_increment = WINDOW_SIZE_INCREMENT
        h2conn._data_to_send += wf.serialize()
        conn.sendall(h2conn.data_to_send())

        headers = [(":authority", args.target), (":path", "/"),
                   (":scheme", "http"), (":method", method)]
        hf = HeadersFrame(1)
        if method == "GET":
            hf.flags.add("END_STREAM")
        e = Encoder()
        hf.data = e.encode(headers)
        h2conn._data_to_send += hf.serialize()
        conn.sendall(h2conn.data_to_send())
예제 #25
0
    def build_headers_frame(self,
                            headers,
                            flags=[],
                            stream_id=1,
                            **priority_kwargs):
        """
        Builds a single valid headers frame out of the contained headers.
        """
        f = HeadersFrame(stream_id)
        f.data = self.encoder.encode(headers)
        f.flags.add('END_HEADERS')
        for flag in flags:
            f.flags.add(flag)

        for k, v in priority_kwargs.items():
            setattr(f, k, v)

        return f
예제 #26
0
파일: helpers.py 프로젝트: Mec-iS/hyper-h2
    def build_headers_frame(self,
                            headers,
                            flags=[],
                            stream_id=1,
                            **priority_kwargs):
        """
        Builds a single valid headers frame out of the contained headers.
        """
        f = HeadersFrame(stream_id)
        f.data = self.encoder.encode(headers)
        f.flags.add('END_HEADERS')
        for flag in flags:
            f.flags.add(flag)

        for k, v in priority_kwargs.items():
            setattr(f, k, v)

        return f
예제 #27
0
    def create_socket(status_code, data, headers):
        # test helper method
        encoder = Encoder()
        h1 = HeadersFrame(1)
        h1.data = encoder.encode([(':status', status_code),
                                  ('content-length', len(data))] + headers)
        h1.flags |= set(['END_HEADERS'])

        d1 = DataFrame(1)
        d1.data = data

        d2 = DataFrame(1)
        d2.flags |= set(['END_STREAM'])

        content = b''.join(f.serialize() for f in [h1, d1, d2])
        buffer = BytesIO(content)

        return DummySocket(buffer)
예제 #28
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')
        ])
예제 #29
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')]
        )
예제 #30
0
파일: test_hyper.py 프로젝트: Lukasa/hyper
    def test_streams_removed_on_close(self):
        # Create content for read from socket
        e = Encoder()
        h1 = HeadersFrame(1)
        h1.data = e.encode([(':status', 200), ('content-type', 'foo/bar')])
        h1.flags |= set(['END_HEADERS', 'END_STREAM'])
        sock = DummySocket()
        sock.buffer = BytesIO(h1.serialize())

        c = HTTP20Connection('www.google.com')
        c._sock = sock
        stream_id = c.request('GET', '/')

        # Create reference to current recent_recv_streams set
        recent_recv_streams = c.recent_recv_streams
        streams = c.streams

        resp = c.get_response(stream_id=stream_id)
        assert stream_id in recent_recv_streams
        assert stream_id in streams
        resp.read()
        assert stream_id not in recent_recv_streams
        assert stream_id not in streams
예제 #31
0
        def socket_handler(listener):
            sock = listener.accept()[0]

            receive_preamble(sock)

            data.append(sock.recv(65535))
            send_event.wait(5)

            h = HeadersFrame(1)
            h.data = self.get_encoder().encode([(':status', 200),
                                                ('content-type', 'not/real'),
                                                ('content-length', 12),
                                                ('server',
                                                 'socket-level-server')])
            h.flags.add('END_HEADERS')
            sock.send(h.serialize())

            d = DataFrame(1)
            d.data = b'thisisaproxy'
            d.flags.add('END_STREAM')
            sock.send(d.serialize())

            sock.close()
예제 #32
0
파일: test_hyper.py 프로젝트: jjdoor/goods
    def test_streams_removed_on_close(self):
        # Create content for read from socket
        e = Encoder()
        h1 = HeadersFrame(1)
        h1.data = e.encode([(':status', 200), ('content-type', 'foo/bar')])
        h1.flags |= set(['END_HEADERS', 'END_STREAM'])
        sock = DummySocket()
        sock.buffer = BytesIO(h1.serialize())

        c = HTTP20Connection('www.google.com')
        c._sock = sock
        stream_id = c.request('GET', '/')

        # Create reference to current recent_recv_streams set
        recent_recv_streams = c.recent_recv_streams
        streams = c.streams

        resp = c.get_response(stream_id=stream_id)
        assert stream_id in recent_recv_streams
        assert stream_id in streams
        resp.read()
        assert stream_id not in recent_recv_streams
        assert stream_id not in streams