summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2013-12-13 07:00:45 -0400
committerKali Kaneko <kali@leap.se>2013-12-13 07:00:45 -0400
commit678858255bb046f4dd5cbdb51ce9820ce9f651a0 (patch)
tree520f877b6557556db42f292fb7d5f147b20107e4
parent7b7ffbc372031bd6a87d44d9573eacf300424790 (diff)
enable gzip compression
-rw-r--r--server/changes/feature_enable-gzip1
-rw-r--r--server/src/leap/soledad/server/__init__.py7
-rw-r--r--server/src/leap/soledad/server/gzip.py69
3 files changed, 75 insertions, 2 deletions
diff --git a/server/changes/feature_enable-gzip b/server/changes/feature_enable-gzip
new file mode 100644
index 00000000..5cc1597c
--- /dev/null
+++ b/server/changes/feature_enable-gzip
@@ -0,0 +1 @@
+ o Enable Gzip compression on the soledad wsgi app.
diff --git a/server/src/leap/soledad/server/__init__.py b/server/src/leap/soledad/server/__init__.py
index 9cad6093..de5daf62 100644
--- a/server/src/leap/soledad/server/__init__.py
+++ b/server/src/leap/soledad/server/__init__.py
@@ -110,6 +110,8 @@ if version.base() == "12.0.0":
sys.modules['OpenSSL.tsafe'] = old_tsafe
from leap.soledad.server.auth import SoledadTokenAuthMiddleware
+from leap.soledad.server.gzip import GzipMiddleware
+
from leap.soledad.common import (
SHARED_DB_NAME,
SHARED_DB_LOCK_DOC_ID_PREFIX,
@@ -378,8 +380,9 @@ def application(environ, start_response):
SoledadApp.SHARED_DB_NAME,
SoledadTokenAuthMiddleware.TOKENS_DB)
# WSGI application that may be used by `twistd -web`
- application = SoledadTokenAuthMiddleware(SoledadApp(state))
- resource = WSGIResource(reactor, reactor.getThreadPool(), application)
+ application = GzipMiddleware(
+ SoledadTokenAuthMiddleware(SoledadApp(state)))
+
return application(environ, start_response)
diff --git a/server/src/leap/soledad/server/gzip.py b/server/src/leap/soledad/server/gzip.py
new file mode 100644
index 00000000..92906513
--- /dev/null
+++ b/server/src/leap/soledad/server/gzip.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+# gzip.py
+# Copyright (C) 2013 LEAP
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+Gzip middleware for WSGI apps.
+"""
+import gzip
+import StringIO
+
+
+class GzipMiddleware(object):
+ """
+ GzipMiddleware class for WSGI.
+ """
+ def __init__(self, app, compresslevel=9):
+ self.app = app
+ self.compresslevel = compresslevel
+
+ def __call__(self, environ, start_response):
+ if 'gzip' not in environ.get('HTTP_ACCEPT_ENCODING', ''):
+ return self.app(environ, start_response)
+ if (environ['PATH_INFO'][-3:] != '.js' and environ[
+ 'PATH_INFO'][-4:] != '.css'):
+ return self.app(environ, start_response)
+ buffer = StringIO.StringIO()
+ output = gzip.GzipFile(
+ mode='wb',
+ compresslevel=self.compresslevel,
+ fileobj=buffer
+ )
+
+ start_response_args = []
+
+ def dummy_start_response(status, headers, exc_info=None):
+ start_response_args.append(status)
+ start_response_args.append(headers)
+ start_response_args.append(exc_info)
+ return output.write
+
+ app_iter = self.app(environ, dummy_start_response)
+ for line in app_iter:
+ output.write(line)
+ if hasattr(app_iter, 'close'):
+ app_iter.close()
+ output.close()
+ buffer.seek(0)
+ result = buffer.getvalue()
+ headers = []
+ for name, value in start_response_args[1]:
+ if name.lower() != 'content-length':
+ headers.append((name, value))
+ headers.append(('Content-Length', str(len(result))))
+ headers.append(('Content-Encoding', 'gzip'))
+ start_response(start_response_args[0], headers, start_response_args[2])
+ buffer.close()
+ return [result]