From 833d143ffdc951dc7f90ad8ce878d1432405c627 Mon Sep 17 00:00:00 2001 From: Muhammad Moinur Rahman Date: Mon, 18 Feb 2019 19:06:51 +0000 Subject: www/mitmproxy: Update version 2.0.1=>4.0.4 PR: 235840 Approved by: gaod@hychen.org --- www/mitmproxy/Makefile | 32 ++-- www/mitmproxy/distinfo | 6 +- .../patch-mitmproxy_proxy_protocol_websocket.py | 174 +++++++++++++++++++++ www/mitmproxy/files/patch-setup.py | 24 +++ 4 files changed, 215 insertions(+), 21 deletions(-) create mode 100644 www/mitmproxy/files/patch-mitmproxy_proxy_protocol_websocket.py create mode 100644 www/mitmproxy/files/patch-setup.py diff --git a/www/mitmproxy/Makefile b/www/mitmproxy/Makefile index ee073d74a8c1..3c67e2f3c98c 100644 --- a/www/mitmproxy/Makefile +++ b/www/mitmproxy/Makefile @@ -2,7 +2,7 @@ # $FreeBSD$ PORTNAME= mitmproxy -PORTVERSION= 2.0.1 +PORTVERSION= 4.0.4 DISTVERSIONPREFIX= v CATEGORIES= www python @@ -15,32 +15,28 @@ LICENSE_FILE= ${WRKSRC}/LICENSE RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}click>=6.2:devel/py-click@${PY_FLAVOR} \ ${PYTHON_PKGNAMEPREFIX}blinker>=1.4:devel/py-blinker@${PY_FLAVOR} \ ${PYTHON_PKGNAMEPREFIX}certifi>0:security/py-certifi@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}construct28>=2.8:devel/py-construct28@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}cryptography>=1.3:security/py-cryptography@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}cssutils>=1.0.1:www/py-cssutils@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}html2text>=2016.1.8:textproc/py-html2text@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}wsproto>=0.13.0:net/py-wsproto@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}ldap3>=2.5:net/py-ldap3@${PY_FLAVOR} \ ${PYTHON_PKGNAMEPREFIX}passlib>=1.6.5:security/py-passlib@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}pyasn1>=0.1.9:devel/py-pyasn1@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}openssl>=16.0:security/py-openssl@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}pyasn1>=0.3.1:devel/py-pyasn1@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}openssl>=17.5:security/py-openssl@${PY_FLAVOR} \ ${PYTHON_PKGNAMEPREFIX}pyparsing>=2.1.3:devel/py-pyparsing@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}requests>=2.9.1:www/py-requests@${PY_FLAVOR} \ ${PYTHON_PKGNAMEPREFIX}ruamel.yaml>=0.13.2:devel/py-ruamel.yaml@${PY_FLAVOR} \ ${PYTHON_PKGNAMEPREFIX}tornado>=4.3:www/py-tornado@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}urwid>=1.3.1:devel/py-urwid@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}watchdog>=0.8.3:devel/py-watchdog@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}brotli>=0.5.1:archivers/py-brotli@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}urwid>=2.0.1:devel/py-urwid@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}brotli>=0.7.0:archivers/py-brotli@${PY_FLAVOR} \ ${PYTHON_PKGNAMEPREFIX}sortedcontainers>=1.5.4:devel/py-sortedcontainers@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}pyperclip>=1.5.22:devel/py-pyperclip@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}hyperframe>=5.0.0:www/py-hyperframe@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}kaitaistruct>=0.6:devel/py-kaitaistruct@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}jsbeautifier>=1.6.3:devel/py-jsbeautifier@${PY_FLAVOR} \ - ${PYTHON_PKGNAMEPREFIX}h2>=3.0.0:www/py-h2@${PY_FLAVOR} + ${PYTHON_PKGNAMEPREFIX}pyperclip>=1.6.0:devel/py-pyperclip@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}hyperframe>=5.1.0:www/py-hyperframe@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}kaitaistruct>=0.7:devel/py-kaitaistruct@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}h2>=3.1.0:www/py-h2@${PY_FLAVOR} USES= python:3.5+ -USE_PYTHON= distutils autoplist optsuffix -NO_ARCH= yes +USE_PYTHON= distutils autoplist USE_GITHUB= yes +NO_ARCH= yes + post-extract: @${REINPLACE_CMD} -e 's/brotlipy/brotli/' -e 's/, <.*",/",/' ${WRKSRC}/setup.py diff --git a/www/mitmproxy/distinfo b/www/mitmproxy/distinfo index af130903b096..8893949d0114 100644 --- a/www/mitmproxy/distinfo +++ b/www/mitmproxy/distinfo @@ -1,3 +1,3 @@ -TIMESTAMP = 1496739322 -SHA256 (mitmproxy-mitmproxy-v2.0.1_GH0.tar.gz) = b0ccc49924762ea78290d62c463be8c041f1837f9005f583ad09c47122547e9d -SIZE (mitmproxy-mitmproxy-v2.0.1_GH0.tar.gz) = 28498142 +TIMESTAMP = 1550146900 +SHA256 (mitmproxy-mitmproxy-v4.0.4_GH0.tar.gz) = d91eaaad06a5e124a76388999b22a4c590ea26149a30aaff73658cd98d0651d5 +SIZE (mitmproxy-mitmproxy-v4.0.4_GH0.tar.gz) = 27131713 diff --git a/www/mitmproxy/files/patch-mitmproxy_proxy_protocol_websocket.py b/www/mitmproxy/files/patch-mitmproxy_proxy_protocol_websocket.py new file mode 100644 index 000000000000..b0f07b3f54a5 --- /dev/null +++ b/www/mitmproxy/files/patch-mitmproxy_proxy_protocol_websocket.py @@ -0,0 +1,174 @@ +--- mitmproxy/proxy/protocol/websocket.py.orig 2019-02-14 21:03:58 UTC ++++ mitmproxy/proxy/protocol/websocket.py +@@ -4,8 +4,9 @@ from OpenSSL import SSL + + + import wsproto +-from wsproto import events +-from wsproto.connection import ConnectionType, WSConnection ++from wsproto import events, WSConnection ++from wsproto.connection import ConnectionType ++from wsproto.events import AcceptConnection, CloseConnection, Message, Ping, Request + from wsproto.extensions import PerMessageDeflate + + from mitmproxy import exceptions +@@ -52,51 +53,52 @@ class WebSocketLayer(base.Layer): + + self.connections: dict[object, WSConnection] = {} + +- extensions = [] ++ client_extensions = [] ++ server_extensions = [] + if 'Sec-WebSocket-Extensions' in handshake_flow.response.headers: + if PerMessageDeflate.name in handshake_flow.response.headers['Sec-WebSocket-Extensions']: +- extensions = [PerMessageDeflate()] +- self.connections[self.client_conn] = WSConnection(ConnectionType.SERVER, +- extensions=extensions) +- self.connections[self.server_conn] = WSConnection(ConnectionType.CLIENT, +- host=handshake_flow.request.host, +- resource=handshake_flow.request.path, +- extensions=extensions) +- if extensions: +- for conn in self.connections.values(): +- conn.extensions[0].finalize(conn, handshake_flow.response.headers['Sec-WebSocket-Extensions']) ++ client_extensions = [PerMessageDeflate()] ++ server_extensions = [PerMessageDeflate()] ++ self.connections[self.client_conn] = WSConnection(ConnectionType.SERVER) ++ self.connections[self.server_conn] = WSConnection(ConnectionType.CLIENT) + +- data = self.connections[self.server_conn].bytes_to_send() +- self.connections[self.client_conn].receive_bytes(data) ++ if client_extensions: ++ client_extensions[0].finalize(handshake_flow.response.headers['Sec-WebSocket-Extensions']) ++ if server_extensions: ++ server_extensions[0].finalize(handshake_flow.response.headers['Sec-WebSocket-Extensions']) + ++ request = Request(extensions=client_extensions, host=handshake_flow.request.host, target=handshake_flow.request.path) ++ data = self.connections[self.server_conn].send(request) ++ self.connections[self.client_conn].receive_data(data) ++ + event = next(self.connections[self.client_conn].events()) +- assert isinstance(event, events.ConnectionRequested) ++ assert isinstance(event, events.Request) + +- self.connections[self.client_conn].accept(event) +- self.connections[self.server_conn].receive_bytes(self.connections[self.client_conn].bytes_to_send()) +- assert isinstance(next(self.connections[self.server_conn].events()), events.ConnectionEstablished) ++ data = self.connections[self.client_conn].send(AcceptConnection(extensions=server_extensions)) ++ self.connections[self.server_conn].receive_data(data) ++ assert isinstance(next(self.connections[self.server_conn].events()), events.AcceptConnection) + + def _handle_event(self, event, source_conn, other_conn, is_server): +- if isinstance(event, events.DataReceived): +- return self._handle_data_received(event, source_conn, other_conn, is_server) +- elif isinstance(event, events.PingReceived): +- return self._handle_ping_received(event, source_conn, other_conn, is_server) +- elif isinstance(event, events.PongReceived): +- return self._handle_pong_received(event, source_conn, other_conn, is_server) +- elif isinstance(event, events.ConnectionClosed): +- return self._handle_connection_closed(event, source_conn, other_conn, is_server) ++ if isinstance(event, events.Message): ++ return self._handle_message(event, source_conn, other_conn, is_server) ++ elif isinstance(event, events.Ping): ++ return self._handle_ping(event, source_conn, other_conn, is_server) ++ elif isinstance(event, events.Pong): ++ return self._handle_pong(event, source_conn, other_conn, is_server) ++ elif isinstance(event, events.CloseConnection): ++ return self._handle_close_connection(event, source_conn, other_conn, is_server) + + # fail-safe for unhandled events + return True # pragma: no cover + +- def _handle_data_received(self, event, source_conn, other_conn, is_server): ++ def _handle_message(self, event, source_conn, other_conn, is_server): + fb = self.server_frame_buffer if is_server else self.client_frame_buffer + fb.append(event.data) + + if event.message_finished: + original_chunk_sizes = [len(f) for f in fb] + +- if isinstance(event, events.TextReceived): ++ if isinstance(event, events.TextMessage): + message_type = wsproto.frame_protocol.Opcode.TEXT + payload = ''.join(fb) + else: +@@ -127,19 +129,20 @@ class WebSocketLayer(base.Layer): + yield (payload[i:i + chunk_size], True if i + chunk_size >= len(payload) else False) + + for chunk, final in get_chunk(websocket_message.content): +- self.connections[other_conn].send_data(chunk, final) +- other_conn.send(self.connections[other_conn].bytes_to_send()) ++ data = self.connections[other_conn].send(Message(data=chunk, message_finished=final)) ++ other_conn.send(data) + + if self.flow.stream: +- self.connections[other_conn].send_data(event.data, event.message_finished) +- other_conn.send(self.connections[other_conn].bytes_to_send()) ++ data = self.connections[other_conn].send(Message(data=event.data, message_finished=event.message_finished)) ++ other_conn.send(data) + return True + +- def _handle_ping_received(self, event, source_conn, other_conn, is_server): +- # PING is automatically answered with a PONG by wsproto +- self.connections[other_conn].ping() +- other_conn.send(self.connections[other_conn].bytes_to_send()) +- source_conn.send(self.connections[source_conn].bytes_to_send()) ++ def _handle_ping(self, event, source_conn, other_conn, is_server): ++ # Use event.response to create the approprate Pong response ++ data = self.connections[other_conn].send(Ping()) ++ other_conn.send(data) ++ data = self.connections[source_conn].send(event.response()) ++ source_conn.send(data) + self.log( + "Ping Received from {}".format("server" if is_server else "client"), + "info", +@@ -147,7 +150,7 @@ class WebSocketLayer(base.Layer): + ) + return True + +- def _handle_pong_received(self, event, source_conn, other_conn, is_server): ++ def _handle_pong(self, event, source_conn, other_conn, is_server): + self.log( + "Pong Received from {}".format("server" if is_server else "client"), + "info", +@@ -155,14 +158,15 @@ class WebSocketLayer(base.Layer): + ) + return True + +- def _handle_connection_closed(self, event, source_conn, other_conn, is_server): ++ def _handle_close_connection(self, event, source_conn, other_conn, is_server): + self.flow.close_sender = "server" if is_server else "client" + self.flow.close_code = event.code + self.flow.close_reason = event.reason + +- self.connections[other_conn].close(event.code, event.reason) +- other_conn.send(self.connections[other_conn].bytes_to_send()) +- source_conn.send(self.connections[source_conn].bytes_to_send()) ++ data = self.connections[other_conn].send(CloseConnection(code=event.code, reason=event.reason)) ++ other_conn.send(data) ++ data = self.connections[source_conn].send(event.response()) ++ source_conn.send(data) + + return False + +@@ -170,8 +174,7 @@ class WebSocketLayer(base.Layer): + while True: + try: + payload = message_queue.get_nowait() +- self.connections[endpoint].send_data(payload, final=True) +- data = self.connections[endpoint].bytes_to_send() ++ data = self.connections[endpoint].send(Message(data=payload, message_finished=True)) + endpoint.send(data) + except queue.Empty: + break +@@ -197,8 +200,8 @@ class WebSocketLayer(base.Layer): + is_server = (source_conn == self.server_conn) + + frame = websockets.Frame.from_file(source_conn.rfile) +- self.connections[source_conn].receive_bytes(bytes(frame)) +- source_conn.send(self.connections[source_conn].bytes_to_send()) ++ data = self.connections[source_conn].receive_data(bytes(frame)) ++ source_conn.send(data) + + if close_received: + return diff --git a/www/mitmproxy/files/patch-setup.py b/www/mitmproxy/files/patch-setup.py new file mode 100644 index 000000000000..3a63db04ef97 --- /dev/null +++ b/www/mitmproxy/files/patch-setup.py @@ -0,0 +1,24 @@ +--- setup.py.orig 2019-02-14 12:22:24 UTC ++++ setup.py +@@ -61,7 +61,7 @@ setup( + # It is not considered best practice to use install_requires to pin dependencies to specific versions. + install_requires=[ + "blinker>=1.4", +- "brotli>=0.7.0,<0.8", ++ "brotli>=0.7.0", + "certifi>=2015.11.20.1", # no semver here - this should always be on the last release! + "click>=6.2", + "cryptography>=2.1.4,<2.4", +@@ -75,10 +75,10 @@ setup( + "pyparsing>=2.1.3", + "pyperclip>=1.6.0", + "ruamel.yaml>=0.13.2", +- "sortedcontainers>=1.5.4,<2.1", ++ "sortedcontainers>=1.5.4", + "tornado>=4.3,<5.2", + "urwid>=2.0.1,<2.1", +- "wsproto>=0.11.0,<0.12.0", ++ "wsproto>=0.13.0", + ], + extras_require={ + ':sys_platform == "win32"': [ -- cgit v1.2.3