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.
354 355 356 |
# File 'lib/middleware/anonymous_cache.rb', line 354 def initialize(app, settings = {}) @app = app end |
Class Method Details
.anon_cache(env, duration) ⇒ Object
43 44 45 |
# File 'lib/middleware/anonymous_cache.rb', line 43 def self.anon_cache(env, duration) env["ANON_CACHE_DURATION"] = duration end |
.build_cache_key(helper) ⇒ Object
38 39 40 41 |
# File 'lib/middleware/anonymous_cache.rb', line 38 def self.build_cache_key(helper) compile_key_builder unless defined?(@@compiled) __compiled_key_builder(helper) end |
.cache_key_segments ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/middleware/anonymous_cache.rb', line 11 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
47 48 49 50 51 52 |
# File 'lib/middleware/anonymous_cache.rb', line 47 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
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/middleware/anonymous_cache.rb', line 26 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
54 55 56 |
# File 'lib/middleware/anonymous_cache.rb', line 54 def self.disable_anon_cache @@disabled = true end |
.enable_anon_cache ⇒ Object
58 59 60 |
# File 'lib/middleware/anonymous_cache.rb', line 58 def self.enable_anon_cache @@disabled = false end |
Instance Method Details
#call(env) ⇒ Object
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 396 397 398 399 400 401 402 403 404 405 406 407 408 409 |
# File 'lib/middleware/anonymous_cache.rb', line 360 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 |