22
33require 'omniauth'
44require 'request_store'
5- require 'i18n'
65
76require 'cdo/global_edition'
8- require 'cdo/i18n'
97require 'dynamic_config/dcdo'
8+ require 'helpers/cookies'
109
1110module Middleware
1211 class GlobalEdition
@@ -15,12 +14,13 @@ def initialize(app)
1514 end
1615
1716 def call ( env )
18- RequestGlobalizer . new ( @app , env ) . call
17+ RouteHandler . new ( @app , env ) . call
1918 end
2019
21- class RequestGlobalizer
20+ class RouteHandler
21+ include Middleware ::Helpers ::Cookies
22+
2223 REGION_KEY = Cdo ::GlobalEdition ::REGION_KEY
23- LOCALE_KEY = Cdo ::I18n ::LOCALE_COOKIE_KEY
2424
2525 # HTTP paths that to be excluded from Global Edition scope.
2626 EXCLUDED_PATHS = [
@@ -45,7 +45,7 @@ def initialize(app, env)
4545 @original_path_info = @request . path_info
4646 @original_path = @request . path
4747 @original_region = @request . cookies [ REGION_KEY ] . presence
48- @original_locale = :: I18n . locale . to_s
48+ @original_locale = @request . locale
4949 end
5050
5151 # Processes the current request within the Global Edition routing context.
@@ -81,14 +81,14 @@ def call
8181 return app . call ( env ) unless Cdo ::GlobalEdition . target_host? ( request . hostname )
8282
8383 # Allows setting the GE region via the URL parameter `?ge_region=<region_code>`.
84- if request . GET . key? ( REGION_KEY )
85- new_region = request . GET [ REGION_KEY ] . presence
84+ if request . params . key? ( REGION_KEY )
85+ new_region = request . params [ REGION_KEY ] . presence
8686
8787 redirect_path = ::File . join ( '/' , main_path )
8888 redirect_path = regional_path_for ( new_region , redirect_path ) if Cdo ::GlobalEdition . region_available? ( new_region )
8989
9090 redirect_uri = URI ( redirect_path )
91- redirect_uri . query = URI . encode_www_form ( request . GET . except ( REGION_KEY ) ) . presence
91+ redirect_uri . query = URI . encode_www_form ( request . params . except ( REGION_KEY ) ) . presence
9292 redirect_path = redirect_uri . to_s
9393
9494 setup_region ( new_region )
@@ -122,9 +122,10 @@ def call
122122 response . finish
123123 ensure
124124 Cdo ::GlobalEdition . current_region = nil
125- # GE may rewrite Rack routing state (`script_name`, `path_info`) to route `/<region>/...` as root paths.
126- # Rack computes `request.path` from both fields (`script_name + path_info`), so we must restore both values.
127- # If only one side is reverted, upstream middleware can observe an invalid path (for example, a duplicated GE prefix).
125+ # Restore the original `script_name` and `path_info` so that upstream middlewares
126+ # (e.g., VarnishEnvironment's after filter) see a consistent `request.path`.
127+ # Without this, downstream processing may partially restore `path_info` while
128+ # leaving `script_name` modified, causing a doubled GE prefix in `request.path`.
128129 request . script_name = original_script_name
129130 request . path_info = original_path_info
130131 end
@@ -187,23 +188,19 @@ def call
187188 end
188189
189190 private def setup_region ( new_region )
191+ return if new_region == original_region
192+
190193 # Resets the region if it's `nil` or sets it only if it's available.
191194 return unless new_region . nil? || Cdo ::GlobalEdition . region_available? ( new_region )
192195
193- Cdo ::GlobalEdition . current_region = new_region
194- return if new_region == original_region
196+ # Sets the request cookies to apply changes immediately without needing to reload the page.
197+ request . cookies [ REGION_KEY ] = Cdo ::GlobalEdition . current_region = new_region
198+ request . cookies [ LOCALE_KEY ] = request . locale = new_locale = resolve_locale_for ( new_region )
195199
196200 # Updates the global `ge_region` cookie to lock the platform to the regional version.
197- request . cookies [ REGION_KEY ] = new_region
198- response . set_cdo_cookie ( REGION_KEY , new_region , priority : :high )
199-
200- region_locale = resolve_locale_for ( new_region )
201- unless region_locale == original_locale
202- # Updates the global `language` cookie to enforce the switch to the regional language.
203- ::I18n . locale = region_locale
204- request . cookies [ LOCALE_KEY ] = region_locale
205- response . set_cdo_cookie ( LOCALE_KEY , region_locale )
206- end
201+ set_global_cookie ( REGION_KEY , new_region , high_priority : true )
202+ # Updates the global `language` cookie to enforce the switch to the regional language.
203+ set_locale_cookie ( new_locale )
207204
208205 Metrics ::Events . log_event (
209206 event_name : 'Global Edition Region Changed' ,
@@ -213,9 +210,11 @@ def call
213210 old_region : original_region ,
214211 old_locale : original_locale ,
215212 new_region :,
216- new_locale : region_locale ,
213+ new_locale :,
217214 } ,
218215 )
216+ ensure
217+ Cdo ::GlobalEdition . current_region = request . cookies [ REGION_KEY ] . presence
219218 end
220219
221220 private def existing_route? ( path = original_path_info )
@@ -232,12 +231,18 @@ def call
232231 # @return [String, nil] The resolved locale for the region,
233232 # or `nil` if no locale should be preserved during a region reset.
234233 private def resolve_locale_for ( region )
235- return original_locale unless region
234+ resolved_locale = original_locale
236235
237- return original_locale if Cdo ::GlobalEdition . locale_available? ( region , original_locale )
238- return url_locale if Cdo ::GlobalEdition . locale_available? ( region , url_locale )
236+ if Cdo ::GlobalEdition . region_available? ( region )
237+ unless Cdo ::GlobalEdition . locale_available? ( region , resolved_locale )
238+ resolved_locale = url_locale || Cdo ::GlobalEdition . main_region_locale ( region )
239+ end
240+ else
241+ # Locales locked to a specific region should not be set during a region reset.
242+ resolved_locale = nil if Cdo ::GlobalEdition . locales_regions [ resolved_locale ] . present?
243+ end
239244
240- Cdo :: GlobalEdition . main_region_locale ( region )
245+ resolved_locale
241246 end
242247
243248 private def excluded_path? ( path )
@@ -319,6 +324,6 @@ def call
319324 end
320325 end
321326
322- private_constant :RequestGlobalizer
327+ private_constant :RouteHandler
323328 end
324329end
0 commit comments