Beispiel #1
0
def test_modify_message(ws_testdata):
    tctx, playbook = ws_testdata
    flow = Placeholder(WebSocketFlow)
    assert (playbook << websocket.WebsocketStartHook(flow) >> reply() >>
            DataReceived(tctx.server, b"\x81\x03foo") <<
            websocket.WebsocketMessageHook(flow))
    flow().messages[-1].content = flow().messages[-1].content.replace(
        "foo", "foobar")
    assert (playbook >> reply() << SendData(tctx.client, b"\x81\x06foobar"))
def test_inject_message(ws_testdata):
    tctx, playbook, flow = ws_testdata
    assert (playbook << websocket.WebsocketStartHook(flow) >> reply() >>
            WebSocketMessageInjected(
                flow, WebSocketMessage(Opcode.TEXT, False, b"hello")) <<
            websocket.WebsocketMessageHook(flow))
    assert flow.websocket.messages[-1].content == b"hello"
    assert flow.websocket.messages[-1].from_client is False
    assert (playbook >> reply() << SendData(tctx.client, b"\x81\x05hello"))
def test_fragmented(ws_testdata):
    tctx, playbook, flow = ws_testdata
    assert (playbook << websocket.WebsocketStartHook(flow) >> reply() >>
            DataReceived(tctx.server, b"\x01\x03foo") >> DataReceived(
                tctx.server, b"\x80\x03bar") <<
            websocket.WebsocketMessageHook(flow) >> reply() << SendData(
                tctx.client, b"\x01\x03foo") << SendData(
                    tctx.client, b"\x80\x03bar"))
    assert flow.websocket.messages[-1].content == b"foobar"
def test_upgrade(tctx):
    """Test a HTTP -> WebSocket upgrade"""
    tctx.server.address = ("example.com", 80)
    tctx.server.state = ConnectionState.OPEN
    flow = Placeholder(HTTPFlow)
    assert (
        Playbook(http.HttpLayer(tctx, HTTPMode.transparent)) >> DataReceived(
            tctx.client, b"GET / HTTP/1.1\r\n"
            b"Connection: upgrade\r\n"
            b"Upgrade: websocket\r\n"
            b"Sec-WebSocket-Version: 13\r\n"
            b"\r\n") << http.HttpRequestHeadersHook(flow) >> reply() <<
        http.HttpRequestHook(flow) >> reply() << SendData(
            tctx.server, b"GET / HTTP/1.1\r\n"
            b"Connection: upgrade\r\n"
            b"Upgrade: websocket\r\n"
            b"Sec-WebSocket-Version: 13\r\n"
            b"\r\n") >> DataReceived(
                tctx.server, b"HTTP/1.1 101 Switching Protocols\r\n"
                b"Upgrade: websocket\r\n"
                b"Connection: Upgrade\r\n"
                b"\r\n") << http.HttpResponseHeadersHook(flow) >> reply() <<
        http.HttpResponseHook(flow) >> reply() << SendData(
            tctx.client, b"HTTP/1.1 101 Switching Protocols\r\n"
            b"Upgrade: websocket\r\n"
            b"Connection: Upgrade\r\n"
            b"\r\n") << websocket.WebsocketStartHook(flow) >> reply() >>
        DataReceived(tctx.client, masked_bytes(b"\x81\x0bhello world")) <<
        websocket.WebsocketMessageHook(flow) >> reply() << SendData(
            tctx.server, masked(b"\x81\x0bhello world")) >> DataReceived(
                tctx.server, b"\x82\nhello back") <<
        websocket.WebsocketMessageHook(flow) >> reply() << SendData(
            tctx.client, b"\x82\nhello back") >> DataReceived(
                tctx.client, masked_bytes(b"\x81\x0bhello again")) <<
        websocket.WebsocketMessageHook(flow) >> reply() << SendData(
            tctx.server, masked(b"\x81\x0bhello again")))
    assert len(flow().websocket.messages) == 3
    assert flow().websocket.messages[0].content == b"hello world"
    assert flow().websocket.messages[0].from_client
    assert flow().websocket.messages[0].type == Opcode.TEXT
    assert flow().websocket.messages[1].content == b"hello back"
    assert flow().websocket.messages[1].from_client is False
    assert flow().websocket.messages[1].type == Opcode.BINARY
    assert flow().live
def test_unfragmented(ws_testdata):
    tctx, playbook, flow = ws_testdata
    assert (playbook << websocket.WebsocketStartHook(flow) >> reply() >>
            DataReceived(tctx.server, b"\x81\x06foo"))
    # This already triggers wsproto to emit a wsproto.events.Message, see
    # https://github.com/mitmproxy/mitmproxy/issues/4701
    assert (playbook >> DataReceived(tctx.server, b"bar") <<
            websocket.WebsocketMessageHook(flow) >> reply() << SendData(
                tctx.client, b"\x81\x06foobar"))
    assert flow.websocket.messages[-1].content == b"foobar"
def test_deflate(ws_testdata):
    tctx, playbook, flow = ws_testdata
    flow.response.headers[
        "Sec-WebSocket-Extensions"] = "permessage-deflate; server_max_window_bits=10"
    assert (playbook << websocket.WebsocketStartHook(flow) >> reply()
            # https://tools.ietf.org/html/rfc7692#section-7.2.3.1
            >> DataReceived(tctx.server,
                            bytes.fromhex("c1 07 f2 48 cd c9 c9 07 00")) <<
            websocket.WebsocketMessageHook(flow) >> reply() << SendData(
                tctx.client, bytes.fromhex("c1 07 f2 48 cd c9 c9 07 00")))
    assert flow.websocket.messages[0].content == b"Hello"
def test_upgrade_streamed(tctx):
    """If the HTTP response is streamed, we may get early data from the client."""
    tctx.server.address = ("example.com", 80)
    tctx.server.state = ConnectionState.OPEN
    flow = Placeholder(HTTPFlow)

    def enable_streaming(flow: HTTPFlow):
        flow.response.stream = True

    assert (
        Playbook(http.HttpLayer(tctx, HTTPMode.transparent)) >> DataReceived(
            tctx.client, b"GET / HTTP/1.1\r\n"
            b"Connection: upgrade\r\n"
            b"Upgrade: websocket\r\n"
            b"Sec-WebSocket-Version: 13\r\n"
            b"\r\n") << http.HttpRequestHeadersHook(flow) >> reply() <<
        http.HttpRequestHook(flow) >> reply() << SendData(
            tctx.server, b"GET / HTTP/1.1\r\n"
            b"Connection: upgrade\r\n"
            b"Upgrade: websocket\r\n"
            b"Sec-WebSocket-Version: 13\r\n"
            b"\r\n") >> DataReceived(
                tctx.server, b"HTTP/1.1 101 Switching Protocols\r\n"
                b"Upgrade: websocket\r\n"
                b"Connection: Upgrade\r\n"
                b"\r\n") << http.HttpResponseHeadersHook(flow) >>
        reply(side_effect=enable_streaming) << SendData(
            tctx.client, b"HTTP/1.1 101 Switching Protocols\r\n"
            b"Upgrade: websocket\r\n"
            b"Connection: Upgrade\r\n"
            b"\r\n") << http.HttpResponseHook(flow) >> DataReceived(
                tctx.client, masked_bytes(b"\x81\x0bhello world"))  # early !!
        >> reply(to=-2) << websocket.WebsocketStartHook(flow) >> reply() <<
        websocket.WebsocketMessageHook(flow) >> reply() << SendData(
            tctx.server, masked(b"\x81\x0bhello world")) >> DataReceived(
                tctx.server, b"\x82\nhello back") <<
        websocket.WebsocketMessageHook(flow) >> reply() << SendData(
            tctx.client, b"\x82\nhello back") >> DataReceived(
                tctx.client, masked_bytes(b"\x81\x0bhello again")) <<
        websocket.WebsocketMessageHook(flow) >> reply() << SendData(
            tctx.server, masked(b"\x81\x0bhello again")))
Beispiel #8
0
def test_deflate(ws_testdata):
    tctx, playbook = ws_testdata
    flow = Placeholder(WebSocketFlow)
    # noinspection PyUnresolvedReferences
    http_flow: HTTPFlow = playbook.layer.flow.handshake_flow
    http_flow.response.headers[
        "Sec-WebSocket-Extensions"] = "permessage-deflate; server_max_window_bits=10"
    assert (playbook << websocket.WebsocketStartHook(flow) >> reply()
            # https://tools.ietf.org/html/rfc7692#section-7.2.3.1
            >> DataReceived(tctx.server,
                            bytes.fromhex("c1 07 f2 48 cd c9 c9 07 00")) <<
            websocket.WebsocketMessageHook(flow) >> reply() << SendData(
                tctx.client, bytes.fromhex("c1 07 f2 48 cd c9 c9 07 00")))
    assert flow().messages[0].content == "Hello"
Beispiel #9
0
def test_drop_message(ws_testdata):
    tctx, playbook, flow = ws_testdata
    assert (
            playbook
            << websocket.WebsocketStartHook(flow)
            >> reply()
            >> DataReceived(tctx.server, b"\x81\x03foo")
            << websocket.WebsocketMessageHook(flow)
    )
    flow.websocket.messages[-1].drop()
    assert (
            playbook
            >> reply()
            << None
    )
Beispiel #10
0
def test_empty_message(ws_testdata):
    tctx, playbook, flow = ws_testdata
    assert (
            playbook
            << websocket.WebsocketStartHook(flow)
            >> reply()
            >> DataReceived(tctx.server, b"\x81\x00")
            << websocket.WebsocketMessageHook(flow)
    )
    assert flow.websocket.messages[-1].content == b""
    assert (
            playbook
            >> reply()
            << SendData(tctx.client, b"\x81\x00")
    )
Beispiel #11
0
def test_drop_message(ws_testdata):
    tctx, playbook = ws_testdata
    flow = Placeholder(WebSocketFlow)
    assert (
            playbook
            << websocket.WebsocketStartHook(flow)
            >> reply()
            >> DataReceived(tctx.server, b"\x81\x03foo")
            << websocket.WebsocketMessageHook(flow)
    )
    flow().messages[-1].content = ""
    assert (
            playbook
            >> reply()
            << None
    )