コード例 #1
0
ファイル: _upstream_proxy.py プロジェクト: szlaozhu/mitmproxy
 def receive_handshake_data(
         self,
         data: bytes) -> layer.CommandGenerator[Tuple[bool, Optional[str]]]:
     if not self.send_connect:
         return (yield from super().receive_handshake_data(data))
     self.buf += data
     response_head = self.buf.maybe_extract_lines()
     if response_head:
         response_head = [
             bytes(x) for x in response_head
         ]  # TODO: Make url.parse compatible with bytearrays
         try:
             response = http1_sansio.read_response_head(response_head)
         except ValueError as e:
             yield commands.Log(
                 f"{human.format_address(self.tunnel_connection.address)}: {e}"
             )
             return False, str(e)
         if 200 <= response.status_code < 300:
             if self.buf:
                 yield from self.receive_data(bytes(self.buf))
                 del self.buf
             return True, None
         else:
             raw_resp = b"\n".join(response_head)
             yield commands.Log(
                 f"{human.format_address(self.tunnel_connection.address)}: {raw_resp!r}",
                 level="debug")
             return False, f"{response.status_code} {response.reason}"
     else:
         return False, None
コード例 #2
0
ファイル: _http1.py プロジェクト: szlaozhu/mitmproxy
    def read_headers(
            self,
            event: events.ConnectionEvent) -> layer.CommandGenerator[None]:
        if isinstance(event, events.DataReceived):
            if not self.request:
                # we just received some data for an unknown request.
                yield commands.Log(
                    f"Unexpected data from server: {bytes(self.buf)!r}")
                yield commands.CloseConnection(self.conn)
                return
            assert self.stream_id

            response_head = self.buf.maybe_extract_lines()
            if response_head:
                response_head = [
                    bytes(x) for x in response_head
                ]  # TODO: Make url.parse compatible with bytearrays
                try:
                    self.response = http1_sansio.read_response_head(
                        response_head)
                    expected_size = http1_sansio.expected_http_body_size(
                        self.request, self.response)
                except (ValueError, exceptions.HttpSyntaxException) as e:
                    yield commands.CloseConnection(self.conn)
                    yield ReceiveHttp(
                        ResponseProtocolError(
                            self.stream_id,
                            f"Cannot parse HTTP response: {e}"))
                    return
                yield ReceiveHttp(
                    ResponseHeaders(self.stream_id, self.response,
                                    expected_size == 0))
                self.body_reader = make_body_reader(expected_size)

                self.state = self.read_body
                yield from self.state(event)
            else:
                pass  # FIXME: protect against header size DoS
        elif isinstance(event, events.ConnectionClosed):
            if self.conn.state & ConnectionState.CAN_WRITE:
                yield commands.CloseConnection(self.conn)
            if self.stream_id:
                if self.buf:
                    yield ReceiveHttp(
                        ResponseProtocolError(
                            self.stream_id,
                            f"unexpected server response: {bytes(self.buf)!r}")
                    )
                else:
                    # The server has closed the connection to prevent us from continuing.
                    # We need to signal that to the stream.
                    # https://tools.ietf.org/html/rfc7231#section-6.5.11
                    yield ReceiveHttp(
                        ResponseProtocolError(self.stream_id,
                                              "server closed connection"))
            else:
                return
        else:
            raise AssertionError(f"Unexpected event: {event}")
コード例 #3
0
def test_read_response_head():
    rfile = [
        b"HTTP/1.1 418 I'm a teapot\r\n",
        b"Content-Length: 4\r\n",
    ]
    r = read_response_head(rfile)
    assert r.status_code == 418
    assert r.headers["Content-Length"] == "4"
    assert r.content is None