Class: Wovnrb::Headers

Inherits:
Object
  • Object
show all
Defined in:
lib/wovnrb/headers.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env, settings, url_lang_switcher) ⇒ Headers

Generates new instance of Wovnrb::Headers. Its parameters are set by parsing env variable.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/wovnrb/headers.rb', line 10

def initialize(env, settings, url_lang_switcher)
  request = Rack::Request.new(env)
  @url_lang_switcher = url_lang_switcher
  @env = env
  @settings = settings
  @protocol = request.scheme
  @unmasked_host = if settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
                     @env['HTTP_X_FORWARDED_HOST']
                   else
                     @env['HTTP_HOST']
                   end
  unless @env.key?('REQUEST_URI')
    # Add '/' to PATH_INFO as a possible fix for pow server
    @env['REQUEST_URI'] = (/^[^\/]/.match?(@env['PATH_INFO']) ? '/' : '') + @env['PATH_INFO'] + (@env['QUERY_STRING'].empty? ? '' : "?#{@env['QUERY_STRING']}")
  end
  # REQUEST_URI is expected to not contain the server name
  # heroku contains http://...
  @env['REQUEST_URI'] = @env['REQUEST_URI'].sub(/^https?:\/\/[^\/]+/, '') if /^https?:\/\//.match?(@env['REQUEST_URI'])
  @unmasked_pathname = @env['REQUEST_URI'].split('?')[0]
  @unmasked_pathname += '/' unless @unmasked_pathname =~ /\/$/ || @unmasked_pathname =~ /\/[^\/.]+\.[^\/.]+$/
  @unmasked_url = "#{@protocol}://#{@unmasked_host}#{@unmasked_pathname}"
  @host = if settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
            @env['HTTP_X_FORWARDED_HOST']
          else
            @env['HTTP_HOST']
          end
  @host = %w[subdomain custom_domain].include?(settings['url_pattern']) ? @url_lang_switcher.remove_lang_from_uri_component(@host, lang_code, self) : @host
  @pathname, @query = @env['REQUEST_URI'].split('?')
  @pathname = %w[path custom_domain].include?(settings['url_pattern']) ? @url_lang_switcher.remove_lang_from_uri_component(@pathname, lang_code, self) : @pathname
  @query ||= ''
  @url = "#{@host}#{@pathname}#{(@query.empty? ? '' : '?') + @url_lang_switcher.remove_lang_from_uri_component(@query, lang_code)}"
  if settings['query'].empty?
    @query = ''
  else
    query_vals = []
    settings['query'].each do |qv|
      rx = Regexp.new("(^|&)(?<query_val>#{qv}[^&]+)(&|$)")
      m = @query.match(rx)
      query_vals.push(m[:query_val]) if m && m[:query_val]
    end
    @query = if query_vals.empty?
               ''
             else
               "?#{query_vals.sort.join('&')}"
             end
  end
  @query = @url_lang_switcher.remove_lang_from_uri_component(@query, lang_code)
  @pathname_with_trailing_slash_if_present = @pathname
  @pathname = @pathname.gsub(/\/$/, '')
end

Instance Attribute Details

#hostObject (readonly)

Returns the value of attribute host.



5
6
7
# File 'lib/wovnrb/headers.rb', line 5

def host
  @host
end

#pathnameObject (readonly)

Returns the value of attribute pathname.



5
6
7
# File 'lib/wovnrb/headers.rb', line 5

def pathname
  @pathname
end

#pathname_with_trailing_slash_if_presentObject (readonly)

Returns the value of attribute pathname_with_trailing_slash_if_present.



5
6
7
# File 'lib/wovnrb/headers.rb', line 5

def pathname_with_trailing_slash_if_present
  @pathname_with_trailing_slash_if_present
end

#protocolObject (readonly)

Returns the value of attribute protocol.



5
6
7
# File 'lib/wovnrb/headers.rb', line 5

def protocol
  @protocol
end

#unmasked_hostObject (readonly)

Returns the value of attribute unmasked_host.



5
6
7
# File 'lib/wovnrb/headers.rb', line 5

def unmasked_host
  @unmasked_host
end

#unmasked_pathnameObject (readonly)

Returns the value of attribute unmasked_pathname.



5
6
7
# File 'lib/wovnrb/headers.rb', line 5

def unmasked_pathname
  @unmasked_pathname
end

#unmasked_urlObject (readonly)

Returns the value of attribute unmasked_url.



5
6
7
# File 'lib/wovnrb/headers.rb', line 5

def unmasked_url
  @unmasked_url
end

#urlObject (readonly)

Returns the value of attribute url.



5
6
7
# File 'lib/wovnrb/headers.rb', line 5

def url
  @url
end

Instance Method Details

#dirnameObject



145
146
147
148
149
150
151
# File 'lib/wovnrb/headers.rb', line 145

def dirname
  if pathname_with_trailing_slash_if_present.include?('/')
    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]
  else
    '/'
  end
end

#lang_codeString

Get the language code of the current request

Returns:

  • (String)

    The lang code of the current page



72
73
74
# File 'lib/wovnrb/headers.rb', line 72

def lang_code
  url_language && !url_language.empty? ? url_language : @settings['default_lang']
end

#out(headers) ⇒ Object



137
138
139
140
141
142
143
# File 'lib/wovnrb/headers.rb', line 137

def out(headers)
  lang_code = Store.instance.settings['custom_lang_aliases'][self.lang_code] || self.lang_code
  should_add_lang_code = lang_code != @settings['default_lang'] && headers.key?('Location') && !@settings['ignore_globs'].ignore?(headers['Location'])

  headers['Location'] = @url_lang_switcher.add_lang_code(headers['Location'], lang_code, self) if should_add_lang_code
  headers
end

#redirect(lang) ⇒ Object



104
105
106
107
108
109
# File 'lib/wovnrb/headers.rb', line 104

def redirect(lang)
  redirect_headers = {}
  redirect_headers['location'] = redirect_location(lang)
  redirect_headers['content-length'] = '0'
  redirect_headers
end

#redirect_location(lang) ⇒ Object



111
112
113
114
115
116
117
118
# File 'lib/wovnrb/headers.rb', line 111

def redirect_location(lang)
  if lang == @settings['default_lang']
    # IS THIS RIGHT??
    return url_with_scheme
  end

  @url_lang_switcher.add_lang_code(url_with_scheme, lang, self)
end

#request_outObject



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/wovnrb/headers.rb', line 120

def request_out
  @env['wovnrb.target_lang'] = lang_code
  case @settings['url_pattern']
  when 'query'
    remove_lang_from_query
  when 'subdomain'
    remove_lang_from_host
  when 'custom_domain'
    remove_lang_from_host
    remove_lang_from_path
    # when 'path'
  else
    remove_lang_from_path
  end
  @env
end

#search_engine_bot?Boolean

Returns:

  • (Boolean)


153
154
155
156
157
158
# File 'lib/wovnrb/headers.rb', line 153

def search_engine_bot?
  return false unless @env.key?('HTTP_USER_AGENT')

  bots = %w[Googlebot/ bingbot/ YandexBot/ YandexWebmaster/ DuckDuckBot-Https/ Baiduspider/ Slurp Yahoo]
  bots.any? { |bot| @env['HTTP_USER_AGENT'].include?(bot) }
end

#to_absolute_path(path) ⇒ Object



160
161
162
163
164
# File 'lib/wovnrb/headers.rb', line 160

def to_absolute_path(path)
  absolute_path = path.blank? ? '/' : path
  absolute_path = URL.join_paths(dirname, absolute_path) unless absolute_path.starts_with?('/')
  URL.normalize_path_slash(path, absolute_path)
end

#unmasked_pathname_without_trailing_slashObject



65
66
67
# File 'lib/wovnrb/headers.rb', line 65

def unmasked_pathname_without_trailing_slash
  @unmasked_pathname.chomp('/')
end

#url_languageString

picks up language code from requested URL by using url_pattern_reg setting. when language code is invalid, this method returns empty string. if you want examples, please see test/lib/headers_test.rb.

Returns:

  • (String)

    language code in requrested URL.



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/wovnrb/headers.rb', line 81

def url_language
  if @url_language.nil?
    full_url = if @settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
                 "#{@env['HTTP_X_FORWARDED_HOST']}#{@env['REQUEST_URI']}"
               else
                 "#{@env['SERVER_NAME']}#{@env['REQUEST_URI']}"
               end

    new_lang_code = nil
    if @settings['url_pattern'] == 'custom_domain'
      custom_domain_langs = Store.instance.custom_domain_langs
      custom_domain = custom_domain_langs.custom_domain_lang_by_url(full_url)
      new_lang_code = custom_domain.lang if custom_domain.present?
    else
      rp = Regexp.new(@settings['url_pattern_reg'])
      match = full_url.match(rp)
      new_lang_code = Lang.get_code(match[:lang]) if match && match[:lang] && Lang.get_lang(match[:lang])
    end
    @url_language = new_lang_code.presence || ''
  end
  @url_language
end

#url_with_schemeObject



61
62
63
# File 'lib/wovnrb/headers.rb', line 61

def url_with_scheme
  "#{@protocol}://#{@url}"
end