[odrs-web] httpd: Support content encoding and pre-compressed forms of ratings.json



commit 7842ea9948b16b52bc10051fadb03e6919b0a584
Author: Philip Withnall <withnall endlessm com>
Date:   Tue Aug 11 16:07:34 2020 +0100

    httpd: Support content encoding and pre-compressed forms of ratings.json
    
    `ratings.json` is quite large (currently 827598B). When gzipped, it
    drops to 103478B, and when brotli-encoded it drops to 81655B (a factor
    of 10 smaller than the original file).
    
    Since this is one of the most commonly-requested ODRS endpoints, it
    probably will help our bandwidth bills (and client download times) to
    allow compression on it, using the `Content-Encoding` HTTP header.
    
    brotli compression, in particular, is not very fast (takes around 1s to
    compress `ratings.json`), so we should cache the pre-compressed files on
    the server.
    
    This is based off the following documentation:
     - https://httpd.apache.org/docs/2.4/mod/mod_brotli.html
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 Dockerfile                             |  2 ++
 app_data/httpd-cfg/odrs.gnome.org.conf | 39 ++++++++++++++++++++++++++++++++++
 app_data/httpd-pre-init/entrypoint.sh  |  7 +++++-
 3 files changed, 47 insertions(+), 1 deletion(-)
---
diff --git a/Dockerfile b/Dockerfile
index 40c3009..6c96011 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -35,6 +35,8 @@ RUN curl https://raw.githubusercontent.com/hughsie/badwords/master/badwords.csv
 RUN LANG=en_US.utf8 python3 /opt/app-root/src/cron.py taboo-import /tmp/badwords.csv
 
 RUN python3 /opt/app-root/src/cron.py ratings /opt/app-root/src/odrs/static/ratings.json
+RUN gzip -k /opt/app-root/src/odrs/static/ratings.json
+RUN brotli -k /opt/app-root/src/odrs/static/ratings.json
 
 RUN chown -R 1000310000:0 ${ODRS_HOME} && \
     chmod -R 664 ${ODRS_HOME} && \
diff --git a/app_data/httpd-cfg/odrs.gnome.org.conf b/app_data/httpd-cfg/odrs.gnome.org.conf
index 51c05f4..339fe79 100644
--- a/app_data/httpd-cfg/odrs.gnome.org.conf
+++ b/app_data/httpd-cfg/odrs.gnome.org.conf
@@ -27,6 +27,45 @@
         ExpiresByType application/json "access plus 2 weeks"
         Header set Cache-Control "public"
     </Directory>
+
+    <IfModule mod_headers.c>
+        # Serve gzip/br compressed CSS and JS files if they exist
+        # and the client accepts gzip/br.
+        RewriteCond "%{HTTP:Accept-encoding}" "gzip"
+        RewriteCond "%{REQUEST_FILENAME}\.gz" -s
+        RewriteRule "^(.*)\.(js|css|json)"         "$1\.$2\.gz" [QSA]
+
+        RewriteCond "%{HTTP:Accept-encoding}" "br"
+        RewriteCond "%{REQUEST_FILENAME}\.br" -s
+        RewriteRule "^(.*)\.(js|css|json)"         "$1\.$2\.br" [QSA]
+
+        # Serve correct content types, and prevent double compression.
+        RewriteRule "\.js\.gz$" "-" [T=application/javascript,E=no-gzip:1]
+        RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1]
+        RewriteRule "\.json\.gz$" "-" [T=application/json,E=no-gzip:1]
+
+        RewriteRule "\.js\.br$" "-" [T=application/javascript,E=no-brotli:1]
+        RewriteRule "\.css\.br$" "-" [T=text/css,E=no-brotli:1]
+        RewriteRule "\.json\.br$" "-" [T=application/json,E=no-brotli:1]
+
+        <FilesMatch "(\.js\.gz|\.css\.gz|\.json\.gz)$">
+            # Serve correct encoding type.
+            Header append Content-Encoding gzip
+
+            # Force proxies to cache gzipped &
+            # non-gzipped files separately.
+            Header append Vary Accept-Encoding
+        </FilesMatch>
+
+        <FilesMatch "(\.js\.br|\.css\.br|\.json\.br)$">
+            # Serve correct encoding type.
+            Header append Content-Encoding br
+
+            # Force proxies to cache brotlied &
+            # non-brotlied files separately.
+            Header append Vary Accept-Encoding
+        </FilesMatch>
+    </IfModule>
 </VirtualHost>
 
 <Directory "/opt/app-root/src/odrs/static">
diff --git a/app_data/httpd-pre-init/entrypoint.sh b/app_data/httpd-pre-init/entrypoint.sh
index c1f2d98..b1a0303 100755
--- a/app_data/httpd-pre-init/entrypoint.sh
+++ b/app_data/httpd-pre-init/entrypoint.sh
@@ -2,5 +2,10 @@
 
 python3 /opt/app-root/src/wsgi-scripts/odrs-apache-setup.py ${HTTPD_CONFIGURATION_PATH}/odrs.gnome.org.conf
 
-while true; do python3 /opt/app-root/src/cron.py ratings /opt/app-root/src/odrs/static/ratings.json ; sleep 
43200 ; done &
+while true; do
+  python3 /opt/app-root/src/cron.py ratings /opt/app-root/src/odrs/static/ratings.json
+  sleep 43200
+  gzip -k /opt/app-root/src/odrs/static/ratings.json
+  brotli -k /opt/app-root/src/odrs/static/ratings.json
+done &
 while true; do python3 /opt/app-root/src/cron.py fsck ; sleep 43200 ; done &


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]