Esempio n. 1
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        while True:
            r = ssl_read_select(self.active_conns, 1)
            for conn in r:
                source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                is_server = (conn == self.server_conn.connection)

                with source_conn.h2.lock:
                    try:
                        raw_frame = b''.join(http2_read_raw_frame(source_conn.rfile))
                    except:
                        for stream in self.streams.values():
                            stream.zombie = time.time()
                        return

                    events = source_conn.h2.receive_data(raw_frame)
                    source_conn.send(source_conn.h2.data_to_send())

                    for event in events:
                        if not self._handle_event(event, source_conn, other_conn, is_server):
                            return

            self._cleanup_streams()
Esempio n. 2
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        while True:
            r = ssl_read_select(self.active_conns, 1)
            for conn in r:
                source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                is_server = (conn == self.server_conn.connection)

                with source_conn.h2.lock:
                    try:
                        raw_frame = b''.join(http2_read_raw_frame(source_conn.rfile))
                    except:
                        # read frame failed: connection closed
                        self._kill_all_streams()
                        return

                    incoming_events = source_conn.h2.receive_data(raw_frame)
                    source_conn.send(source_conn.h2.data_to_send())

                    for event in incoming_events:
                        if not self._handle_event(event, source_conn, other_conn, is_server):
                            # connection terminated: GoAway
                            self._kill_all_streams()
                            return

            self._cleanup_streams()
Esempio n. 3
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        while True:
            r = ssl_read_select(self.active_conns, 1)
            for conn in r:
                source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                is_server = (conn == self.server_conn.connection)

                with source_conn.h2.lock:
                    try:
                        raw_frame = b''.join(
                            http2_read_raw_frame(source_conn.rfile))
                    except:
                        for stream in self.streams.values():
                            stream.zombie = time.time()
                        return

                    events = source_conn.h2.receive_data(raw_frame)
                    source_conn.send(source_conn.h2.data_to_send())

                    for event in events:
                        if not self._handle_event(event, source_conn,
                                                  other_conn, is_server):
                            return

            self._cleanup_streams()
Esempio n. 4
0
        def handle(self):
            h2_conn = h2.connection.H2Connection(client_side=False)

            preamble = self.rfile.read(24)
            h2_conn.initiate_connection()
            h2_conn.receive_data(preamble)
            self.wfile.write(h2_conn.data_to_send())
            self.wfile.flush()

            done = False
            while not done:
                try:
                    raw = b''.join(http2_read_raw_frame(self.rfile))
                    events = h2_conn.receive_data(raw)
                except:
                    break
                self.wfile.write(h2_conn.data_to_send())
                self.wfile.flush()

                for event in events:
                    try:
                        if not self.server.handle_server_event(
                                event, h2_conn, self.rfile, self.wfile):
                            done = True
                            break
                    except Exception as e:
                        print(repr(e))
                        print(traceback.format_exc())
                        done = True
                        break
        def handle(self):
            h2_conn = h2.connection.H2Connection(client_side=False, header_encoding=False)

            preamble = self.rfile.read(24)
            h2_conn.initiate_connection()
            h2_conn.receive_data(preamble)
            self.wfile.write(h2_conn.data_to_send())
            self.wfile.flush()

            done = False
            while not done:
                try:
                    raw = b''.join(http2_read_raw_frame(self.rfile))
                    events = h2_conn.receive_data(raw)
                except:
                    break
                self.wfile.write(h2_conn.data_to_send())
                self.wfile.flush()

                for event in events:
                    try:
                        if not self.server.handle_server_event(event, h2_conn, self.rfile, self.wfile):
                            done = True
                            break
                    except Exception as e:
                        print(repr(e))
                        print(traceback.format_exc())
                        done = True
                        break
    def test_connection_lost(self):
        client, h2_conn = self._setup_connection()

        self._send_request(client.wfile,
                           h2_conn,
                           stream_id=1,
                           headers=[(':authority', "127.0.0.1:%s" %
                                     self.server.server.address.port),
                                    (':method', 'GET'), (':scheme', 'https'),
                                    (':path', '/'), ('foo', 'bar')])

        done = False
        ended_streams = 0
        pushed_streams = 0
        responses = 0
        while not done:
            try:
                raw = b''.join(http2_read_raw_frame(client.rfile))
                events = h2_conn.receive_data(raw)
            except:
                break
            client.wfile.write(h2_conn.data_to_send())
            client.wfile.flush()

        if len(self.master.state.flows) == 1:
            assert self.master.state.flows[0].response is None
    def test_with_bodies(self):
        client, h2_conn = self._setup_connection()

        self._send_request(
            client.wfile,
            h2_conn,
            headers=[
                (':authority', "127.0.0.1:%s" % self.server.server.address.port),
                (':method', 'GET'),
                (':scheme', 'https'),
                (':path', '/'),
            ],
            body='foobar with request body',
        )

        done = False
        while not done:
            try:
                events = h2_conn.receive_data(b''.join(http2_read_raw_frame(client.rfile)))
            except:
                break
            client.wfile.write(h2_conn.data_to_send())
            client.wfile.flush()

            for event in events:
                if isinstance(event, h2.events.StreamEnded):
                    done = True

        h2_conn.close_connection()
        client.wfile.write(h2_conn.data_to_send())
        client.wfile.flush()

        assert self.master.state.flows[0].response.body == b'foobar with request body'
    def test_simple(self):
        client, h2_conn = self._setup_connection()

        self._send_request(client.wfile, h2_conn, headers=[
            (':authority', "127.0.0.1:%s" % self.server.server.address.port),
            (':method', 'GET'),
            (':scheme', 'https'),
            (':path', '/'),
            ('ClIeNt-FoO', 'client-bar-1'),
            ('ClIeNt-FoO', 'client-bar-2'),
        ], body='my request body echoed back to me')

        done = False
        while not done:
            try:
                events = h2_conn.receive_data(b''.join(http2_read_raw_frame(client.rfile)))
            except:
                break
            client.wfile.write(h2_conn.data_to_send())
            client.wfile.flush()

            for event in events:
                if isinstance(event, h2.events.StreamEnded):
                    done = True

        h2_conn.close_connection()
        client.wfile.write(h2_conn.data_to_send())
        client.wfile.flush()

        assert len(self.master.state.flows) == 1
        assert self.master.state.flows[0].response.status_code == 200
        assert self.master.state.flows[0].response.headers['server-foo'] == 'server-bar'
        assert self.master.state.flows[0].response.headers['föo'] == 'bär'
        assert self.master.state.flows[0].response.body == b'foobar'
Esempio n. 9
0
        def handle(self):
            # send magic
            self.wfile.write(codecs.decode('505249202a20485454502f322e300d0a0d0a534d0d0a0d0a', 'hex_codec'))
            self.wfile.flush()

            # send empty settings frame
            self.wfile.write(codecs.decode('000000040000000000', 'hex_codec'))
            self.wfile.flush()

            # check empty settings frame
            raw = utils.http2_read_raw_frame(self.rfile)
            assert raw == codecs.decode('00000c040000000000000200000000000300000001', 'hex_codec')

            # check settings acknowledgement
            raw = utils.http2_read_raw_frame(self.rfile)
            assert raw == codecs.decode('000000040100000000', 'hex_codec')

            # send settings acknowledgement
            self.wfile.write(codecs.decode('000000040100000000', 'hex_codec'))
            self.wfile.flush()
Esempio n. 10
0
    def test_push_promise_reset(self):
        client, h2_conn = self._setup_connection()

        self._send_request(client.wfile,
                           h2_conn,
                           stream_id=1,
                           headers=[(':authority', "127.0.0.1:%s" %
                                     self.server.server.address.port),
                                    (':method', 'GET'), (':scheme', 'https'),
                                    (':path', '/'), ('foo', 'bar')])

        done = False
        ended_streams = 0
        pushed_streams = 0
        responses = 0
        while not done:
            try:
                events = h2_conn.receive_data(b''.join(
                    http2_read_raw_frame(client.rfile)))
            except:
                break
            client.wfile.write(h2_conn.data_to_send())
            client.wfile.flush()

            for event in events:
                if isinstance(event,
                              h2.events.StreamEnded) and event.stream_id == 1:
                    ended_streams += 1
                elif isinstance(event, h2.events.PushedStreamReceived):
                    pushed_streams += 1
                    h2_conn.reset_stream(event.pushed_stream_id,
                                         error_code=0x8)
                    client.wfile.write(h2_conn.data_to_send())
                    client.wfile.flush()
                elif isinstance(event, h2.events.ResponseReceived):
                    responses += 1
                if isinstance(event, h2.events.ConnectionTerminated):
                    done = True

            if responses >= 1 and ended_streams >= 1 and pushed_streams == 2:
                done = True

        h2_conn.close_connection()
        client.wfile.write(h2_conn.data_to_send())
        client.wfile.flush()

        bodies = [
            flow.response.body for flow in self.master.state.flows
            if flow.response
        ]
        assert len(bodies) >= 1
        assert b'regular_stream' in bodies
Esempio n. 11
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        while True:
            r = ssl_read_select(self.active_conns, 1)
            for conn in r:
                source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                is_server = (conn == self.server_conn.connection)

                with source_conn.h2.lock:
                    try:
                        raw_frame = b''.join(
                            http2_read_raw_frame(source_conn.rfile))
                    except:
                        for stream in self.streams.values():
                            stream.zombie = time.time()
                        return

                    frame, _ = hyperframe.frame.Frame.parse_frame_header(
                        raw_frame[:9])

                    if is_server:
                        list = self.server_reset_streams
                    else:
                        list = self.client_reset_streams
                    if frame.stream_id in list:
                        # this frame belongs to a reset stream - just ignore it
                        if isinstance(
                                frame,
                                hyperframe.frame.HeadersFrame) or isinstance(
                                    frame, hyperframe.frame.ContinuationFrame):
                            # we need to keep the hpack-decoder happy too
                            source_conn.h2.decoder.decode(raw_frame[9:])
                        continue

                    events = source_conn.h2.receive_data(raw_frame)
                    source_conn.send(source_conn.h2.data_to_send())

                    for event in events:
                        if not self._handle_event(event, source_conn,
                                                  other_conn, is_server):
                            return

            self._cleanup_streams()
    def test_push_promise(self):
        client, h2_conn = self._setup_connection()

        self._send_request(client.wfile, h2_conn, stream_id=1, headers=[
            (':authority', "127.0.0.1:%s" % self.server.server.address.port),
            (':method', 'GET'),
            (':scheme', 'https'),
            (':path', '/'),
            ('foo', 'bar')
        ])

        done = False
        ended_streams = 0
        pushed_streams = 0
        responses = 0
        while not done:
            try:
                raw = b''.join(http2_read_raw_frame(client.rfile))
                events = h2_conn.receive_data(raw)
            except:
                break
            client.wfile.write(h2_conn.data_to_send())
            client.wfile.flush()

            for event in events:
                if isinstance(event, h2.events.StreamEnded):
                    ended_streams += 1
                elif isinstance(event, h2.events.PushedStreamReceived):
                    pushed_streams += 1
                elif isinstance(event, h2.events.ResponseReceived):
                    responses += 1
                if isinstance(event, h2.events.ConnectionTerminated):
                    done = True

            if responses == 3 and ended_streams == 3 and pushed_streams == 2:
                done = True

        h2_conn.close_connection()
        client.wfile.write(h2_conn.data_to_send())
        client.wfile.flush()

        assert ended_streams == 3
        assert pushed_streams == 2

        bodies = [flow.response.body for flow in self.master.state.flows]
        assert len(bodies) == 3
        assert b'regular_stream' in bodies
        assert b'pushed_stream_foo' in bodies
        assert b'pushed_stream_bar' in bodies
Esempio n. 13
0
        def handle(self):
            # send magic
            self.wfile.write(
                codecs.decode(
                    '505249202a20485454502f322e300d0a0d0a534d0d0a0d0a',
                    'hex_codec'))
            self.wfile.flush()

            # send empty settings frame
            self.wfile.write(codecs.decode('000000040000000000', 'hex_codec'))
            self.wfile.flush()

            # check empty settings frame
            raw = utils.http2_read_raw_frame(self.rfile)
            assert raw == codecs.decode(
                '00000c040000000000000200000000000300000001', 'hex_codec')

            # check settings acknowledgement
            raw = utils.http2_read_raw_frame(self.rfile)
            assert raw == codecs.decode('000000040100000000', 'hex_codec')

            # send settings acknowledgement
            self.wfile.write(codecs.decode('000000040100000000', 'hex_codec'))
            self.wfile.flush()
Esempio n. 14
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        while True:
            r = ssl_read_select(self.active_conns, 1)
            for conn in r:
                source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                is_server = conn == self.server_conn.connection

                with source_conn.h2.lock:
                    try:
                        raw_frame = b"".join(http2_read_raw_frame(source_conn.rfile))
                    except:
                        for stream in self.streams.values():
                            stream.zombie = time.time()
                        return

                    frame, _ = hyperframe.frame.Frame.parse_frame_header(raw_frame[:9])

                    if is_server:
                        list = self.server_reset_streams
                    else:
                        list = self.client_reset_streams
                    if frame.stream_id in list:
                        # this frame belongs to a reset stream - just ignore it
                        if isinstance(frame, hyperframe.frame.HeadersFrame) or isinstance(
                            frame, hyperframe.frame.ContinuationFrame
                        ):
                            # we need to keep the hpack-decoder happy too
                            source_conn.h2.decoder.decode(raw_frame[9:])
                        continue

                    events = source_conn.h2.receive_data(raw_frame)
                    source_conn.send(source_conn.h2.data_to_send())

                    for event in events:
                        if not self._handle_event(event, source_conn, other_conn, is_server):
                            return

            self._cleanup_streams()
Esempio n. 15
0
    def test_simple(self):
        client, h2_conn = self._setup_connection()

        self._send_request(client.wfile,
                           h2_conn,
                           headers=[
                               (':authority', "127.0.0.1:%s" %
                                self.server.server.address.port),
                               (':method', 'GET'),
                               (':scheme', 'https'),
                               (':path', '/'),
                               ('ClIeNt-FoO', 'client-bar-1'),
                               ('ClIeNt-FoO', 'client-bar-2'),
                           ],
                           body='my request body echoed back to me')

        done = False
        while not done:
            try:
                events = h2_conn.receive_data(b''.join(
                    http2_read_raw_frame(client.rfile)))
            except:
                break
            client.wfile.write(h2_conn.data_to_send())
            client.wfile.flush()

            for event in events:
                if isinstance(event, h2.events.StreamEnded):
                    done = True

        h2_conn.close_connection()
        client.wfile.write(h2_conn.data_to_send())
        client.wfile.flush()

        assert len(self.master.state.flows) == 1
        assert self.master.state.flows[0].response.status_code == 200
        assert self.master.state.flows[0].response.headers[
            'server-foo'] == 'server-bar'
        assert self.master.state.flows[0].response.headers['föo'] == 'bär'
        assert self.master.state.flows[0].response.body == b'foobar'
    def test_connection_lost(self):
        client, h2_conn = self._setup_connection()

        self._send_request(client.wfile, h2_conn, stream_id=1, headers=[
            (':authority', "127.0.0.1:%s" % self.server.server.address.port),
            (':method', 'GET'),
            (':scheme', 'https'),
            (':path', '/'),
            ('foo', 'bar')
        ])

        done = False
        while not done:
            try:
                raw = b''.join(http2_read_raw_frame(client.rfile))
                h2_conn.receive_data(raw)
            except:
                break
            client.wfile.write(h2_conn.data_to_send())
            client.wfile.flush()

        if len(self.master.state.flows) == 1:
            assert self.master.state.flows[0].response is None
Esempio n. 17
0
    def test_with_bodies(self):
        client, h2_conn = self._setup_connection()

        self._send_request(
            client.wfile,
            h2_conn,
            headers=[
                (':authority',
                 "127.0.0.1:%s" % self.server.server.address.port),
                (':method', 'GET'),
                (':scheme', 'https'),
                (':path', '/'),
            ],
            body='foobar with request body',
        )

        done = False
        while not done:
            try:
                events = h2_conn.receive_data(b''.join(
                    http2_read_raw_frame(client.rfile)))
            except:
                break
            client.wfile.write(h2_conn.data_to_send())
            client.wfile.flush()

            for event in events:
                if isinstance(event, h2.events.StreamEnded):
                    done = True

        h2_conn.close_connection()
        client.wfile.write(h2_conn.data_to_send())
        client.wfile.flush()

        assert self.master.state.flows[
            0].response.body == b'foobar with request body'