FIX: Include resolved locale in anonymous cache key (#10289)
This only applies when set_locale_from_accept_language_header is enabled
This commit is contained in:
parent
bcb0e62363
commit
c09b5807f3
|
@ -530,17 +530,7 @@ class ApplicationController < ActionController::Base
|
||||||
private
|
private
|
||||||
|
|
||||||
def locale_from_header
|
def locale_from_header
|
||||||
begin
|
HttpLanguageParser.parse(request.env["HTTP_ACCEPT_LANGUAGE"])
|
||||||
# Rails I18n uses underscores between the locale and the region; the request
|
|
||||||
# headers use hyphens.
|
|
||||||
require 'http_accept_language' unless defined? HttpAcceptLanguage
|
|
||||||
available_locales = I18n.available_locales.map { |locale| locale.to_s.tr('_', '-') }
|
|
||||||
parser = HttpAcceptLanguage::Parser.new(request.env["HTTP_ACCEPT_LANGUAGE"])
|
|
||||||
parser.language_region_compatible_from(available_locales).tr('-', '_')
|
|
||||||
rescue
|
|
||||||
# If Accept-Language headers are not set.
|
|
||||||
I18n.default_locale
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def preload_anonymous_data
|
def preload_anonymous_data
|
||||||
|
|
|
@ -1425,7 +1425,7 @@ en:
|
||||||
delete_old_hidden_posts: "Auto-delete any hidden posts that stay hidden for more than 30 days."
|
delete_old_hidden_posts: "Auto-delete any hidden posts that stay hidden for more than 30 days."
|
||||||
default_locale: "The default language of this Discourse instance. You can replace the text of system generated categories and topics at <a href='%{base_path}/admin/customize/site_texts' target='_blank'>Customize / Text</a>."
|
default_locale: "The default language of this Discourse instance. You can replace the text of system generated categories and topics at <a href='%{base_path}/admin/customize/site_texts' target='_blank'>Customize / Text</a>."
|
||||||
allow_user_locale: "Allow users to choose their own language interface preference"
|
allow_user_locale: "Allow users to choose their own language interface preference"
|
||||||
set_locale_from_accept_language_header: "set interface language for anonymous users from their web browser's language headers. (EXPERIMENTAL, does not work with anonymous cache)"
|
set_locale_from_accept_language_header: "set interface language for anonymous users from their web browser's language headers"
|
||||||
support_mixed_text_direction: "Support mixed left-to-right and right-to-left text directions."
|
support_mixed_text_direction: "Support mixed left-to-right and right-to-left text directions."
|
||||||
min_post_length: "Minimum allowed post length in characters"
|
min_post_length: "Minimum allowed post length in characters"
|
||||||
min_first_post_length: "Minimum allowed first post (topic body) length in characters"
|
min_first_post_length: "Minimum allowed first post (topic body) length in characters"
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module HttpLanguageParser
|
||||||
|
def self.parse(header)
|
||||||
|
# Rails I18n uses underscores between the locale and the region; the request
|
||||||
|
# headers use hyphens.
|
||||||
|
require 'http_accept_language' unless defined? HttpAcceptLanguage
|
||||||
|
available_locales = I18n.available_locales.map { |locale| locale.to_s.tr('_', '-') }
|
||||||
|
parser = HttpAcceptLanguage::Parser.new(header)
|
||||||
|
matched = parser.language_region_compatible_from(available_locales)&.tr('-', '_')
|
||||||
|
matched || SiteSetting.default_locale
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,6 +3,7 @@
|
||||||
require_dependency "mobile_detection"
|
require_dependency "mobile_detection"
|
||||||
require_dependency "crawler_detection"
|
require_dependency "crawler_detection"
|
||||||
require_dependency "guardian"
|
require_dependency "guardian"
|
||||||
|
require_dependency "http_language_parser"
|
||||||
|
|
||||||
module Middleware
|
module Middleware
|
||||||
class AnonymousCache
|
class AnonymousCache
|
||||||
|
@ -13,7 +14,8 @@ module Middleware
|
||||||
c: 'key_is_crawler?',
|
c: 'key_is_crawler?',
|
||||||
b: 'key_has_brotli?',
|
b: 'key_has_brotli?',
|
||||||
t: 'key_cache_theme_ids',
|
t: 'key_cache_theme_ids',
|
||||||
ca: 'key_compress_anon'
|
ca: 'key_compress_anon',
|
||||||
|
l: 'key_locale'
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -89,6 +91,14 @@ module Middleware
|
||||||
@has_brotli == :true
|
@has_brotli == :true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def key_locale
|
||||||
|
if SiteSetting.set_locale_from_accept_language_header
|
||||||
|
HttpLanguageParser.parse(@env["HTTP_ACCEPT_LANGUAGE"])
|
||||||
|
else
|
||||||
|
"" # No need to key, it is the same for all anon users
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def is_crawler?
|
def is_crawler?
|
||||||
@is_crawler ||=
|
@is_crawler ||=
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -46,6 +46,32 @@ describe Middleware::AnonymousCache::Helper do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with header-based locale locale" do
|
||||||
|
it "handles different languages" do
|
||||||
|
# Normally does not check the language header
|
||||||
|
french1 = new_helper("HTTP_ACCEPT_LANGUAGE" => "fr").cache_key
|
||||||
|
french2 = new_helper("HTTP_ACCEPT_LANGUAGE" => "FR").cache_key
|
||||||
|
english = new_helper("HTTP_ACCEPT_LANGUAGE" => SiteSetting.default_locale).cache_key
|
||||||
|
none = new_helper.cache_key
|
||||||
|
|
||||||
|
expect(none).to eq(french1)
|
||||||
|
expect(none).to eq(french2)
|
||||||
|
expect(none).to eq(english)
|
||||||
|
|
||||||
|
SiteSetting.allow_user_locale = true
|
||||||
|
SiteSetting.set_locale_from_accept_language_header = true
|
||||||
|
|
||||||
|
french1 = new_helper("HTTP_ACCEPT_LANGUAGE" => "fr").cache_key
|
||||||
|
french2 = new_helper("HTTP_ACCEPT_LANGUAGE" => "FR").cache_key
|
||||||
|
english = new_helper("HTTP_ACCEPT_LANGUAGE" => SiteSetting.default_locale).cache_key
|
||||||
|
none = new_helper.cache_key
|
||||||
|
|
||||||
|
expect(none).to eq(english)
|
||||||
|
expect(french1).to eq(french2)
|
||||||
|
expect(french1).not_to eq(none)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'force_anonymous!' do
|
context 'force_anonymous!' do
|
||||||
before do
|
before do
|
||||||
RateLimiter.enable
|
RateLimiter.enable
|
||||||
|
|
Loading…
Reference in New Issue