From 049244e8a8d4b30d5201d51b290f4bb2c2876d77 Mon Sep 17 00:00:00 2001 From: Moritz Ulrich Date: Sun, 27 Jan 2019 17:23:24 +0100 Subject: [PATCH] WebServer: Enable deflate and gzip compression (#3677) * get-index: Enable deflate and gzip compression * Spaces -> Tabs * listen: Add optional `gzip=yes` parameter (defaults to "no") * get-index: Add comment explaining the usage of `zlib.*Sync` instead of async. --- core/language/en-GB/Help/listen.tid | 1 + core/modules/server/routes/get-index.js | 30 +++++++++++++++++++++++-- core/modules/server/server.js | 5 ++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/core/language/en-GB/Help/listen.tid b/core/language/en-GB/Help/listen.tid index 15b77d061..88208ea29 100644 --- a/core/language/en-GB/Help/listen.tid +++ b/core/language/en-GB/Help/listen.tid @@ -28,6 +28,7 @@ All parameters are optional with safe defaults, and can be specified in any orde * ''tls-cert'' - pathname of TLS certificate file (relative to wiki folder) * ''tls-key'' - pathname of TLS key file (relative to wiki folder) * ''debug-level'' - optional debug level; set to "debug" to view request details (defaults to "none") +* ''gzip'' - set to "yes" to enable gzip compression for some http endpoints (defaults to "no") For information on opening up your instance to the entire local network, and possible security concerns, see the WebServer tiddler at TiddlyWiki.com. diff --git a/core/modules/server/routes/get-index.js b/core/modules/server/routes/get-index.js index 603103c6b..08021af64 100644 --- a/core/modules/server/routes/get-index.js +++ b/core/modules/server/routes/get-index.js @@ -12,14 +12,40 @@ GET / /*global $tw: false */ "use strict"; +var zlib = require('zlib'); + exports.method = "GET"; exports.path = /^\/$/; exports.handler = function(request,response,state) { - response.writeHead(200, {"Content-Type": state.server.get("root-serve-type")}); + var acceptEncoding = request.headers['accept-encoding']; + if (!acceptEncoding) { acceptEncoding = ''; } + var text = state.wiki.renderTiddler(state.server.get("root-render-type"),state.server.get("root-tiddler")); - response.end(text,"utf8"); + + var responseHeaders = { + "Content-Type": state.server.get("root-serve-type") + }; + + /* + If the gzip=yes flag for `listen` is set, check if the user agent permits + compression. If so, compress our response. Note that we use the synchronous + functions from zlib to stay in the imperative style. The current `Server` + doesn't depend on this, and we may just as well use the async versions. + */ + if(state.server.enableGzip) { + if (/\bdeflate\b/.test(acceptEncoding)) { + responseHeaders['Content-Encoding'] = 'deflate'; + text = zlib.deflateSync(text); + } else if (/\bgzip\b/.test(acceptEncoding)) { + responseHeaders['Content-Encoding'] = 'gzip'; + text = zlib.gzipSync(text); + } + } + + response.writeHead(200, responseHeaders); + response.end(text); }; }()); diff --git a/core/modules/server/server.js b/core/modules/server/server.js index 02268d2a2..a763773bb 100644 --- a/core/modules/server/server.js +++ b/core/modules/server/server.js @@ -43,6 +43,8 @@ function Server(options) { $tw.utils.extend({},this.defaultVariables,options.variables); // Initialise CSRF this.csrfDisable = this.get("csrf-disable") === "yes"; + // Initialize Gzip compression + this.enableGzip = this.get("gzip") === "yes"; // Initialise authorization var authorizedUserName = (this.get("username") && this.get("password")) ? this.get("username") : "(anon)"; this.authorizationPrincipals = { @@ -84,7 +86,8 @@ Server.prototype.defaultVariables = { "tiddler-render-template": "$:/core/templates/server/static.tiddler.html", "system-tiddler-render-type": "text/plain", "system-tiddler-render-template": "$:/core/templates/wikified-tiddler", - "debug-level": "none" + "debug-level": "none", + "gzip": "no" }; Server.prototype.get = function(name) {