Class: Middleware::AnonymousCache
- Inherits:
-
Object
- Object
- Middleware::AnonymousCache
- Defined in:
- lib/middleware/anonymous_cache.rb
Defined Under Namespace
Classes: Helper
Constant Summary collapse
- PAYLOAD_INVALID_REQUEST_METHODS =
%w[GET HEAD]
Class Method Summary collapse
- .anon_cache(env, duration) ⇒ Object
- .build_cache_key(helper) ⇒ Object
- .cache_key_segments ⇒ Object
- .clear_all_cache! ⇒ Object
-
.compile_key_builder ⇒ Object
Compile a string builder method that will be called to create an anonymous cache key.
- .disable_anon_cache ⇒ Object
- .enable_anon_cache ⇒ Object
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app, settings = {}) ⇒ AnonymousCache
constructor
A new instance of AnonymousCache.
Constructor Details
#initialize(app, settings = {}) ⇒ AnonymousCache
Returns a new instance of AnonymousCache.
340 341 342 |
# File 'lib/middleware/anonymous_cache.rb', line 340 def initialize(app, settings = {}) @app = app end |
Class Method Details
.anon_cache(env, duration) ⇒ Object
42 43 44 |
# File 'lib/middleware/anonymous_cache.rb', line 42 def self.anon_cache(env, duration) env["ANON_CACHE_DURATION"] = duration end |
.build_cache_key(helper) ⇒ Object
37 38 39 40 |
# File 'lib/middleware/anonymous_cache.rb', line 37 def self.build_cache_key(helper) compile_key_builder unless defined?(@@compiled) __compiled_key_builder(helper) end |
.cache_key_segments ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/middleware/anonymous_cache.rb', line 10 def self.cache_key_segments @@cache_key_segments ||= { m: "key_is_mobile?", c: "key_is_crawler?", o: "key_is_old_browser?", d: "key_is_modern_mobile_device?", b: "key_has_brotli?", t: "key_cache_theme_ids", ca: "key_compress_anon", l: "key_locale", } end |
.clear_all_cache! ⇒ Object
46 47 48 49 50 51 |
# File 'lib/middleware/anonymous_cache.rb', line 46 def self.clear_all_cache! if Rails.env.production? raise "for perf reasons, clear_all_cache! cannot be used in production." end Discourse.redis.keys("ANON_CACHE_*").each { |k| Discourse.redis.del(k) } end |
.compile_key_builder ⇒ Object
Compile a string builder method that will be called to create an anonymous cache key
25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/middleware/anonymous_cache.rb', line 25 def self.compile_key_builder method = +"def self.__compiled_key_builder(h)\n \"" cache_key_segments.each do |k, v| raise "Invalid key name" unless k =~ /\A[a-z]+\z/ raise "Invalid method name" unless v =~ /\Akey_[a-z_\?]+\z/ method << "|#{k}=#\{h.#{v}}" end method << "\"\nend" eval(method) # rubocop:disable Security/Eval @@compiled = true end |
.disable_anon_cache ⇒ Object
53 54 55 |
# File 'lib/middleware/anonymous_cache.rb', line 53 def self.disable_anon_cache @@disabled = true end |
.enable_anon_cache ⇒ Object
57 58 59 |
# File 'lib/middleware/anonymous_cache.rb', line 57 def self.enable_anon_cache @@disabled = false end |
Instance Method Details
#call(env) ⇒ Object
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 |
# File 'lib/middleware/anonymous_cache.rb', line 346 def call(env) return @app.call(env) if defined?(@@disabled) && @@disabled if PAYLOAD_INVALID_REQUEST_METHODS.include?(env[Rack::REQUEST_METHOD]) && env[Rack::RACK_INPUT].size > 0 return 413, { "Cache-Control" => "private, max-age=0, must-revalidate" }, [] end helper = Helper.new(env) force_anon = false if helper.blocked_crawler? env["discourse.request_tracker.skip"] = true return 403, {}, ["Crawler is not allowed!"] end if helper.should_force_anonymous? force_anon = env["DISCOURSE_FORCE_ANON"] = true helper.force_anonymous! end if (env["HTTP_DISCOURSE_BACKGROUND"] == "true") && (queue_time = env["REQUEST_QUEUE_SECONDS"]) max_time = GlobalSetting.background_requests_max_queue_length.to_f if max_time > 0 && queue_time.to_f > max_time return [ 429, { "content-type" => "application/json; charset=utf-8" }, [ { errors: I18n.t("rate_limiter.slow_down"), extras: { wait_seconds: 5 + (5 * rand).round(2), }, }.to_json, ] ] end end result = if helper.cacheable? helper.cached(env) || helper.cache(@app.call(env), env) else @app.call(env) end result[1]["Set-Cookie"] = "dosp=1; Path=/" if force_anon result end |