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.



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
60
61
62
63
64
# File 'lib/wovnrb/headers.rb', line 15

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_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?
               "?#{query_vals.sort.join('&')}"
             else
               ''
             end
  else
    @query = ''
  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.



7
8
9
# File 'lib/wovnrb/headers.rb', line 7

def host
  @host
end

#pathnameObject (readonly)

Returns the value of attribute pathname.



9
10
11
# File 'lib/wovnrb/headers.rb', line 9

def pathname
  @pathname
end

#pathname_with_trailing_slash_if_presentObject (readonly)

Returns the value of attribute pathname_with_trailing_slash_if_present.



10
11
12
# File 'lib/wovnrb/headers.rb', line 10

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.



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

def unmasked_host
  @unmasked_host
end

#unmasked_pathnameObject (readonly)

Returns the value of attribute unmasked_pathname.



8
9
10
# File 'lib/wovnrb/headers.rb', line 8

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.



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

def url
  @url
end

Instance Method Details

#dirnameObject



208
209
210
211
212
213
214
# File 'lib/wovnrb/headers.rb', line 208

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



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

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

#out(headers) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/wovnrb/headers.rb', line 184

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
    unless @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
  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.



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

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



99
100
101
102
103
104
# File 'lib/wovnrb/headers.rb', line 99

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

#redirect_location(lang) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/wovnrb/headers.rb', line 106

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']
      if location !~ /\?/
        location = "#{location}?#{lang_param_name}=#{lang_code}"
      else @env['REQUEST_URI'] !~ /(\?|&)#{lang_param_name}=/
           location = "#{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



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/wovnrb/headers.rb', line 165

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



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/wovnrb/headers.rb', line 133

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



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

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