From 1b04a562322a386ef806f1ada73e83d40fa1f0ce Mon Sep 17 00:00:00 2001
From: Miguel Grinberg <miguel.grinberg@gmail.com>
Date: Wed, 5 Jul 2023 11:53:57 +0100
Subject: [PATCH] Configure eventlet's websocket max frame length (Fixes #319)

---
 src/engineio/async_drivers/aiohttp.py      | 4 ++--
 src/engineio/async_drivers/asgi.py         | 2 +-
 src/engineio/async_drivers/eventlet.py     | 6 ++++--
 src/engineio/async_drivers/gevent.py       | 4 ++--
 src/engineio/async_drivers/gevent_uwsgi.py | 4 ++--
 src/engineio/async_drivers/sanic.py        | 2 +-
 src/engineio/async_drivers/threading.py    | 4 ++--
 src/engineio/async_drivers/tornado.py      | 2 +-
 src/engineio/asyncio_socket.py             | 3 ++-
 src/engineio/socket.py                     | 3 ++-
 tests/asyncio/test_asyncio_socket.py       | 2 +-
 tests/common/test_async_eventlet.py        | 4 ++--
 tests/common/test_socket.py                | 2 +-
 13 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/src/engineio/async_drivers/aiohttp.py b/src/engineio/async_drivers/aiohttp.py
index a5919958..a68d3094 100644
--- a/src/engineio/async_drivers/aiohttp.py
+++ b/src/engineio/async_drivers/aiohttp.py
@@ -84,13 +84,13 @@ class WebSocket(object):  # pragma: no cover
     This wrapper class provides a aiohttp WebSocket interface that is
     somewhat compatible with eventlet's implementation.
     """
-    def __init__(self, handler):
+    def __init__(self, handler, server):
         self.handler = handler
         self._sock = None
 
     async def __call__(self, environ):
         request = environ['aiohttp.request']
-        self._sock = WebSocketResponse()
+        self._sock = WebSocketResponse(max_msg_size=0)
         await self._sock.prepare(request)
 
         self.environ = environ
diff --git a/src/engineio/async_drivers/asgi.py b/src/engineio/async_drivers/asgi.py
index d6618411..94716d7e 100644
--- a/src/engineio/async_drivers/asgi.py
+++ b/src/engineio/async_drivers/asgi.py
@@ -223,7 +223,7 @@ class WebSocket(object):  # pragma: no cover
     This wrapper class provides an asgi WebSocket interface that is
     somewhat compatible with eventlet's implementation.
     """
-    def __init__(self, handler):
+    def __init__(self, handler, server):
         self.handler = handler
         self.asgi_receive = None
         self.asgi_send = None
diff --git a/src/engineio/async_drivers/eventlet.py b/src/engineio/async_drivers/eventlet.py
index 9be3797c..2434c3e9 100644
--- a/src/engineio/async_drivers/eventlet.py
+++ b/src/engineio/async_drivers/eventlet.py
@@ -7,8 +7,10 @@
 
 
 class WebSocketWSGI(_WebSocketWSGI):
-    def __init__(self, *args, **kwargs):
-        super(WebSocketWSGI, self).__init__(*args, **kwargs)
+    def __init__(self, handler, server):
+        print(server.max_http_buffer_size)
+        super(WebSocketWSGI, self).__init__(
+            handler, max_frame_length=int(server.max_http_buffer_size))
         self._sock = None
 
     def __call__(self, environ, start_response):
diff --git a/src/engineio/async_drivers/gevent.py b/src/engineio/async_drivers/gevent.py
index 024dd0aa..b3c6d151 100644
--- a/src/engineio/async_drivers/gevent.py
+++ b/src/engineio/async_drivers/gevent.py
@@ -27,8 +27,8 @@ class WebSocketWSGI(object):  # pragma: no cover
     This wrapper class provides a gevent WebSocket interface that is
     compatible with eventlet's implementation.
     """
-    def __init__(self, app):
-        self.app = app
+    def __init__(self, handler, server):
+        self.app = handler
 
     def __call__(self, environ, start_response):
         if 'wsgi.websocket' not in environ:
diff --git a/src/engineio/async_drivers/gevent_uwsgi.py b/src/engineio/async_drivers/gevent_uwsgi.py
index 9a5cc0ce..9bbdd01d 100644
--- a/src/engineio/async_drivers/gevent_uwsgi.py
+++ b/src/engineio/async_drivers/gevent_uwsgi.py
@@ -23,8 +23,8 @@ class uWSGIWebSocket(object):  # pragma: no cover
     This wrapper class provides a uWSGI WebSocket interface that is
     compatible with eventlet's implementation.
     """
-    def __init__(self, app):
-        self.app = app
+    def __init__(self, handler, server):
+        self.app = handler
         self._sock = None
         self.received_messages = []
 
diff --git a/src/engineio/async_drivers/sanic.py b/src/engineio/async_drivers/sanic.py
index 88b3e5ff..70a62239 100644
--- a/src/engineio/async_drivers/sanic.py
+++ b/src/engineio/async_drivers/sanic.py
@@ -112,7 +112,7 @@ class WebSocket(object):  # pragma: no cover
     This wrapper class provides a sanic WebSocket interface that is
     somewhat compatible with eventlet's implementation.
     """
-    def __init__(self, handler):
+    def __init__(self, handler, server):
         self.handler = handler
         self._sock = None
 
diff --git a/src/engineio/async_drivers/threading.py b/src/engineio/async_drivers/threading.py
index de8df794..8af578bd 100644
--- a/src/engineio/async_drivers/threading.py
+++ b/src/engineio/async_drivers/threading.py
@@ -15,8 +15,8 @@ class WebSocketWSGI(object):  # pragma: no cover
     This wrapper class provides a threading WebSocket interface that is
     compatible with eventlet's implementation.
     """
-    def __init__(self, app):
-        self.app = app
+    def __init__(self, handler, server):
+        self.app = handler
 
     def __call__(self, environ, start_response):
         self.ws = Server(environ)
diff --git a/src/engineio/async_drivers/tornado.py b/src/engineio/async_drivers/tornado.py
index eb1c4de8..2c70135a 100644
--- a/src/engineio/async_drivers/tornado.py
+++ b/src/engineio/async_drivers/tornado.py
@@ -147,7 +147,7 @@ class WebSocket(object):  # pragma: no cover
     This wrapper class provides a tornado WebSocket interface that is
     somewhat compatible with eventlet's implementation.
     """
-    def __init__(self, handler):
+    def __init__(self, handler, server):
         self.handler = handler
         self.tornado_handler = None
 
diff --git a/src/engineio/asyncio_socket.py b/src/engineio/asyncio_socket.py
index 17265c20..84479666 100644
--- a/src/engineio/asyncio_socket.py
+++ b/src/engineio/asyncio_socket.py
@@ -138,7 +138,8 @@ async def _upgrade_websocket(self, environ):
         if self.server._async['websocket'] is None:
             # the selected async mode does not support websocket
             return self.server._bad_request()
-        ws = self.server._async['websocket'](self._websocket_handler)
+        ws = self.server._async['websocket'](
+            self._websocket_handler, self.server)
         return await ws(environ)
 
     async def _websocket_handler(self, ws):
diff --git a/src/engineio/socket.py b/src/engineio/socket.py
index be0c83f6..2cf8b0aa 100644
--- a/src/engineio/socket.py
+++ b/src/engineio/socket.py
@@ -154,7 +154,8 @@ def _upgrade_websocket(self, environ, start_response):
         if self.server._async['websocket'] is None:
             # the selected async mode does not support websocket
             return self.server._bad_request()
-        ws = self.server._async['websocket'](self._websocket_handler)
+        ws = self.server._async['websocket'](
+            self._websocket_handler, self.server)
         return ws(environ, start_response)
 
     def _websocket_handler(self, ws):
diff --git a/tests/asyncio/test_asyncio_socket.py b/tests/asyncio/test_asyncio_socket.py
index 6af50e93..30e8f7a4 100644
--- a/tests/asyncio/test_asyncio_socket.py
+++ b/tests/asyncio/test_asyncio_socket.py
@@ -252,7 +252,7 @@ def test_upgrade(self):
         environ = "foo"
         _run(s._upgrade_websocket(environ))
         mock_server._async['websocket'].assert_called_once_with(
-            s._websocket_handler
+            s._websocket_handler, mock_server
         )
         mock_ws.mock.assert_called_once_with(environ)
 
diff --git a/tests/common/test_async_eventlet.py b/tests/common/test_async_eventlet.py
index 2509677e..9cd652df 100644
--- a/tests/common/test_async_eventlet.py
+++ b/tests/common/test_async_eventlet.py
@@ -11,7 +11,7 @@ def setUp(self):
         logging.getLogger('engineio').setLevel(logging.NOTSET)
 
     def test_bad_environ(self):
-        wsgi = async_eventlet.WebSocketWSGI(None)
+        wsgi = async_eventlet.WebSocketWSGI(None, mock.MagicMock())
         environ = {'foo': 'bar'}
         start_response = 'bar'
         with pytest.raises(RuntimeError):
@@ -25,5 +25,5 @@ def test_wsgi_call(self, _WebSocketWSGI):
         _WebSocketWSGI.__call__ = lambda e, s: 'data'
         environ = {'eventlet.input': mock.MagicMock()}
         start_response = 'bar'
-        wsgi = async_eventlet.WebSocketWSGI(None)
+        wsgi = async_eventlet.WebSocketWSGI(None, mock.MagicMock())
         assert wsgi(environ, start_response) == 'data'
diff --git a/tests/common/test_socket.py b/tests/common/test_socket.py
index 84e43175..41b7424c 100644
--- a/tests/common/test_socket.py
+++ b/tests/common/test_socket.py
@@ -235,7 +235,7 @@ def test_upgrade(self):
         start_response = "bar"
         s._upgrade_websocket(environ, start_response)
         mock_server._async['websocket'].assert_called_once_with(
-            s._websocket_handler
+            s._websocket_handler, mock_server
         )
         mock_ws.assert_called_once_with(environ, start_response)
 
