예제 #1
0
    def test_priority_frame_with_all_data_serializes_properly(self):
        f = PriorityFrame(1)
        f.depends_on = 0x04
        f.stream_weight = 64
        f.exclusive = True

        assert f.serialize() == self.payload
예제 #2
0
 def test_repr(self):
     f = PriorityFrame(1)
     assert repr(f).endswith(
         "exclusive=False, depends_on=0, stream_weight=0")
     f.exclusive = True
     f.depends_on = 0x04
     f.stream_weight = 64
     assert repr(f).endswith(
         "exclusive=True, depends_on=4, stream_weight=64")
예제 #3
0
 def build_priority_frame(self,
                          stream_id,
                          weight,
                          depends_on=0,
                          exclusive=False):
     """
     Builds a single priority frame.
     """
     f = PriorityFrame(stream_id)
     f.depends_on = depends_on
     f.stream_weight = weight
     f.exclusive = exclusive
     return f
예제 #4
0
파일: helpers.py 프로젝트: Mec-iS/hyper-h2
 def build_priority_frame(self,
                          stream_id,
                          weight,
                          depends_on=0,
                          exclusive=False):
     """
     Builds a single priority frame.
     """
     f = PriorityFrame(stream_id)
     f.depends_on = depends_on
     f.stream_weight = weight
     f.exclusive = exclusive
     return f
예제 #5
0
    def test_priority_frame_with_all_data_serializes_properly(self):
        f = PriorityFrame(1)
        f.depends_on = 0x04
        f.stream_weight = 64
        f.exclusive = True

        assert f.serialize() == self.payload
예제 #6
0
 def test_priority_frame_has_no_flags(self):
     f = PriorityFrame(1)
     flags = f.parse_flags(0xFF)
     assert flags == set()
     assert isinstance(flags, set)
예제 #7
0
    def _handle_event(self, event, source_conn, other_conn, is_server):
        self.log(
            "HTTP2 Event from {}".format("server" if is_server else "client"),
            "debug",
            [repr(event)]
        )

        if hasattr(event, 'stream_id'):
            if is_server and event.stream_id % 2 == 1:
                eid = self.server_to_client_stream_ids[event.stream_id]
            else:
                eid = event.stream_id

        if isinstance(event, events.RequestReceived):
            headers = Headers([[k, v] for k, v in event.headers])
            self.streams[eid] = Http2SingleStreamLayer(self, eid, headers)
            self.streams[eid].timestamp_start = time.time()
            self.streams[eid].start()
        elif isinstance(event, events.ResponseReceived):
            headers = Headers([[k, v] for k, v in event.headers])
            self.streams[eid].queued_data_length = 0
            self.streams[eid].timestamp_start = time.time()
            self.streams[eid].response_headers = headers
            self.streams[eid].response_arrived.set()
        elif isinstance(event, events.DataReceived):
            if self.config.body_size_limit and self.streams[eid].queued_data_length > self.config.body_size_limit:
                raise HttpException("HTTP body too large. Limit is {}.".format(self.config.body_size_limit))
            self.streams[eid].data_queue.put(event.data)
            self.streams[eid].queued_data_length += len(event.data)
            source_conn.h2.safe_increment_flow_control(event.stream_id, event.flow_controlled_length)
        elif isinstance(event, events.StreamEnded):
            self.streams[eid].timestamp_end = time.time()
            self.streams[eid].data_finished.set()
        elif isinstance(event, events.StreamReset):
            self.streams[eid].zombie = time.time()
            if eid in self.streams and event.error_code == 0x8:
                if is_server:
                    other_stream_id = self.streams[eid].client_stream_id
                else:
                    other_stream_id = self.streams[eid].server_stream_id
                if other_stream_id is not None:
                    other_conn.h2.safe_reset_stream(other_stream_id, event.error_code)
        elif isinstance(event, events.RemoteSettingsChanged):
            new_settings = dict([(id, cs.new_value) for (id, cs) in six.iteritems(event.changed_settings)])
            other_conn.h2.safe_update_settings(new_settings)
        elif isinstance(event, events.ConnectionTerminated):
            # Do not immediately terminate the other connection.
            # Some streams might be still sending data to the client.
            return False
        elif isinstance(event, events.PushedStreamReceived):
            # pushed stream ids should be unique and not dependent on race conditions
            # only the parent stream id must be looked up first
            parent_eid = self.server_to_client_stream_ids[event.parent_stream_id]
            with self.client_conn.h2.lock:
                self.client_conn.h2.push_stream(parent_eid, event.pushed_stream_id, event.headers)
                self.client_conn.send(self.client_conn.h2.data_to_send())

            headers = Headers([[str(k), str(v)] for k, v in event.headers])
            headers['x-mitmproxy-pushed'] = 'true'
            self.streams[event.pushed_stream_id] = Http2SingleStreamLayer(self, event.pushed_stream_id, headers)
            self.streams[event.pushed_stream_id].timestamp_start = time.time()
            self.streams[event.pushed_stream_id].pushed = True
            self.streams[event.pushed_stream_id].parent_stream_id = parent_eid
            self.streams[event.pushed_stream_id].timestamp_end = time.time()
            self.streams[event.pushed_stream_id].request_data_finished.set()
            self.streams[event.pushed_stream_id].start()
        elif isinstance(event, events.PriorityUpdated):
            stream_id = event.stream_id
            if stream_id in self.streams.keys() and self.streams[stream_id].server_stream_id:
                stream_id = self.streams[stream_id].server_stream_id

            depends_on = event.depends_on
            if depends_on in self.streams.keys() and self.streams[depends_on].server_stream_id:
                depends_on = self.streams[depends_on].server_stream_id

            # weight is between 1 and 256 (inclusive), but represented as uint8 (0 to 255)
            frame = PriorityFrame(stream_id, depends_on, event.weight - 1, event.exclusive)
            self.server_conn.send(frame.serialize())
        elif isinstance(event, events.TrailersReceived):
            raise NotImplementedError()

        return True
예제 #8
0
 def test_priority_frame_comes_on_a_stream(self):
     with pytest.raises(ValueError):
         PriorityFrame(0)
예제 #9
0
    def test_priority_frame_default_serializes_properly(self):
        f = PriorityFrame(1)

        assert f.serialize() == (
            b'\x00\x00\x05\x02\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00')
예제 #10
0
 def test_priority_frame_has_no_flags(self):
     f = PriorityFrame(1)
     flags = f.parse_flags(0xFF)
     assert flags == set()
     assert isinstance(flags, Flags)
예제 #11
0
 def test_priority_frame_comes_on_a_stream(self):
     with pytest.raises(InvalidDataError):
         PriorityFrame(0)
예제 #12
0
    def test_priority_frame_default_serializes_properly(self):
        f = PriorityFrame(1)

        assert f.serialize() == (
            b'\x00\x00\x05\x02\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00'
        )