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) ⇒ Headers

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



8
9
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
# File 'lib/wovnrb/headers.rb', line 8

def initialize(env, settings)
  request = Rack::Request.new(env)

  @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'] = (@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 @env['REQUEST_URI'] =~ /^https?:\/\//
  @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 = settings['url_pattern'] == 'subdomain' ? remove_lang(@host, lang_code) : @host
  @pathname, @query = @env['REQUEST_URI'].split('?')
  @pathname = settings['url_pattern'] == 'path' ? remove_lang(@pathname, lang_code) : @pathname
  @query ||= ''
  @url = "#{@host}#{@pathname}#{(@query.empty? ? '' : '?') + remove_lang(@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 = remove_lang(@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.



3
4
5
# File 'lib/wovnrb/headers.rb', line 3

def host
  @host
end

#pathnameObject (readonly)

Returns the value of attribute pathname.



3
4
5
# File 'lib/wovnrb/headers.rb', line 3

def pathname
  @pathname
end

#pathname_with_trailing_slash_if_presentObject (readonly)

Returns the value of attribute pathname_with_trailing_slash_if_present.



3
4
5
# File 'lib/wovnrb/headers.rb', line 3

def pathname_with_trailing_slash_if_present
  @pathname_with_trailing_slash_if_present
end

#protocolObject (readonly)

Returns the value of attribute protocol.



3
4
5
# File 'lib/wovnrb/headers.rb', line 3

def protocol
  @protocol
end

#unmasked_hostObject (readonly)

Returns the value of attribute unmasked_host.



3
4
5
# File 'lib/wovnrb/headers.rb', line 3

def unmasked_host
  @unmasked_host
end

#unmasked_pathnameObject (readonly)

Returns the value of attribute unmasked_pathname.



3
4
5
# File 'lib/wovnrb/headers.rb', line 3

def unmasked_pathname
  @unmasked_pathname
end

#unmasked_urlObject (readonly)

Returns the value of attribute unmasked_url.



3
4
5
# File 'lib/wovnrb/headers.rb', line 3

def unmasked_url
  @unmasked_url
end

#urlObject (readonly)

Returns the value of attribute url.



3
4
5
# File 'lib/wovnrb/headers.rb', line 3

def url
  @url
end

Instance Method Details

#dirnameObject



199
200
201
202
203
204
205
# File 'lib/wovnrb/headers.rb', line 199

def dirname
  if pathname.include?('/')
    pathname.end_with?('/') ? pathname : pathname[0, pathname.rindex('/') + 1]
  else
    '/'
  end
end

#lang_codeString

Get the language code of the current request

Returns:

  • (String)

    The lang code of the current page



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

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

#out(headers) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/wovnrb/headers.rb', line 177

def out(headers)
  r = Regexp.new("//#{@host}")
  lang_code = Store.instance.settings['custom_lang_aliases'][self.lang_code] || self.lang_code
  if lang_code != @settings['default_lang'] && headers.key?('Location') && headers['Location'] =~ r && !@settings['ignore_globs'].ignore?(headers['Location'])
    case @settings['url_pattern']
    when 'query'
      headers['Location'] += if headers['Location'] =~ /\?/
                               '&'
                             else
                               '?'
                             end
      headers['Location'] += "#{@settings['lang_param_name']}=#{lang_code}"
    when 'subdomain'
      headers['Location'] = headers['Location'].sub(/\/\/([^.]+)/, "//#{lang_code}.\\1")
    # when 'path'
    else
      headers['Location'] = headers['Location'].sub(/(\/\/[^\/]+)/, "\\1/#{lang_code}")
    end
  end
  headers
end

#path_langString

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.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/wovnrb/headers.rb', line 75

def path_lang
  if @path_lang.nil?
    rp = Regexp.new(@settings['url_pattern_reg'])
    match = if @settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
              "#{@env['HTTP_X_FORWARDED_HOST']}#{@env['REQUEST_URI']}".match(rp)
            else
              "#{@env['SERVER_NAME']}#{@env['REQUEST_URI']}".match(rp)
            end
    @path_lang = if match && match[:lang] && Lang.get_lang(match[:lang])
                   Lang.get_code(match[:lang])
                 else
                   ''
                 end
  end
  @path_lang
end

#redirect(lang) ⇒ Object



92
93
94
95
96
97
# File 'lib/wovnrb/headers.rb', line 92

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

#redirect_location(lang) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/wovnrb/headers.rb', line 99

def redirect_location(lang)
  if lang == @settings['default_lang']
    # IS THIS RIGHT??
    "#{protocol}://#{url}"
    # return remove_lang("#{@env['HTTP_HOST']}#{@env['REQUEST_URI']}", lang)
  else
    # TODO test
    lang_code = Store.instance.settings['custom_lang_aliases'][lang] || lang
    location = url
    case @settings['url_pattern']
    when 'query'
      lang_param_name = @settings['lang_param_name']
      location = if location =~ /\?/
                   "#{location}&#{lang_param_name}=#{lang_code}"
                 else
                   "#{location}?#{lang_param_name}=#{lang_code}"
                 end
    when 'subdomain'
      location = "#{lang_code.downcase}.#{location}"
    # when 'path'
    else
      location = location.sub(/(\/|$)/, "/#{lang_code}/")
    end
    "#{protocol}://#{location}"
  end
end

#remove_lang(uri, lang = path_lang) ⇒ String

TODO: this should be in Lang for reusability Remove language code from the URI.

Parameters:

  • uri (String)

    original URI

  • lang_code (String)

    language code

Returns:

  • (String)

    removed URI



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/wovnrb/headers.rb', line 158

def remove_lang(uri, lang = path_lang)
  lang_code = Store.instance.settings['custom_lang_aliases'][lang] || lang

  # Do nothing if lang is empty.
  return uri if lang_code.nil? || lang_code.empty?

  case @settings['url_pattern']
  when 'query'
    lang_param_name = @settings['lang_param_name']
    uri.sub(/(^|\?|&)#{lang_param_name}=#{lang_code}(&|$)/, '\1').gsub(/(\?|&)$/, '')
  when 'subdomain'
    rp = Regexp.new("(^|(//))#{lang_code}\\.", 'i')
    uri.sub(rp, '\1')
  # when 'path'
  else
    uri.sub(/\/#{lang_code}(\/|$)/, '/')
  end
end

#request_out(_def_lang = ) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/wovnrb/headers.rb', line 126

def request_out(_def_lang = @settings['default_lang'])
  @env['wovnrb.target_lang'] = lang_code
  case @settings['url_pattern']
  when 'query'
    @env['REQUEST_URI'] = remove_lang(@env['REQUEST_URI']) if @env.key?('REQUEST_URI')
    @env['QUERY_STRING'] = remove_lang(@env['QUERY_STRING']) if @env.key?('QUERY_STRING')
    @env['ORIGINAL_FULLPATH'] = remove_lang(@env['ORIGINAL_FULLPATH']) if @env.key?('ORIGINAL_FULLPATH')
  when 'subdomain'
    if @settings['use_proxy'] && @env.key?('HTTP_X_FORWARDED_HOST')
      @env['HTTP_X_FORWARDED_HOST'] = remove_lang(@env['HTTP_X_FORWARDED_HOST'])
    else
      @env['HTTP_HOST'] = remove_lang(@env['HTTP_HOST'])
      @env['SERVER_NAME'] = remove_lang(@env['SERVER_NAME'])
    end
    @env['HTTP_REFERER'] = remove_lang(@env['HTTP_REFERER']) if @env.key?('HTTP_REFERER')
  # when 'path'
  else
    @env['REQUEST_URI'] = remove_lang(@env['REQUEST_URI'])
    @env['REQUEST_PATH'] = remove_lang(@env['REQUEST_PATH']) if @env.key?('REQUEST_PATH')
    @env['PATH_INFO'] = remove_lang(@env['PATH_INFO'])
    @env['ORIGINAL_FULLPATH'] = remove_lang(@env['ORIGINAL_FULLPATH']) if @env.key?('ORIGINAL_FULLPATH')
    @env['HTTP_REFERER'] = remove_lang(@env['HTTP_REFERER']) if @env.key?('HTTP_REFERER')
  end
  @env
end

#unmasked_pathname_without_trailing_slashObject



59
60
61
# File 'lib/wovnrb/headers.rb', line 59

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