Repository: streamlit/streamlit

Issue:
Create a config option to toggle websocket compression in Streamlit server
# Problem

PR #1506 enabled websocket compression in Streamlit server by default.  It's a great feature and while it works well when connecting to the server directly, some reverse proxies may not support the websocket compression, making the app unaccessible.

### Solution

**MVP:**
Create a new boolean config option `server.enableWebsocketCompression` to toggle websocket compression.  It should be enabled by default, and optionally users can override and disable it.




Discussion:

Resolving patch:
diff --git a/lib/streamlit/config.py b/lib/streamlit/config.py
--- a/lib/streamlit/config.py
+++ b/lib/streamlit/config.py
@@ -125,7 +125,7 @@ def _create_option(
                 default_val = 12345)
 
         (2) More complex, programmable config options use decorator syntax to
-        resolve thier values at runtime:
+        resolve their values at runtime:
 
             @_create_option('section.optionName')
             def _section_option_name():
@@ -498,6 +498,15 @@ def _server_max_upload_size():
     return 200
 
 
+@_create_option("server.enableWebsocketCompression", type_=bool)
+def _server_enable_websocket_compression():
+    """Enables support for websocket compression.
+
+    Default: true
+    """
+    return True
+
+
 # Config Section: Browser #
 
 _create_section("browser", "Configuration of browser front-end.")
diff --git a/lib/streamlit/server/Server.py b/lib/streamlit/server/Server.py
--- a/lib/streamlit/server/Server.py
+++ b/lib/streamlit/server/Server.py
@@ -608,12 +608,14 @@ def on_close(self):
     def get_compression_options(self):
         """Enable WebSocket compression.
 
-        By default, this method returns None, which means compression
-        is disabled. Returning an empty dict enables it.
+        Returning an empty dict enables websocket compression. Returning
+        None disables it.
 
         (See the docstring in the parent class.)
         """
-        return {}
+        if config.get_option("server.enableWebsocketCompression"):
+            return {}
+        return None
 
     @tornado.gen.coroutine
     def on_message(self, payload):


Test patch:
diff --git a/lib/tests/streamlit/Server_test.py b/lib/tests/streamlit/Server_test.py
--- a/lib/tests/streamlit/Server_test.py
+++ b/lib/tests/streamlit/Server_test.py
@@ -162,6 +162,22 @@ def test_websocket_compression(self):
             extensions = ws_client.headers.get("Sec-Websocket-Extensions")
             self.assertIn("permessage-deflate", extensions)
 
+    @tornado.testing.gen_test
+    def test_websocket_compression_disabled(self):
+        with self._patch_report_session():
+            config._set_option("server.enableWebsocketCompression", False, "test")
+            yield self.start_server_loop()
+
+            # Connect to the server, and explicitly request compression.
+            ws_client = yield tornado.websocket.websocket_connect(
+                self.get_ws_url("/stream"), compression_options={}
+            )
+
+            # Ensure that the "Sec-Websocket-Extensions" header is not
+            # present in the response from the server.
+            self.assertIsNone(ws_client.headers.get("Sec-Websocket-Extensions"))
+
+
     @tornado.testing.gen_test
     def test_forwardmsg_hashing(self):
         """Test that outgoing ForwardMsgs contain hashes."""
diff --git a/lib/tests/streamlit/config_test.py b/lib/tests/streamlit/config_test.py
--- a/lib/tests/streamlit/config_test.py
+++ b/lib/tests/streamlit/config_test.py
@@ -300,6 +300,7 @@ def test_config_option_keys(self):
                 "s3.secretAccessKey",
                 "s3.url",
                 "server.enableCORS",
+                "server.enableWebsocketCompression",
                 "server.baseUrlPath",
                 "server.cookieSecret",
                 "server.folderWatchBlacklist",