From d95642f6d913a99fc44f0ac0695d53534afb7962 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Tue, 29 May 2018 07:43:47 +0900 Subject: [PATCH] Cache attachments on external host with service worker (#7493) --- .env.production.sample | 8 ++++++++ .eslintrc.yml | 3 +++ .../mastodon/service_worker/entry.js | 2 +- config/webpack/production.js | 20 +++++++++++++++++-- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/.env.production.sample b/.env.production.sample index 24b6b01439..3047f75950 100644 --- a/.env.production.sample +++ b/.env.production.sample @@ -88,6 +88,10 @@ SMTP_FROM_ADDRESS=notifications@example.com # CDN_HOST=https://assets.example.com # S3 (optional) +# The attachment host must allow cross origin request from WEB_DOMAIN or +# LOCAL_DOMAIN if WEB_DOMAIN is not set. For example, the server may have the +# following header field: +# Access-Control-Allow-Origin: https://192.168.1.123:9000/ # S3_ENABLED=true # S3_BUCKET= # AWS_ACCESS_KEY_ID= @@ -97,6 +101,8 @@ SMTP_FROM_ADDRESS=notifications@example.com # S3_HOSTNAME=192.168.1.123:9000 # S3 (Minio Config (optional) Please check Minio instance for details) +# The attachment host must allow cross origin request - see the description +# above. # S3_ENABLED=true # S3_BUCKET= # AWS_ACCESS_KEY_ID= @@ -108,6 +114,8 @@ SMTP_FROM_ADDRESS=notifications@example.com # S3_SIGNATURE_VERSION= # Swift (optional) +# The attachment host must allow cross origin request - see the description +# above. # SWIFT_ENABLED=true # SWIFT_USERNAME= # For Keystone V3, the value for SWIFT_TENANT should be the project name diff --git a/.eslintrc.yml b/.eslintrc.yml index 576e5b70ac..205c9460ae 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -7,6 +7,9 @@ env: es6: true jest: true +globals: + ATTACHMENT_HOST: false + parser: babel-eslint plugins: diff --git a/app/javascript/mastodon/service_worker/entry.js b/app/javascript/mastodon/service_worker/entry.js index ce42271a9a..c1854c1cd2 100644 --- a/app/javascript/mastodon/service_worker/entry.js +++ b/app/javascript/mastodon/service_worker/entry.js @@ -49,7 +49,7 @@ self.addEventListener('fetch', function(event) { return response; })); - } else if (storageFreeable && process.env.CDN_HOST ? url.host === process.env.CDN_HOST : url.pathname.startsWith('/system/')) { + } else if (storageFreeable && (ATTACHMENT_HOST ? url.host === ATTACHMENT_HOST : url.pathname.startsWith('/system/'))) { event.respondWith(openSystemCache().then(cache => { return cache.match(event.request.url).then(cached => { if (cached === undefined) { diff --git a/config/webpack/production.js b/config/webpack/production.js index a823307916..408c56930c 100644 --- a/config/webpack/production.js +++ b/config/webpack/production.js @@ -6,8 +6,9 @@ const CompressionPlugin = require('compression-webpack-plugin'); const sharedConfig = require('./shared.js'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const OfflinePlugin = require('offline-plugin'); -const { env, publicPath } = require('./configuration.js'); +const { publicPath } = require('./configuration.js'); const path = require('path'); +const { URL } = require('url'); let compressionAlgorithm; try { @@ -19,6 +20,21 @@ try { compressionAlgorithm = 'gzip'; } +let attachmentHost; + +if (process.env.S3_ENABLED === 'true') { + if (process.env.S3_CLOUDFRONT_HOST) { + attachmentHost = process.env.S3_CLOUDFRONT_HOST; + } else { + attachmentHost = process.env.S3_HOSTNAME || `s3-${process.env.S3_REGION || 'us-east-1'}.amazonaws.com`; + } +} else if (process.env.SWIFT_ENABLED === 'true') { + const { host } = new URL(process.env.SWIFT_OBJECT_URL); + attachmentHost = host; +} else { + attachmentHost = null; +} + module.exports = merge(sharedConfig, { output: { filename: '[name]-[chunkhash].js', @@ -90,7 +106,7 @@ module.exports = merge(sharedConfig, { '**/*.woff', ], ServiceWorker: { - entry: `imports-loader?process.env=>${encodeURIComponent(JSON.stringify(env))}!${encodeURI(path.join(__dirname, '../../app/javascript/mastodon/service_worker/entry.js'))}`, + entry: `imports-loader?ATTACHMENT_HOST=>${encodeURIComponent(JSON.stringify(attachmentHost))}!${encodeURI(path.join(__dirname, '../../app/javascript/mastodon/service_worker/entry.js'))}`, cacheName: 'mastodon', output: '../assets/sw.js', publicPath: '/sw.js',