From af4938baf15b4551ba8fc9727e6b9f482afd50c7 Mon Sep 17 00:00:00 2001 From: Vinoth Kannan Date: Fri, 30 Oct 2020 10:35:35 +0530 Subject: [PATCH] Revert "DEV: enable cors to all cdn get requests from workbox. (#10684)" (#11076) This reverts commit e3de45359f9bc7a71d9b8045a7e369fd0cf8f433. We need to improve out strategy by adding a cache breaker with this change ... some assets on CDNs and clients may have incorrect CORS headers which can cause stuff to break. --- app/assets/javascripts/service-worker.js.erb | 93 +------- app/controllers/application_controller.rb | 14 -- app/controllers/highlight_js_controller.rb | 2 - app/controllers/static_controller.rb | 2 - app/controllers/stylesheets_controller.rb | 2 - app/controllers/svg_sprite_controller.rb | 2 - .../theme_javascripts_controller.rb | 2 - app/controllers/uploads_controller.rb | 2 - app/controllers/user_avatars_controller.rb | 2 - config/initializers/008-rack-cors.rb | 12 +- lib/discourse.rb | 19 -- lib/middleware/enforce_hostname.rb | 1 - lib/tasks/javascript.rake | 4 - package.json | 1 - .../workbox/workbox-cacheable-response.dev.js | 200 ------------------ .../workbox-cacheable-response.dev.js.map | 1 - .../workbox-cacheable-response.prod.js | 2 - .../workbox-cacheable-response.prod.js.map | 1 - spec/requests/application_controller_spec.rb | 11 - spec/requests/static_controller_spec.rb | 19 -- yarn.lock | 7 - 21 files changed, 8 insertions(+), 391 deletions(-) delete mode 100644 public/javascripts/workbox/workbox-cacheable-response.dev.js delete mode 100644 public/javascripts/workbox/workbox-cacheable-response.dev.js.map delete mode 100644 public/javascripts/workbox/workbox-cacheable-response.prod.js delete mode 100644 public/javascripts/workbox/workbox-cacheable-response.prod.js.map diff --git a/app/assets/javascripts/service-worker.js.erb b/app/assets/javascripts/service-worker.js.erb index 0b736be4453..f2640948171 100644 --- a/app/assets/javascripts/service-worker.js.erb +++ b/app/assets/javascripts/service-worker.js.erb @@ -4,109 +4,24 @@ importScripts("<%= "#{Discourse.asset_host}#{Discourse.base_path}/javascripts/wo workbox.setConfig({ modulePathPrefix: "<%= "#{Discourse.asset_host}#{Discourse.base_path}/javascripts/workbox" %>", - debug: <%= Rails.env.development? %> + debug: false }); var authUrl = "<%= Discourse.base_path %>/auth/"; var cacheVersion = "1"; -var discourseCacheName = "discourse-" + cacheVersion; -var externalCacheName = "external-" + cacheVersion; // Cache all GET requests, so Discourse can be used while offline - workbox.routing.registerRoute( function(args) { - return args.url.origin === location.origin && !args.url.pathname.startsWith(authUrl); + return !(args.url.origin === location.origin && args.url.pathname.startsWith(authUrl)); }, // Match all except auth routes new workbox.strategies.NetworkFirst({ // This will only use the cache when a network request fails - cacheName: discourseCacheName, + cacheName: "discourse-" + cacheVersion, plugins: [ - new workbox.cacheableResponse.Plugin({ - statuses: [200] // opaque responses will return status code '0' - }), // for s3 secure media signed urls new workbox.expiration.Plugin({ maxAgeSeconds: 7* 24 * 60 * 60, // 7 days - maxEntries: 250, - purgeOnQuotaError: true, // safe to automatically delete if exceeding the available storage - }), - ], - }) -); - -var cdnUrls = []; - -<% if GlobalSetting.try(:cdn_cors_enabled) %> -cdnUrls = ["<%= "#{GlobalSetting.s3_cdn_url}" %>", "<%= "#{GlobalSetting.cdn_url}" %>"].filter(Boolean); - -if (cdnUrls.length > 0) { - var cdnCacheName = "cdn-" + cacheVersion; - - var appendQueryStringPlugin = { - requestWillFetch: function (args) { - var request = args.request; - - if (request.url.includes("avatar") || request.url.includes("emoji")) { - var url = new URL(request.url); - // Using this temporary query param to force browsers to redownload images from server. - url.searchParams.append('refresh', 'true'); - return new Request(url.href, request); - } - - return request; - } - }; - - workbox.routing.registerRoute( - function(args) { - var matching = cdnUrls.filter( - function(url) { - return args.url.href.startsWith(url); - } - ); - return matching.length > 0; - }, // Match all cdn resources - new workbox.strategies.NetworkFirst({ // This will only use the cache when a network request fails - cacheName: cdnCacheName, - fetchOptions: { - mode: 'cors', - credentials: 'omit' - }, - plugins: [ - new workbox.expiration.Plugin({ - maxAgeSeconds: 7* 24 * 60 * 60, // 7 days - maxEntries: 250, - purgeOnQuotaError: true, // safe to automatically delete if exceeding the available storage - }), - appendQueryStringPlugin - ], - }) - ); -} -<% end %> - -workbox.routing.registerRoute( - function(args) { - if (args.url.origin === location.origin) { - return false; - } - - var matching = cdnUrls.filter( - function(url) { - return args.url.href.startsWith(url); - } - ); - return matching.length === 0; - }, // Match all other external resources - new workbox.strategies.NetworkFirst({ // This will only use the cache when a network request fails - cacheName: externalCacheName, - plugins: [ - new workbox.cacheableResponse.Plugin({ - statuses: [200] // opaque responses will return status code '0' - }), - new workbox.expiration.Plugin({ - maxAgeSeconds: 7* 24 * 60 * 60, // 7 days - maxEntries: 250, + maxEntries: 500, purgeOnQuotaError: true, // safe to automatically delete if exceeding the available storage }), ], diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 438fc52cbd6..693970d14a4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -42,7 +42,6 @@ class ApplicationController < ActionController::Base before_action :preload_json before_action :add_noindex_header, if: -> { is_feed_request? || !SiteSetting.allow_index_in_robots_txt } before_action :check_xhr - before_action :block_cdn_requests after_action :add_readonly_header after_action :perform_refresh_session after_action :dont_cache_page @@ -673,19 +672,6 @@ class ApplicationController < ActionController::Base raise ApplicationController::RenderEmpty.new unless ((request.format && request.format.json?) || request.xhr?) end - def block_cdn_requests - raise Discourse::NotFound if Discourse.is_cdn_request?(request.env, request.method) - end - - def apply_cdn_headers - Discourse.apply_cdn_headers(response.headers) if Discourse.is_cdn_request?(request.env, request.method) - end - - def self.cdn_action(args = {}) - skip_before_action :block_cdn_requests, args - before_action :apply_cdn_headers, args - end - def self.requires_login(arg = {}) @requires_login_arg = arg end diff --git a/app/controllers/highlight_js_controller.rb b/app/controllers/highlight_js_controller.rb index 55dab4693a6..768c4e7286c 100644 --- a/app/controllers/highlight_js_controller.rb +++ b/app/controllers/highlight_js_controller.rb @@ -3,8 +3,6 @@ class HighlightJsController < ApplicationController skip_before_action :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show] - cdn_action only: [:show] - def show no_cookies diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb index 519c2652f6d..16f692569a0 100644 --- a/app/controllers/static_controller.rb +++ b/app/controllers/static_controller.rb @@ -7,8 +7,6 @@ class StaticController < ApplicationController skip_before_action :preload_json, only: [:brotli_asset, :cdn_asset, :enter, :favicon, :service_worker_asset] skip_before_action :handle_theme, only: [:brotli_asset, :cdn_asset, :enter, :favicon, :service_worker_asset] - cdn_action only: [:brotli_asset, :cdn_asset, :enter, :favicon, :service_worker_asset] - PAGES_WITH_EMAIL_PARAM = ['login', 'password_reset', 'signup'] MODAL_PAGES = ['password_reset', 'signup'] diff --git a/app/controllers/stylesheets_controller.rb b/app/controllers/stylesheets_controller.rb index a96cbec6170..163ed9e430f 100644 --- a/app/controllers/stylesheets_controller.rb +++ b/app/controllers/stylesheets_controller.rb @@ -3,8 +3,6 @@ class StylesheetsController < ApplicationController skip_before_action :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show, :show_source_map, :color_scheme] - cdn_action only: [:show, :show_source_map, :color_scheme] - def show_source_map show_resource(source_map: true) end diff --git a/app/controllers/svg_sprite_controller.rb b/app/controllers/svg_sprite_controller.rb index 7b15d837ca3..81b970547e1 100644 --- a/app/controllers/svg_sprite_controller.rb +++ b/app/controllers/svg_sprite_controller.rb @@ -3,8 +3,6 @@ class SvgSpriteController < ApplicationController skip_before_action :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show, :search, :svg_icon] - cdn_action only: [:show, :search, :svg_icon] - requires_login except: [:show, :svg_icon] def show diff --git a/app/controllers/theme_javascripts_controller.rb b/app/controllers/theme_javascripts_controller.rb index 3323a33722a..0fb5f526a5b 100644 --- a/app/controllers/theme_javascripts_controller.rb +++ b/app/controllers/theme_javascripts_controller.rb @@ -13,8 +13,6 @@ class ThemeJavascriptsController < ApplicationController before_action :is_asset_path, :no_cookies, only: [:show] - cdn_action only: [:show] - def show raise Discourse::NotFound unless last_modified.present? return render body: nil, status: 304 if not_modified? diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index 0114c1df4cc..814b65ac39d 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -10,8 +10,6 @@ class UploadsController < ApplicationController before_action :is_asset_path, only: [:show, :show_short, :show_secure] - cdn_action only: [:show, :show_short, :show_secure] - SECURE_REDIRECT_GRACE_SECONDS = 5 def create diff --git a/app/controllers/user_avatars_controller.rb b/app/controllers/user_avatars_controller.rb index 88b25289cc7..583fc81e653 100644 --- a/app/controllers/user_avatars_controller.rb +++ b/app/controllers/user_avatars_controller.rb @@ -4,8 +4,6 @@ class UserAvatarsController < ApplicationController skip_before_action :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show, :show_letter, :show_proxy_letter] - cdn_action only: [:show, :show_letter, :show_proxy_letter] - def refresh_gravatar user = User.find_by(username_lower: params[:username].downcase) guardian.ensure_can_edit!(user) diff --git a/config/initializers/008-rack-cors.rb b/config/initializers/008-rack-cors.rb index d0c3ce46dbf..e54a451657e 100644 --- a/config/initializers/008-rack-cors.rb +++ b/config/initializers/008-rack-cors.rb @@ -25,19 +25,15 @@ class Discourse::Cors status, headers, body = @app.call(env) headers ||= {} - Discourse::Cors.apply_headers(cors_origins, env, headers) + Discourse::Cors.apply_headers(cors_origins, env, headers) if cors_origins [status, headers, body] end def self.apply_headers(cors_origins, env, headers) - request_method = env['REQUEST_METHOD'] - - if env['SCRIPT_NAME'] == "/assets" && Discourse.is_cdn_request?(env, request_method) - Discourse.apply_cdn_headers(headers) - elsif cors_origins - origin = nil + origin = nil + if cors_origins if origin = env['HTTP_ORIGIN'] origin = nil unless cors_origins.include?(origin) end @@ -52,6 +48,6 @@ class Discourse::Cors end end -if GlobalSetting.enable_cors || GlobalSetting.cdn_url +if GlobalSetting.enable_cors Rails.configuration.middleware.insert_before ActionDispatch::Flash, Discourse::Cors end diff --git a/lib/discourse.rb b/lib/discourse.rb index 7ac27fe8986..3524d3d249e 100644 --- a/lib/discourse.rb +++ b/lib/discourse.rb @@ -17,7 +17,6 @@ end module Discourse DB_POST_MIGRATE_PATH ||= "db/post_migrate" - REQUESTED_HOSTNAME ||= "REQUESTED_HOSTNAME" require 'sidekiq/exception_handler' class SidekiqExceptionHandler @@ -910,24 +909,6 @@ module Discourse def self.is_parallel_test? ENV['RAILS_ENV'] == "test" && ENV['TEST_ENV_NUMBER'] end - - CDN_REQUEST_METHODS ||= ["GET", "HEAD", "OPTIONS"] - - def self.is_cdn_request?(env, request_method) - return unless CDN_REQUEST_METHODS.include?(request_method) - - cdn_hostnames = GlobalSetting.cdn_hostnames - return if cdn_hostnames.blank? - - requested_hostname = env[REQUESTED_HOSTNAME] || env[Rack::HTTP_HOST] - cdn_hostnames.include?(requested_hostname) - end - - def self.apply_cdn_headers(headers) - headers['Access-Control-Allow-Origin'] = '*' - headers['Access-Control-Allow-Methods'] = CDN_REQUEST_METHODS.join(", ") - headers - end end # rubocop:enable Style/GlobalVars diff --git a/lib/middleware/enforce_hostname.rb b/lib/middleware/enforce_hostname.rb index c462e5b7bcc..00e8870d57c 100644 --- a/lib/middleware/enforce_hostname.rb +++ b/lib/middleware/enforce_hostname.rb @@ -17,7 +17,6 @@ module Middleware allowed_hostnames = RailsMultisite::ConnectionManagement.current_db_hostnames requested_hostname = env[Rack::HTTP_HOST] - env[Discourse::REQUESTED_HOSTNAME] = requested_hostname env[Rack::HTTP_HOST] = allowed_hostnames.find { |h| h == requested_hostname } || Discourse.current_hostname @app.call(env) diff --git a/lib/tasks/javascript.rake b/lib/tasks/javascript.rake index 852bcea76a8..27ba82f8a39 100644 --- a/lib/tasks/javascript.rake +++ b/lib/tasks/javascript.rake @@ -135,10 +135,6 @@ def dependencies destination: 'workbox', public: true, skip_versioning: true - }, { - source: 'workbox-cacheable-response/build/.', - destination: 'workbox', - public: true }, { source: '@popperjs/core/dist/umd/popper.js' }, { diff --git a/package.json b/package.json index e8913cfb398..683a21d56d4 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ "pikaday": "1.8.0", "resumablejs": "1.1.0", "spectrum-colorpicker": "1.8.0", - "workbox-cacheable-response": "^4.3.1", "workbox-core": "^4.3.1", "workbox-expiration": "^4.3.1", "workbox-routing": "^4.3.1", diff --git a/public/javascripts/workbox/workbox-cacheable-response.dev.js b/public/javascripts/workbox/workbox-cacheable-response.dev.js deleted file mode 100644 index 54a2e499975..00000000000 --- a/public/javascripts/workbox/workbox-cacheable-response.dev.js +++ /dev/null @@ -1,200 +0,0 @@ -this.workbox = this.workbox || {}; -this.workbox.cacheableResponse = (function (exports, WorkboxError_mjs, assert_mjs, getFriendlyURL_mjs, logger_mjs) { - 'use strict'; - - try { - self['workbox:cacheable-response:4.3.1'] && _(); - } catch (e) {} // eslint-disable-line - - /* - Copyright 2018 Google LLC - - Use of this source code is governed by an MIT-style - license that can be found in the LICENSE file or at - https://opensource.org/licenses/MIT. - */ - /** - * This class allows you to set up rules determining what - * status codes and/or headers need to be present in order for a - * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) - * to be considered cacheable. - * - * @memberof workbox.cacheableResponse - */ - - class CacheableResponse { - /** - * To construct a new CacheableResponse instance you must provide at least - * one of the `config` properties. - * - * If both `statuses` and `headers` are specified, then both conditions must - * be met for the `Response` to be considered cacheable. - * - * @param {Object} config - * @param {Array} [config.statuses] One or more status codes that a - * `Response` can have and be considered cacheable. - * @param {Object} [config.headers] A mapping of header names - * and expected values that a `Response` can have and be considered cacheable. - * If multiple headers are provided, only one needs to be present. - */ - constructor(config = {}) { - { - if (!(config.statuses || config.headers)) { - throw new WorkboxError_mjs.WorkboxError('statuses-or-headers-required', { - moduleName: 'workbox-cacheable-response', - className: 'CacheableResponse', - funcName: 'constructor' - }); - } - - if (config.statuses) { - assert_mjs.assert.isArray(config.statuses, { - moduleName: 'workbox-cacheable-response', - className: 'CacheableResponse', - funcName: 'constructor', - paramName: 'config.statuses' - }); - } - - if (config.headers) { - assert_mjs.assert.isType(config.headers, 'object', { - moduleName: 'workbox-cacheable-response', - className: 'CacheableResponse', - funcName: 'constructor', - paramName: 'config.headers' - }); - } - } - - this._statuses = config.statuses; - this._headers = config.headers; - } - /** - * Checks a response to see whether it's cacheable or not, based on this - * object's configuration. - * - * @param {Response} response The response whose cacheability is being - * checked. - * @return {boolean} `true` if the `Response` is cacheable, and `false` - * otherwise. - */ - - - isResponseCacheable(response) { - { - assert_mjs.assert.isInstance(response, Response, { - moduleName: 'workbox-cacheable-response', - className: 'CacheableResponse', - funcName: 'isResponseCacheable', - paramName: 'response' - }); - } - - let cacheable = true; - - if (this._statuses) { - cacheable = this._statuses.includes(response.status); - } - - if (this._headers && cacheable) { - cacheable = Object.keys(this._headers).some(headerName => { - return response.headers.get(headerName) === this._headers[headerName]; - }); - } - - { - if (!cacheable) { - logger_mjs.logger.groupCollapsed(`The request for ` + `'${getFriendlyURL_mjs.getFriendlyURL(response.url)}' returned a response that does ` + `not meet the criteria for being cached.`); - logger_mjs.logger.groupCollapsed(`View cacheability criteria here.`); - logger_mjs.logger.log(`Cacheable statuses: ` + JSON.stringify(this._statuses)); - logger_mjs.logger.log(`Cacheable headers: ` + JSON.stringify(this._headers, null, 2)); - logger_mjs.logger.groupEnd(); - const logFriendlyHeaders = {}; - response.headers.forEach((value, key) => { - logFriendlyHeaders[key] = value; - }); - logger_mjs.logger.groupCollapsed(`View response status and headers here.`); - logger_mjs.logger.log(`Response status: ` + response.status); - logger_mjs.logger.log(`Response headers: ` + JSON.stringify(logFriendlyHeaders, null, 2)); - logger_mjs.logger.groupEnd(); - logger_mjs.logger.groupCollapsed(`View full response details here.`); - logger_mjs.logger.log(response.headers); - logger_mjs.logger.log(response); - logger_mjs.logger.groupEnd(); - logger_mjs.logger.groupEnd(); - } - } - - return cacheable; - } - - } - - /* - Copyright 2018 Google LLC - - Use of this source code is governed by an MIT-style - license that can be found in the LICENSE file or at - https://opensource.org/licenses/MIT. - */ - /** - * A class implementing the `cacheWillUpdate` lifecycle callback. This makes it - * easier to add in cacheability checks to requests made via Workbox's built-in - * strategies. - * - * @memberof workbox.cacheableResponse - */ - - class Plugin { - /** - * To construct a new cacheable response Plugin instance you must provide at - * least one of the `config` properties. - * - * If both `statuses` and `headers` are specified, then both conditions must - * be met for the `Response` to be considered cacheable. - * - * @param {Object} config - * @param {Array} [config.statuses] One or more status codes that a - * `Response` can have and be considered cacheable. - * @param {Object} [config.headers] A mapping of header names - * and expected values that a `Response` can have and be considered cacheable. - * If multiple headers are provided, only one needs to be present. - */ - constructor(config) { - this._cacheableResponse = new CacheableResponse(config); - } - /** - * @param {Object} options - * @param {Response} options.response - * @return {boolean} - * @private - */ - - - cacheWillUpdate({ - response - }) { - if (this._cacheableResponse.isResponseCacheable(response)) { - return response; - } - - return null; - } - - } - - /* - Copyright 2018 Google LLC - - Use of this source code is governed by an MIT-style - license that can be found in the LICENSE file or at - https://opensource.org/licenses/MIT. - */ - - exports.CacheableResponse = CacheableResponse; - exports.Plugin = Plugin; - - return exports; - -}({}, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private)); -//# sourceMappingURL=workbox-cacheable-response.dev.js.map diff --git a/public/javascripts/workbox/workbox-cacheable-response.dev.js.map b/public/javascripts/workbox/workbox-cacheable-response.dev.js.map deleted file mode 100644 index 86bc689049e..00000000000 --- a/public/javascripts/workbox/workbox-cacheable-response.dev.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"workbox-cacheable-response.dev.js","sources":["../_version.mjs","../CacheableResponse.mjs","../Plugin.mjs","../index.mjs"],"sourcesContent":["try{self['workbox:cacheable-response:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport './_version.mjs';\n\n/**\n * This class allows you to set up rules determining what\n * status codes and/or headers need to be present in order for a\n * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * to be considered cacheable.\n *\n * @memberof workbox.cacheableResponse\n */\nclass CacheableResponse {\n /**\n * To construct a new CacheableResponse instance you must provide at least\n * one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config = {}) {\n if (process.env.NODE_ENV !== 'production') {\n if (!(config.statuses || config.headers)) {\n throw new WorkboxError('statuses-or-headers-required', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n });\n }\n\n if (config.statuses) {\n assert.isArray(config.statuses, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.statuses',\n });\n }\n\n if (config.headers) {\n assert.isType(config.headers, 'object', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.headers',\n });\n }\n }\n\n this._statuses = config.statuses;\n this._headers = config.headers;\n }\n\n /**\n * Checks a response to see whether it's cacheable or not, based on this\n * object's configuration.\n *\n * @param {Response} response The response whose cacheability is being\n * checked.\n * @return {boolean} `true` if the `Response` is cacheable, and `false`\n * otherwise.\n */\n isResponseCacheable(response) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(response, Response, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'isResponseCacheable',\n paramName: 'response',\n });\n }\n\n let cacheable = true;\n\n if (this._statuses) {\n cacheable = this._statuses.includes(response.status);\n }\n\n if (this._headers && cacheable) {\n cacheable = Object.keys(this._headers).some((headerName) => {\n return response.headers.get(headerName) === this._headers[headerName];\n });\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (!cacheable) {\n logger.groupCollapsed(`The request for ` +\n `'${getFriendlyURL(response.url)}' returned a response that does ` +\n `not meet the criteria for being cached.`);\n\n logger.groupCollapsed(`View cacheability criteria here.`);\n logger.log(`Cacheable statuses: ` +\n JSON.stringify(this._statuses));\n logger.log(`Cacheable headers: ` +\n JSON.stringify(this._headers, null, 2));\n logger.groupEnd();\n\n const logFriendlyHeaders = {};\n response.headers.forEach((value, key) => {\n logFriendlyHeaders[key] = value;\n });\n\n logger.groupCollapsed(`View response status and headers here.`);\n logger.log(`Response status: ` + response.status);\n logger.log(`Response headers: ` +\n JSON.stringify(logFriendlyHeaders, null, 2));\n logger.groupEnd();\n\n logger.groupCollapsed(`View full response details here.`);\n logger.log(response.headers);\n logger.log(response);\n logger.groupEnd();\n\n logger.groupEnd();\n }\n }\n\n return cacheable;\n }\n}\n\nexport {CacheableResponse};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport {CacheableResponse} from './CacheableResponse.mjs';\nimport './_version.mjs';\n\n/**\n * A class implementing the `cacheWillUpdate` lifecycle callback. This makes it\n * easier to add in cacheability checks to requests made via Workbox's built-in\n * strategies.\n *\n * @memberof workbox.cacheableResponse\n */\nclass Plugin {\n /**\n * To construct a new cacheable response Plugin instance you must provide at\n * least one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config) {\n this._cacheableResponse = new CacheableResponse(config);\n }\n\n /**\n * @param {Object} options\n * @param {Response} options.response\n * @return {boolean}\n * @private\n */\n cacheWillUpdate({response}) {\n if (this._cacheableResponse.isResponseCacheable(response)) {\n return response;\n }\n return null;\n }\n}\n\nexport {Plugin};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport {CacheableResponse} from './CacheableResponse.mjs';\nimport {Plugin} from './Plugin.mjs';\nimport './_version.mjs';\n\n\n/**\n * @namespace workbox.cacheableResponse\n */\n\nexport {\n CacheableResponse,\n Plugin,\n};\n"],"names":["self","_","e","CacheableResponse","constructor","config","statuses","headers","WorkboxError","moduleName","className","funcName","assert","isArray","paramName","isType","_statuses","_headers","isResponseCacheable","response","isInstance","Response","cacheable","includes","status","Object","keys","some","headerName","get","logger","groupCollapsed","getFriendlyURL","url","log","JSON","stringify","groupEnd","logFriendlyHeaders","forEach","value","key","Plugin","_cacheableResponse","cacheWillUpdate"],"mappings":"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"} \ No newline at end of file diff --git a/public/javascripts/workbox/workbox-cacheable-response.prod.js b/public/javascripts/workbox/workbox-cacheable-response.prod.js deleted file mode 100644 index a7e42f263a8..00000000000 --- a/public/javascripts/workbox/workbox-cacheable-response.prod.js +++ /dev/null @@ -1,2 +0,0 @@ -this.workbox=this.workbox||{},this.workbox.cacheableResponse=function(t){"use strict";try{self["workbox:cacheable-response:4.3.1"]&&_()}catch(t){}class s{constructor(t={}){this.t=t.statuses,this.s=t.headers}isResponseCacheable(t){let s=!0;return this.t&&(s=this.t.includes(t.status)),this.s&&s&&(s=Object.keys(this.s).some(s=>t.headers.get(s)===this.s[s])),s}}return t.CacheableResponse=s,t.Plugin=class{constructor(t){this.i=new s(t)}cacheWillUpdate({response:t}){return this.i.isResponseCacheable(t)?t:null}},t}({}); -//# sourceMappingURL=workbox-cacheable-response.prod.js.map diff --git a/public/javascripts/workbox/workbox-cacheable-response.prod.js.map b/public/javascripts/workbox/workbox-cacheable-response.prod.js.map deleted file mode 100644 index b1a0d1d2b79..00000000000 --- a/public/javascripts/workbox/workbox-cacheable-response.prod.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"workbox-cacheable-response.prod.js","sources":["../_version.mjs","../CacheableResponse.mjs","../Plugin.mjs"],"sourcesContent":["try{self['workbox:cacheable-response:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport './_version.mjs';\n\n/**\n * This class allows you to set up rules determining what\n * status codes and/or headers need to be present in order for a\n * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * to be considered cacheable.\n *\n * @memberof workbox.cacheableResponse\n */\nclass CacheableResponse {\n /**\n * To construct a new CacheableResponse instance you must provide at least\n * one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config = {}) {\n if (process.env.NODE_ENV !== 'production') {\n if (!(config.statuses || config.headers)) {\n throw new WorkboxError('statuses-or-headers-required', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n });\n }\n\n if (config.statuses) {\n assert.isArray(config.statuses, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.statuses',\n });\n }\n\n if (config.headers) {\n assert.isType(config.headers, 'object', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.headers',\n });\n }\n }\n\n this._statuses = config.statuses;\n this._headers = config.headers;\n }\n\n /**\n * Checks a response to see whether it's cacheable or not, based on this\n * object's configuration.\n *\n * @param {Response} response The response whose cacheability is being\n * checked.\n * @return {boolean} `true` if the `Response` is cacheable, and `false`\n * otherwise.\n */\n isResponseCacheable(response) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(response, Response, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'isResponseCacheable',\n paramName: 'response',\n });\n }\n\n let cacheable = true;\n\n if (this._statuses) {\n cacheable = this._statuses.includes(response.status);\n }\n\n if (this._headers && cacheable) {\n cacheable = Object.keys(this._headers).some((headerName) => {\n return response.headers.get(headerName) === this._headers[headerName];\n });\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (!cacheable) {\n logger.groupCollapsed(`The request for ` +\n `'${getFriendlyURL(response.url)}' returned a response that does ` +\n `not meet the criteria for being cached.`);\n\n logger.groupCollapsed(`View cacheability criteria here.`);\n logger.log(`Cacheable statuses: ` +\n JSON.stringify(this._statuses));\n logger.log(`Cacheable headers: ` +\n JSON.stringify(this._headers, null, 2));\n logger.groupEnd();\n\n const logFriendlyHeaders = {};\n response.headers.forEach((value, key) => {\n logFriendlyHeaders[key] = value;\n });\n\n logger.groupCollapsed(`View response status and headers here.`);\n logger.log(`Response status: ` + response.status);\n logger.log(`Response headers: ` +\n JSON.stringify(logFriendlyHeaders, null, 2));\n logger.groupEnd();\n\n logger.groupCollapsed(`View full response details here.`);\n logger.log(response.headers);\n logger.log(response);\n logger.groupEnd();\n\n logger.groupEnd();\n }\n }\n\n return cacheable;\n }\n}\n\nexport {CacheableResponse};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport {CacheableResponse} from './CacheableResponse.mjs';\nimport './_version.mjs';\n\n/**\n * A class implementing the `cacheWillUpdate` lifecycle callback. This makes it\n * easier to add in cacheability checks to requests made via Workbox's built-in\n * strategies.\n *\n * @memberof workbox.cacheableResponse\n */\nclass Plugin {\n /**\n * To construct a new cacheable response Plugin instance you must provide at\n * least one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config) {\n this._cacheableResponse = new CacheableResponse(config);\n }\n\n /**\n * @param {Object} options\n * @param {Response} options.response\n * @return {boolean}\n * @private\n */\n cacheWillUpdate({response}) {\n if (this._cacheableResponse.isResponseCacheable(response)) {\n return response;\n }\n return null;\n }\n}\n\nexport {Plugin};\n"],"names":["self","_","e","CacheableResponse","constructor","config","_statuses","statuses","_headers","headers","isResponseCacheable","response","cacheable","this","includes","status","Object","keys","some","headerName","get","_cacheableResponse","cacheWillUpdate"],"mappings":"sFAAA,IAAIA,KAAK,qCAAqCC,IAAI,MAAMC,ICsBxD,MAAMC,EAeJC,YAAYC,EAAS,SA6BdC,EAAYD,EAAOE,cACnBC,EAAWH,EAAOI,QAYzBC,oBAAoBC,OAUdC,GAAY,SAEZC,KAAKP,IACPM,EAAYC,KAAKP,EAAUQ,SAASH,EAASI,SAG3CF,KAAKL,GAAYI,IACnBA,EAAYI,OAAOC,KAAKJ,KAAKL,GAAUU,KAAMC,GACpCR,EAASF,QAAQW,IAAID,KAAgBN,KAAKL,EAASW,KAqCvDP,yCCpHX,MAeER,YAAYC,QACLgB,EAAqB,IAAIlB,EAAkBE,GASlDiB,iBAAgBX,SAACA,WACXE,KAAKQ,EAAmBX,oBAAoBC,GACvCA,EAEF"} \ No newline at end of file diff --git a/spec/requests/application_controller_spec.rb b/spec/requests/application_controller_spec.rb index 6edb228732c..7808d23de2c 100644 --- a/spec/requests/application_controller_spec.rb +++ b/spec/requests/application_controller_spec.rb @@ -737,17 +737,6 @@ RSpec.describe ApplicationController do end end - context "cdn requests" do - before do - GlobalSetting.stubs(:cdn_url).returns("https://www.example.com/") - end - - it "should block the dynamic routes" do - get "/" - expect(response.status).to eq(404) - end - end - context "set_locale_from_accept_language_header enabled" do context "accept-language header differs from default locale" do before do diff --git a/spec/requests/static_controller_spec.rb b/spec/requests/static_controller_spec.rb index 3156b2a7ab1..967185f567c 100644 --- a/spec/requests/static_controller_spec.rb +++ b/spec/requests/static_controller_spec.rb @@ -116,25 +116,6 @@ describe StaticController do File.delete(file_path) end end - - it 'has correct cors headers for brotli assets' do - begin - assets_path = Rails.root.join("public/assets") - - FileUtils.mkdir_p(assets_path) - - file_path = assets_path.join("test.js.br") - File.write(file_path, 'fake brotli file') - GlobalSetting.stubs(:cdn_url).returns("https://www.example.com/") - - get "/brotli_asset/test.js" - - expect(response.status).to eq(200) - expect(response.headers["Access-Control-Allow-Origin"]).to match("*") - ensure - File.delete(file_path) - end - end end context '#cdn_asset' do diff --git a/yarn.lock b/yarn.lock index c22acbfd93e..d02e9bf4ee8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3078,13 +3078,6 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= -workbox-cacheable-response@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz#f53e079179c095a3f19e5313b284975c91428c91" - integrity sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw== - dependencies: - workbox-core "^4.3.1" - workbox-core@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-4.3.1.tgz#005d2c6a06a171437afd6ca2904a5727ecd73be6"