Beispiel #1
0
def read_response_head(lines: List[bytes]) -> Response:
    """
    Parse an HTTP response head (response line + headers) from an iterable of lines

    Args:
        lines: The input lines

    Returns:
        The HTTP response object (without body)

    Raises:
        ValueError: The input is malformed.
    """
    http_version, status_code, reason = _read_response_line(lines[0])
    headers = _read_headers(lines[1:])

    return Response(
        http_version=http_version,
        status_code=status_code,
        reason=reason,
        headers=headers,
        content=None,
        trailers=None,
        timestamp_start=time.time(),
        timestamp_end=None,
    )
Beispiel #2
0
	def request(self, flow: Flow) -> None:
		if flow.response or flow.error or (flow.reply and flow.reply.state == 'taken'):
			return
		if not (self.filter and self.filter(flow)):
			return

		headers = {
			'server': version.MITMPROXY,
		}

		script = self._get_script()
		if not script:
			flow.response = Response.make(404, None, headers)
			return

		headers['content-type'] = 'application/javascript'
		flow.response = Response.make(200, script, headers)
 async def wrapper():
     try:
         await awaitable
     except:
         print_exc()
         flow.response = Response.make(500, None,
                                       {'server': version.MITMPROXY})
     finally:
         flow.reply.commit()
    async def _async_request(self, flow: Flow) -> None:
        referer = flow.request.headers['referer']
        log.info(f'Webmanifest request from {referer}.')
        headers = {
            'server': version.MITMPROXY,
        }

        try:
            character_info = await wait_for(self.data.get(referer), timeout=15)
        except (TimeoutError, CancelledError):
            log.error(
                f'Timeout while waiting for character data from {referer}.')
            flow.response = Response.make(404, b'', headers)
            return

        data = loads(character_info.decode('utf-8'))['data']
        character_name = data['name']
        avatar_url = data['decorations'].get('avatarUrl', None)
        manifest = {
            'name': f'{character_name} - D&D Beyond',
            'short_name': character_name,
            'description':
            'An official digital toolset for Fifth Edition (5e) Dungeons & Dragons (D&D).',
            'icons': [],
            'display': 'fullscreen',
            'start_url': referer,
        }
        if avatar_url:
            manifest['icons'].append({
                'src': avatar_url,
                'sizes': '192x192',
                'type': 'image/webp',
            })
        else:
            manifest['icons'].append({
                'src':
                'https://www.dndbeyond.com/Content/Skins/Waterdeep/images/characters/default-avatar-builder.png',
                'sizes': '192x192',
                'type': 'image/png',
            })

        headers['content-type'] = 'application/webmanifest+json'
        flow.response = Response.make(200,
                                      dumps(manifest).encode('utf-8'), headers)
Beispiel #5
0
def ws_testdata(tctx):
    tctx.server.address = ("example.com", 80)
    tctx.server.state = ConnectionState.OPEN
    flow = HTTPFlow(
        tctx.client,
        tctx.server
    )
    flow.request = Request.make("GET", "http://example.com/", headers={
        "Connection": "upgrade",
        "Upgrade": "websocket",
        "Sec-WebSocket-Version": "13",
    })
    flow.response = Response.make(101, headers={
        "Connection": "upgrade",
        "Upgrade": "websocket",
    })
    return tctx, Playbook(websocket.WebsocketLayer(tctx, flow))
Beispiel #6
0
 def test_serializable(self):
     resp = tresp()
     resp.trailers = Headers()
     resp2 = Response.from_state(resp.get_state())
     assert resp.data == resp2.data
Beispiel #7
0
    def test_make(self):
        r = Response.make()
        assert r.status_code == 200
        assert r.content == b""

        r = Response.make(418, "teatime")
        assert r.status_code == 418
        assert r.content == b"teatime"
        assert r.headers["content-length"] == "7"

        Response.make(content=b"foo")
        Response.make(content="foo")
        with pytest.raises(TypeError):
            Response.make(content=42)

        r = Response.make(headers=[(b"foo", b"bar")])
        assert r.headers["foo"] == "bar"

        r = Response.make(headers=({"foo": "baz"}))
        assert r.headers["foo"] == "baz"

        r = Response.make(headers=Headers(foo="qux"))
        assert r.headers["foo"] == "qux"

        with pytest.raises(TypeError):
            Response.make(headers=42)
Beispiel #8
0
def test_kill_flow(tctx, when):
    """Test that we properly kill flows if instructed to do so"""
    server = Placeholder(Server)
    connect_flow = Placeholder(HTTPFlow)
    flow = Placeholder(HTTPFlow)

    def kill(flow: HTTPFlow):
        # Can't use flow.kill() here because that currently still depends on a reply object.
        flow.error = Error(Error.KILLED_MESSAGE)

    def assert_kill(err_hook: bool = True):
        playbook >> reply(side_effect=kill)
        if err_hook:
            playbook << http.HttpErrorHook(flow)
            playbook >> reply()
        playbook << CloseConnection(tctx.client)
        assert playbook

    playbook = Playbook(http.HttpLayer(tctx, HTTPMode.regular))
    assert (playbook
            >> DataReceived(tctx.client, b"CONNECT example.com:80 HTTP/1.1\r\n\r\n")
            << http.HttpConnectHook(connect_flow))
    if when == "http_connect":
        return assert_kill(False)
    assert (playbook
            >> reply()
            << SendData(tctx.client, b'HTTP/1.1 200 Connection established\r\n\r\n')
            >> DataReceived(tctx.client, b"GET /foo?hello=1 HTTP/1.1\r\nHost: example.com\r\n\r\n")
            << layer.NextLayerHook(Placeholder())
            >> reply_next_layer(lambda ctx: http.HttpLayer(ctx, HTTPMode.transparent))
            << http.HttpRequestHeadersHook(flow))
    if when == "requestheaders":
        return assert_kill()
    assert (playbook
            >> reply()
            << http.HttpRequestHook(flow))
    if when == "request":
        return assert_kill()
    if when == "script-response-responseheaders":
        assert (playbook
                >> reply(side_effect=lambda f: setattr(f, "response", Response.make()))
                << http.HttpResponseHeadersHook(flow))
        return assert_kill()
    assert (playbook
            >> reply()
            << OpenConnection(server)
            >> reply(None)
            << SendData(server, b"GET /foo?hello=1 HTTP/1.1\r\nHost: example.com\r\n\r\n")
            >> DataReceived(server, b"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World")
            << http.HttpResponseHeadersHook(flow))
    if when == "responseheaders":
        return assert_kill()

    if when == "response":
        assert (playbook
                >> reply()
                >> DataReceived(server, b"!")
                << http.HttpResponseHook(flow))
        return assert_kill(False)
    elif when == "error":
        assert (playbook
                >> reply()
                >> ConnectionClosed(server)
                << CloseConnection(server)
                << http.HttpErrorHook(flow))
        return assert_kill(False)
    else:
        raise AssertionError
Beispiel #9
0
 def reply_from_proxy(flow: HTTPFlow):
     flow.response = Response.make(418)
Beispiel #10
0
def request(flow):
    flow.response = HTTPResponse.make(200, cow, {'Content-Type': 'text/plain'})