wovnrb 3.8.0 → 3.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,181 +1,192 @@
1
- module Wovnrb
2
- class Headers
3
- attr_reader :unmasked_url, :url, :protocol, :unmasked_host, :host, :unmasked_pathname, :pathname, :pathname_with_trailing_slash_if_present
4
-
5
- # Generates new instance of Wovnrb::Headers.
6
- # Its parameters are set by parsing env variable.
7
-
8
- def initialize(env, settings, url_lang_switcher)
9
- request = Rack::Request.new(env)
10
- @url_lang_switcher = url_lang_switcher
11
- @env = env
12
- @settings = settings
13
- @protocol = request.scheme
14
- @unmasked_host = if settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
15
- @env['HTTP_X_FORWARDED_HOST']
16
- else
17
- @env['HTTP_HOST']
18
- end
19
- unless @env.key?('REQUEST_URI')
20
- # Add '/' to PATH_INFO as a possible fix for pow server
21
- @env['REQUEST_URI'] = (/^[^\/]/.match?(@env['PATH_INFO']) ? '/' : '') + @env['PATH_INFO'] + (@env['QUERY_STRING'].empty? ? '' : "?#{@env['QUERY_STRING']}")
22
- end
23
- # REQUEST_URI is expected to not contain the server name
24
- # heroku contains http://...
25
- @env['REQUEST_URI'] = @env['REQUEST_URI'].sub(/^https?:\/\/[^\/]+/, '') if /^https?:\/\//.match?(@env['REQUEST_URI'])
26
- @unmasked_pathname = @env['REQUEST_URI'].split('?')[0]
27
- @unmasked_pathname += '/' unless @unmasked_pathname =~ /\/$/ || @unmasked_pathname =~ /\/[^\/.]+\.[^\/.]+$/
28
- @unmasked_url = "#{@protocol}://#{@unmasked_host}#{@unmasked_pathname}"
29
- @host = if settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
30
- @env['HTTP_X_FORWARDED_HOST']
31
- else
32
- @env['HTTP_HOST']
33
- end
34
- @host = settings['url_pattern'] == 'subdomain' ? @url_lang_switcher.remove_lang_from_uri_component(@host, lang_code) : @host
35
- @pathname, @query = @env['REQUEST_URI'].split('?')
36
- @pathname = settings['url_pattern'] == 'path' ? @url_lang_switcher.remove_lang_from_uri_component(@pathname, lang_code) : @pathname
37
- @query ||= ''
38
- @url = "#{@host}#{@pathname}#{(@query.empty? ? '' : '?') + @url_lang_switcher.remove_lang_from_uri_component(@query, lang_code)}"
39
- if settings['query'].empty?
40
- @query = ''
41
- else
42
- query_vals = []
43
- settings['query'].each do |qv|
44
- rx = Regexp.new("(^|&)(?<query_val>#{qv}[^&]+)(&|$)")
45
- m = @query.match(rx)
46
- query_vals.push(m[:query_val]) if m && m[:query_val]
47
- end
48
- @query = if query_vals.empty?
49
- ''
50
- else
51
- "?#{query_vals.sort.join('&')}"
52
- end
53
- end
54
- @query = @url_lang_switcher.remove_lang_from_uri_component(@query, lang_code)
55
- @pathname_with_trailing_slash_if_present = @pathname
56
- @pathname = @pathname.gsub(/\/$/, '')
57
- end
58
-
59
- def url_with_scheme
60
- "#{@protocol}://#{@url}"
61
- end
62
-
63
- def unmasked_pathname_without_trailing_slash
64
- @unmasked_pathname.chomp('/')
65
- end
66
-
67
- # Get the language code of the current request
68
- #
69
- # @return [String] The lang code of the current page
70
- def lang_code
71
- path_lang && !path_lang.empty? ? path_lang : @settings['default_lang']
72
- end
73
-
74
- # picks up language code from requested URL by using url_pattern_reg setting.
75
- # when language code is invalid, this method returns empty string.
76
- # if you want examples, please see test/lib/headers_test.rb.
77
- #
78
- # @return [String] language code in requrested URL.
79
- def path_lang
80
- if @path_lang.nil?
81
- rp = Regexp.new(@settings['url_pattern_reg'])
82
- match = if @settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
83
- "#{@env['HTTP_X_FORWARDED_HOST']}#{@env['REQUEST_URI']}".match(rp)
84
- else
85
- "#{@env['SERVER_NAME']}#{@env['REQUEST_URI']}".match(rp)
86
- end
87
- @path_lang = if match && match[:lang] && Lang.get_lang(match[:lang])
88
- Lang.get_code(match[:lang])
89
- else
90
- ''
91
- end
92
- end
93
- @path_lang
94
- end
95
-
96
- def redirect(lang)
97
- redirect_headers = {}
98
- redirect_headers['location'] = redirect_location(lang)
99
- redirect_headers['content-length'] = '0'
100
- redirect_headers
101
- end
102
-
103
- def redirect_location(lang)
104
- if lang == @settings['default_lang']
105
- # IS THIS RIGHT??
106
- return url_with_scheme
107
- end
108
-
109
- @url_lang_switcher.add_lang_code(url_with_scheme, lang, self)
110
- end
111
-
112
- def request_out(_def_lang = @settings['default_lang'])
113
- @env['wovnrb.target_lang'] = lang_code
114
- case @settings['url_pattern']
115
- when 'query'
116
- @env['REQUEST_URI'] = @url_lang_switcher.remove_lang_from_uri_component(@env['REQUEST_URI'], lang_code) if @env.key?('REQUEST_URI')
117
- @env['QUERY_STRING'] = @url_lang_switcher.remove_lang_from_uri_component(@env['QUERY_STRING'], lang_code) if @env.key?('QUERY_STRING')
118
- @env['ORIGINAL_FULLPATH'] = @url_lang_switcher.remove_lang_from_uri_component(@env['ORIGINAL_FULLPATH'], lang_code) if @env.key?('ORIGINAL_FULLPATH')
119
- when 'subdomain'
120
- if @settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
121
- @env['HTTP_X_FORWARDED_HOST'] = @url_lang_switcher.remove_lang_from_uri_component(@env['HTTP_X_FORWARDED_HOST'], lang_code)
122
- else
123
- @env['HTTP_HOST'] = @url_lang_switcher.remove_lang_from_uri_component(@env['HTTP_HOST'], lang_code)
124
- @env['SERVER_NAME'] = @url_lang_switcher.remove_lang_from_uri_component(@env['SERVER_NAME'], lang_code)
125
- end
126
- @env['HTTP_REFERER'] = @url_lang_switcher.remove_lang_from_uri_component(@env['HTTP_REFERER'], lang_code) if @env.key?('HTTP_REFERER')
127
- # when 'path'
128
- else
129
- @env['REQUEST_URI'] = @url_lang_switcher.remove_lang_from_uri_component(@env['REQUEST_URI'], lang_code)
130
- @env['REQUEST_PATH'] = @url_lang_switcher.remove_lang_from_uri_component(@env['REQUEST_PATH'], lang_code) if @env.key?('REQUEST_PATH')
131
- @env['PATH_INFO'] = @url_lang_switcher.remove_lang_from_uri_component(@env['PATH_INFO'], lang_code)
132
- @env['ORIGINAL_FULLPATH'] = @url_lang_switcher.remove_lang_from_uri_component(@env['ORIGINAL_FULLPATH'], lang_code) if @env.key?('ORIGINAL_FULLPATH')
133
- @env['HTTP_REFERER'] = @url_lang_switcher.remove_lang_from_uri_component(@env['HTTP_REFERER'], lang_code) if @env.key?('HTTP_REFERER')
134
- end
135
- @env
136
- end
137
-
138
- def out(headers)
139
- r = Regexp.new("//#{@host}")
140
- lang_code = Store.instance.settings['custom_lang_aliases'][self.lang_code] || self.lang_code
141
- if lang_code != @settings['default_lang'] && headers.key?('Location') && headers['Location'] =~ r && !@settings['ignore_globs'].ignore?(headers['Location'])
142
- case @settings['url_pattern']
143
- when 'query'
144
- headers['Location'] += if /\?/.match?(headers['Location'])
145
- '&'
146
- else
147
- '?'
148
- end
149
- headers['Location'] += "#{@settings['lang_param_name']}=#{lang_code}"
150
- when 'subdomain'
151
- headers['Location'] = headers['Location'].sub(/\/\/([^.]+)/, "//#{lang_code}.\\1")
152
- # when 'path'
153
- else
154
- headers['Location'] = headers['Location'].sub(/(\/\/[^\/]+)/, "\\1/#{lang_code}")
155
- end
156
- end
157
- headers
158
- end
159
-
160
- def dirname
161
- if pathname_with_trailing_slash_if_present.include?('/')
162
- pathname_with_trailing_slash_if_present.end_with?('/') ? pathname_with_trailing_slash_if_present : pathname_with_trailing_slash_if_present[0, pathname_with_trailing_slash_if_present.rindex('/') + 1]
163
- else
164
- '/'
165
- end
166
- end
167
-
168
- def search_engine_bot?
169
- return false unless @env.key?('HTTP_USER_AGENT')
170
-
171
- bots = %w[Googlebot/ bingbot/ YandexBot/ YandexWebmaster/ DuckDuckBot-Https/ Baiduspider/ Slurp Yahoo]
172
- bots.any? { |bot| @env['HTTP_USER_AGENT'].include?(bot) }
173
- end
174
-
175
- def to_absolute_path(path)
176
- absolute_path = path.blank? ? '/' : path
177
- absolute_path = absolute_path.starts_with?('/') ? absolute_path : URL.join_paths(dirname, absolute_path)
178
- URL.normalize_path_slash(path, absolute_path)
179
- end
180
- end
181
- end
1
+ require 'wovnrb/custom_domain/custom_domain_lang_url_handler'
2
+
3
+ module Wovnrb
4
+ class Headers
5
+ attr_reader :unmasked_url, :url, :protocol, :unmasked_host, :host, :unmasked_pathname, :pathname, :pathname_with_trailing_slash_if_present
6
+
7
+ # Generates new instance of Wovnrb::Headers.
8
+ # Its parameters are set by parsing env variable.
9
+
10
+ def initialize(env, settings, url_lang_switcher)
11
+ request = Rack::Request.new(env)
12
+ @url_lang_switcher = url_lang_switcher
13
+ @env = env
14
+ @settings = settings
15
+ @protocol = request.scheme
16
+ @unmasked_host = if settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
17
+ @env['HTTP_X_FORWARDED_HOST']
18
+ else
19
+ @env['HTTP_HOST']
20
+ end
21
+ unless @env.key?('REQUEST_URI')
22
+ # Add '/' to PATH_INFO as a possible fix for pow server
23
+ @env['REQUEST_URI'] = (/^[^\/]/.match?(@env['PATH_INFO']) ? '/' : '') + @env['PATH_INFO'] + (@env['QUERY_STRING'].empty? ? '' : "?#{@env['QUERY_STRING']}")
24
+ end
25
+ # REQUEST_URI is expected to not contain the server name
26
+ # heroku contains http://...
27
+ @env['REQUEST_URI'] = @env['REQUEST_URI'].sub(/^https?:\/\/[^\/]+/, '') if /^https?:\/\//.match?(@env['REQUEST_URI'])
28
+ @unmasked_pathname = @env['REQUEST_URI'].split('?')[0]
29
+ @unmasked_pathname += '/' unless @unmasked_pathname =~ /\/$/ || @unmasked_pathname =~ /\/[^\/.]+\.[^\/.]+$/
30
+ @unmasked_url = "#{@protocol}://#{@unmasked_host}#{@unmasked_pathname}"
31
+ @host = if settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
32
+ @env['HTTP_X_FORWARDED_HOST']
33
+ else
34
+ @env['HTTP_HOST']
35
+ end
36
+ @host = %w[subdomain custom_domain].include?(settings['url_pattern']) ? @url_lang_switcher.remove_lang_from_uri_component(@host, lang_code, self) : @host
37
+ @pathname, @query = @env['REQUEST_URI'].split('?')
38
+ @pathname = %w[path custom_domain].include?(settings['url_pattern']) ? @url_lang_switcher.remove_lang_from_uri_component(@pathname, lang_code, self) : @pathname
39
+ @query ||= ''
40
+ @url = "#{@host}#{@pathname}#{(@query.empty? ? '' : '?') + @url_lang_switcher.remove_lang_from_uri_component(@query, lang_code)}"
41
+ if settings['query'].empty?
42
+ @query = ''
43
+ else
44
+ query_vals = []
45
+ settings['query'].each do |qv|
46
+ rx = Regexp.new("(^|&)(?<query_val>#{qv}[^&]+)(&|$)")
47
+ m = @query.match(rx)
48
+ query_vals.push(m[:query_val]) if m && m[:query_val]
49
+ end
50
+ @query = if query_vals.empty?
51
+ ''
52
+ else
53
+ "?#{query_vals.sort.join('&')}"
54
+ end
55
+ end
56
+ @query = @url_lang_switcher.remove_lang_from_uri_component(@query, lang_code)
57
+ @pathname_with_trailing_slash_if_present = @pathname
58
+ @pathname = @pathname.gsub(/\/$/, '')
59
+ end
60
+
61
+ def url_with_scheme
62
+ "#{@protocol}://#{@url}"
63
+ end
64
+
65
+ def unmasked_pathname_without_trailing_slash
66
+ @unmasked_pathname.chomp('/')
67
+ end
68
+
69
+ # Get the language code of the current request
70
+ #
71
+ # @return [String] The lang code of the current page
72
+ def lang_code
73
+ url_language && !url_language.empty? ? url_language : @settings['default_lang']
74
+ end
75
+
76
+ # picks up language code from requested URL by using url_pattern_reg setting.
77
+ # when language code is invalid, this method returns empty string.
78
+ # if you want examples, please see test/lib/headers_test.rb.
79
+ #
80
+ # @return [String] language code in requrested URL.
81
+ def url_language
82
+ if @url_language.nil?
83
+ full_url = if @settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
84
+ "#{@env['HTTP_X_FORWARDED_HOST']}#{@env['REQUEST_URI']}"
85
+ else
86
+ "#{@env['SERVER_NAME']}#{@env['REQUEST_URI']}"
87
+ end
88
+
89
+ new_lang_code = nil
90
+ if @settings['url_pattern'] == 'custom_domain'
91
+ custom_domain_langs = Store.instance.custom_domain_langs
92
+ custom_domain = custom_domain_langs.custom_domain_lang_by_url(full_url)
93
+ new_lang_code = custom_domain.lang if custom_domain.present?
94
+ else
95
+ rp = Regexp.new(@settings['url_pattern_reg'])
96
+ match = full_url.match(rp)
97
+ new_lang_code = Lang.get_code(match[:lang]) if match && match[:lang] && Lang.get_lang(match[:lang])
98
+ end
99
+ @url_language = new_lang_code.presence || ''
100
+ end
101
+ @url_language
102
+ end
103
+
104
+ def redirect(lang)
105
+ redirect_headers = {}
106
+ redirect_headers['location'] = redirect_location(lang)
107
+ redirect_headers['content-length'] = '0'
108
+ redirect_headers
109
+ end
110
+
111
+ def redirect_location(lang)
112
+ if lang == @settings['default_lang']
113
+ # IS THIS RIGHT??
114
+ return url_with_scheme
115
+ end
116
+
117
+ @url_lang_switcher.add_lang_code(url_with_scheme, lang, self)
118
+ end
119
+
120
+ def request_out
121
+ @env['wovnrb.target_lang'] = lang_code
122
+ case @settings['url_pattern']
123
+ when 'query'
124
+ remove_lang_from_query
125
+ when 'subdomain'
126
+ remove_lang_from_host
127
+ when 'custom_domain'
128
+ remove_lang_from_host
129
+ remove_lang_from_path
130
+ # when 'path'
131
+ else
132
+ remove_lang_from_path
133
+ end
134
+ @env
135
+ end
136
+
137
+ def out(headers)
138
+ lang_code = Store.instance.settings['custom_lang_aliases'][self.lang_code] || self.lang_code
139
+ should_add_lang_code = lang_code != @settings['default_lang'] && headers.key?('Location') && !@settings['ignore_globs'].ignore?(headers['Location'])
140
+
141
+ headers['Location'] = @url_lang_switcher.add_lang_code(headers['Location'], lang_code, self) if should_add_lang_code
142
+ headers
143
+ end
144
+
145
+ def dirname
146
+ if pathname_with_trailing_slash_if_present.include?('/')
147
+ pathname_with_trailing_slash_if_present.end_with?('/') ? pathname_with_trailing_slash_if_present : pathname_with_trailing_slash_if_present[0, pathname_with_trailing_slash_if_present.rindex('/') + 1]
148
+ else
149
+ '/'
150
+ end
151
+ end
152
+
153
+ def search_engine_bot?
154
+ return false unless @env.key?('HTTP_USER_AGENT')
155
+
156
+ bots = %w[Googlebot/ bingbot/ YandexBot/ YandexWebmaster/ DuckDuckBot-Https/ Baiduspider/ Slurp Yahoo]
157
+ bots.any? { |bot| @env['HTTP_USER_AGENT'].include?(bot) }
158
+ end
159
+
160
+ def to_absolute_path(path)
161
+ absolute_path = path.blank? ? '/' : path
162
+ absolute_path = URL.join_paths(dirname, absolute_path) unless absolute_path.starts_with?('/')
163
+ URL.normalize_path_slash(path, absolute_path)
164
+ end
165
+
166
+ private
167
+
168
+ def remove_lang_from_query
169
+ @env['REQUEST_URI'] = @url_lang_switcher.remove_lang_from_uri_component(@env['REQUEST_URI'], lang_code) if @env.key?('REQUEST_URI')
170
+ @env['QUERY_STRING'] = @url_lang_switcher.remove_lang_from_uri_component(@env['QUERY_STRING'], lang_code) if @env.key?('QUERY_STRING')
171
+ @env['ORIGINAL_FULLPATH'] = @url_lang_switcher.remove_lang_from_uri_component(@env['ORIGINAL_FULLPATH'], lang_code) if @env.key?('ORIGINAL_FULLPATH')
172
+ end
173
+
174
+ def remove_lang_from_host
175
+ if @settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
176
+ @env['HTTP_X_FORWARDED_HOST'] = @url_lang_switcher.remove_lang_from_uri_component(@env['HTTP_X_FORWARDED_HOST'], lang_code, self)
177
+ else
178
+ @env['HTTP_HOST'] = @url_lang_switcher.remove_lang_from_uri_component(@env['HTTP_HOST'], lang_code, self)
179
+ @env['SERVER_NAME'] = @url_lang_switcher.remove_lang_from_uri_component(@env['SERVER_NAME'], lang_code, self)
180
+ end
181
+ @env['HTTP_REFERER'] = @url_lang_switcher.remove_lang_from_uri_component(@env['HTTP_REFERER'], lang_code, self) if @env.key?('HTTP_REFERER')
182
+ end
183
+
184
+ def remove_lang_from_path
185
+ @env['REQUEST_URI'] = @url_lang_switcher.remove_lang_from_uri_component(@env['REQUEST_URI'], lang_code, self)
186
+ @env['REQUEST_PATH'] = @url_lang_switcher.remove_lang_from_uri_component(@env['REQUEST_PATH'], lang_code, self) if @env.key?('REQUEST_PATH')
187
+ @env['PATH_INFO'] = @url_lang_switcher.remove_lang_from_uri_component(@env['PATH_INFO'], lang_code, self)
188
+ @env['ORIGINAL_FULLPATH'] = @url_lang_switcher.remove_lang_from_uri_component(@env['ORIGINAL_FULLPATH'], lang_code, self) if @env.key?('ORIGINAL_FULLPATH')
189
+ @env['HTTP_REFERER'] = @url_lang_switcher.remove_lang_from_uri_component(@env['HTTP_REFERER'], lang_code, self) if @env.key?('HTTP_REFERER')
190
+ end
191
+ end
192
+ end
data/lib/wovnrb/lang.rb CHANGED
@@ -250,7 +250,7 @@ module Wovnrb
250
250
  end
251
251
 
252
252
  def add_query_lang_code(href, lang_code, lang_param_name)
253
- query_separator = /\?/.match?(href) ? '&' : '?'
253
+ query_separator = href.include?('?') ? '&' : '?'
254
254
 
255
255
  href.sub(/(#|$)/, "#{query_separator}#{lang_param_name}=#{lang_code}\\1")
256
256
  end