コード例 #1
0
def twebsocketflow(client_conn=True,
                   server_conn=True,
                   messages=True,
                   err=None,
                   handshake_flow=True):

    if client_conn is True:
        client_conn = tclient_conn()
    if server_conn is True:
        server_conn = tserver_conn()
    if handshake_flow is True:
        req = http.HTTPRequest("relative",
                               "GET",
                               "http",
                               "example.com",
                               "80",
                               "/ws",
                               "HTTP/1.1",
                               headers=net_http.Headers(
                                   connection="upgrade",
                                   upgrade="websocket",
                                   sec_websocket_version="13",
                                   sec_websocket_key="1234",
                               ),
                               content=b'')
        resp = http.HTTPResponse(
            "HTTP/1.1",
            101,
            reason=net_http.status_codes.RESPONSES.get(101),
            headers=net_http.Headers(
                connection='upgrade',
                upgrade='websocket',
                sec_websocket_accept=b'',
            ),
            content=b'',
        )
        handshake_flow = http.HTTPFlow(client_conn, server_conn)
        handshake_flow.request = req
        handshake_flow.response = resp

    f = websocket.WebSocketFlow(client_conn, server_conn, handshake_flow)
    handshake_flow.metadata['websocket_flow'] = f

    if messages is True:
        messages = [
            websocket.WebSocketMessage(websockets.OPCODE.BINARY, True,
                                       b"hello binary"),
            websocket.WebSocketMessage(websockets.OPCODE.TEXT, True,
                                       "hello text".encode()),
            websocket.WebSocketMessage(websockets.OPCODE.TEXT, False,
                                       "it's me".encode()),
        ]
    if err is True:
        err = terr()

    f.messages = messages
    f.error = err
    f.reply = controller.DummyReply()
    return f
コード例 #2
0
ファイル: tflow.py プロジェクト: zhoulingmin/mitmproxy
def twebsocketflow(messages=True, err=None) -> http.HTTPFlow:
    flow = http.HTTPFlow(tclient_conn(), tserver_conn())
    flow.request = http.Request(
        "example.com",
        80,
        b"GET",
        b"http",
        b"example.com",
        b"/ws",
        b"HTTP/1.1",
        headers=http.Headers(
            connection="upgrade",
            upgrade="websocket",
            sec_websocket_version="13",
            sec_websocket_key="1234",
        ),
        content=b'',
        trailers=None,
        timestamp_start=946681200,
        timestamp_end=946681201,
    )
    flow.response = http.Response(
        b"HTTP/1.1",
        101,
        reason=b"Switching Protocols",
        headers=http.Headers(
            connection='upgrade',
            upgrade='websocket',
            sec_websocket_accept=b'',
        ),
        content=b'',
        trailers=None,
        timestamp_start=946681202,
        timestamp_end=946681203,
    )
    flow.websocket = websocket.WebSocketData()

    if messages is True:
        flow.websocket.messages = [
            websocket.WebSocketMessage(Opcode.BINARY, True, b"hello binary",
                                       946681203),
            websocket.WebSocketMessage(Opcode.TEXT, True, b"hello text",
                                       946681204),
            websocket.WebSocketMessage(Opcode.TEXT, False, b"it's me",
                                       946681205),
        ]
    if err is True:
        flow.error = terr()

    flow.reply = controller.DummyReply()
    return flow
コード例 #3
0
    def test_text(self):
        txt = websocket.WebSocketMessage(Opcode.TEXT, True, b"foo")
        bin = websocket.WebSocketMessage(Opcode.BINARY, True, b"foo")

        assert txt.is_text
        assert txt.text == "foo"
        txt.text = "bar"
        assert txt.content == b"bar"

        assert not bin.is_text
        with pytest.raises(AttributeError,
                           match="do not have a 'text' attribute."):
            _ = bin.text
        with pytest.raises(AttributeError,
                           match="do not have a 'text' attribute."):
            bin.text = "bar"
コード例 #4
0
ファイル: tflow.py プロジェクト: EndUser509/mitmproxy
def twebsocket(messages: bool = True) -> websocket.WebSocketData:
    ws = websocket.WebSocketData()

    if messages:
        ws.messages = [
            websocket.WebSocketMessage(Opcode.BINARY, True, b"hello binary",
                                       946681203),
            websocket.WebSocketMessage(Opcode.TEXT, True, b"hello text",
                                       946681204),
            websocket.WebSocketMessage(Opcode.TEXT, False, b"it's me",
                                       946681205),
        ]
    ws.close_reason = "Close Reason"
    ws.close_code = 1000
    ws.closed_by_client = False
    ws.timestamp_end = 946681205

    return ws
コード例 #5
0
    def test_basic(self):
        m = websocket.WebSocketMessage(Opcode.TEXT, True, b"foo")
        m.set_state(m.get_state())
        assert m.content == b"foo"
        assert repr(m) == "'foo'"
        m.type = Opcode.BINARY
        assert repr(m) == "b'foo'"

        assert not m.killed
        m.kill()
        assert m.killed
コード例 #6
0
ファイル: proxyserver.py プロジェクト: lingying177/mitmproxy
    def inject_websocket(self, flow: Flow, to_client: bool, message: bytes, is_text: bool = True):
        if not isinstance(flow, http.HTTPFlow) or not flow.websocket:
            ctx.log.warn("Cannot inject WebSocket messages into non-WebSocket flows.")

        msg = websocket.WebSocketMessage(
            Opcode.TEXT if is_text else Opcode.BINARY,
            not to_client,
            message
        )
        event = WebSocketMessageInjected(flow, msg)
        try:
            self.inject_event(event)
        except ValueError as e:
            ctx.log.warn(str(e))
コード例 #7
0
    def relay_messages(
            self,
            event: events.ConnectionEvent) -> layer.CommandGenerator[None]:
        from_client = event.connection == self.context.client
        from_str = 'client' if from_client else 'server'
        if from_client:
            src_ws = self.client_ws
            dst_ws = self.server_ws
        else:
            src_ws = self.server_ws
            dst_ws = self.client_ws

        if isinstance(event, events.DataReceived):
            src_ws.receive_data(event.data)
        elif isinstance(event, events.ConnectionClosed):
            src_ws.receive_data(None)
        else:  # pragma: no cover
            raise AssertionError(f"Unexpected event: {event}")

        for ws_event in src_ws.events():
            if isinstance(ws_event, wsproto.events.Message):
                src_ws.frame_buf.append(ws_event.data)

                if ws_event.message_finished:
                    if isinstance(ws_event, wsproto.events.TextMessage):
                        frame_type = Opcode.TEXT
                        content = "".join(src_ws.frame_buf)  # type: ignore
                    else:
                        frame_type = Opcode.BINARY
                        content = b"".join(src_ws.frame_buf)  # type: ignore

                    fragmentizer = Fragmentizer(src_ws.frame_buf)
                    src_ws.frame_buf.clear()

                    message = websocket.WebSocketMessage(
                        frame_type, from_client, content)
                    self.flow.messages.append(message)
                    yield WebsocketMessageHook(self.flow)

                    assert not message.killed  # this is deprecated, instead we should have .content set to emptystr.

                    for msg in fragmentizer(message.content):
                        yield dst_ws.send2(msg)

            elif isinstance(ws_event,
                            (wsproto.events.Ping, wsproto.events.Pong)):
                yield commands.Log(
                    f"Received WebSocket {ws_event.__class__.__name__.lower()} from {from_str} "
                    f"(payload: {bytes(ws_event.payload)!r})")
                yield dst_ws.send2(ws_event)
            elif isinstance(ws_event, wsproto.events.CloseConnection):
                self.flow.close_sender = from_str
                self.flow.close_code = ws_event.code
                self.flow.close_reason = ws_event.reason

                for ws in [self.server_ws, self.client_ws]:
                    if ws.state in {
                            ConnectionState.OPEN,
                            ConnectionState.REMOTE_CLOSING
                    }:
                        # response == original event, so no need to differentiate here.
                        yield ws.send2(ws_event)
                    yield commands.CloseConnection(ws.conn)
                if ws_event.code in {1000, 1001, 1005}:
                    yield WebsocketEndHook(self.flow)
                else:
                    self.flow.error = flow.Error(
                        f"WebSocket Error: {format_close_event(ws_event)}")
                    yield WebsocketErrorHook(self.flow)
                self._handle_event = self.done
            else:  # pragma: no cover
                raise AssertionError(f"Unexpected WebSocket event: {ws_event}")
コード例 #8
0
def twebsocketflow(client_conn=True,
                   server_conn=True,
                   messages=True,
                   err=None,
                   handshake_flow=True):

    if client_conn is True:
        client_conn = tclient_conn()
    if server_conn is True:
        server_conn = tserver_conn()
    if handshake_flow is True:
        req = http.HTTPRequest(
            "example.com",
            80,
            b"GET",
            b"http",
            b"example.com",
            b"/ws",
            b"HTTP/1.1",
            headers=net_http.Headers(
                connection="upgrade",
                upgrade="websocket",
                sec_websocket_version="13",
                sec_websocket_key="1234",
            ),
            content=b'',
            trailers=None,
            timestamp_start=946681200,
            timestamp_end=946681201,
        )
        resp = http.HTTPResponse(
            b"HTTP/1.1",
            101,
            reason=net_http.status_codes.RESPONSES.get(101),
            headers=net_http.Headers(
                connection='upgrade',
                upgrade='websocket',
                sec_websocket_accept=b'',
            ),
            content=b'',
            trailers=None,
            timestamp_start=946681202,
            timestamp_end=946681203,
        )
        handshake_flow = http.HTTPFlow(client_conn, server_conn)
        handshake_flow.request = req
        handshake_flow.response = resp

    f = websocket.WebSocketFlow(client_conn, server_conn, handshake_flow)
    f.metadata['websocket_handshake'] = handshake_flow.id
    handshake_flow.metadata['websocket_flow'] = f.id
    handshake_flow.metadata['websocket'] = True

    if messages is True:
        messages = [
            websocket.WebSocketMessage(Opcode.BINARY, True, b"hello binary"),
            websocket.WebSocketMessage(Opcode.TEXT, True, b"hello text"),
            websocket.WebSocketMessage(Opcode.TEXT, False, b"it's me"),
        ]
    if err is True:
        err = terr()

    f.messages = messages
    f.error = err
    f.reply = controller.DummyReply()
    return f
コード例 #9
0
    def relay_messages(self,
                       event: events.Event) -> layer.CommandGenerator[None]:
        assert self.flow.websocket  # satisfy type checker

        if isinstance(event, events.ConnectionEvent):
            from_client = event.connection == self.context.client
        elif isinstance(event, WebSocketMessageInjected):
            from_client = event.message.from_client
        else:
            raise AssertionError(f"Unexpected event: {event}")

        from_str = 'client' if from_client else 'server'
        if from_client:
            src_ws = self.client_ws
            dst_ws = self.server_ws
        else:
            src_ws = self.server_ws
            dst_ws = self.client_ws

        if isinstance(event, events.DataReceived):
            src_ws.receive_data(event.data)
        elif isinstance(event, events.ConnectionClosed):
            src_ws.receive_data(None)
        elif isinstance(event, WebSocketMessageInjected):
            fragmentizer = Fragmentizer([], event.message.type == Opcode.TEXT)
            src_ws._events.extend(fragmentizer(event.message.content))
        else:  # pragma: no cover
            raise AssertionError(f"Unexpected event: {event}")

        for ws_event in src_ws.events():
            if isinstance(ws_event, wsproto.events.Message):
                is_text = isinstance(ws_event.data, str)
                if is_text:
                    typ = Opcode.TEXT
                    src_ws.frame_buf[-1] += ws_event.data.encode()
                else:
                    typ = Opcode.BINARY
                    src_ws.frame_buf[-1] += ws_event.data

                if ws_event.message_finished:
                    content = b"".join(src_ws.frame_buf)

                    fragmentizer = Fragmentizer(src_ws.frame_buf, is_text)
                    src_ws.frame_buf = [b""]

                    message = websocket.WebSocketMessage(
                        typ, from_client, content)
                    self.flow.websocket.messages.append(message)
                    yield WebsocketMessageHook(self.flow)

                    if not message.dropped:
                        for msg in fragmentizer(message.content):
                            yield dst_ws.send2(msg)

                elif ws_event.frame_finished:
                    src_ws.frame_buf.append(b"")

            elif isinstance(ws_event,
                            (wsproto.events.Ping, wsproto.events.Pong)):
                yield commands.Log(
                    f"Received WebSocket {ws_event.__class__.__name__.lower()} from {from_str} "
                    f"(payload: {bytes(ws_event.payload)!r})")
                yield dst_ws.send2(ws_event)
            elif isinstance(ws_event, wsproto.events.CloseConnection):
                self.flow.websocket.timestamp_end = time.time()
                self.flow.websocket.closed_by_client = from_client
                self.flow.websocket.close_code = ws_event.code
                self.flow.websocket.close_reason = ws_event.reason

                for ws in [self.server_ws, self.client_ws]:
                    if ws.state in {
                            ConnectionState.OPEN,
                            ConnectionState.REMOTE_CLOSING
                    }:
                        # response == original event, so no need to differentiate here.
                        yield ws.send2(ws_event)
                    yield commands.CloseConnection(ws.conn)
                yield WebsocketEndHook(self.flow)
                self._handle_event = self.done
            else:  # pragma: no cover
                raise AssertionError(f"Unexpected WebSocket event: {ws_event}")