rack-wwwhisper 1.0.1.pre → 1.0.2.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/rack/wwwhisper.rb +119 -112
 - data/test/test_wwwhisper.rb +27 -18
 - metadata +5 -2
 
    
        data/lib/rack/wwwhisper.rb
    CHANGED
    
    | 
         @@ -33,10 +33,12 @@ class WWWhisper 
     | 
|
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
                @wwwhisper_iframe = ENV['WWWHISPER_IFRAME'] ||
         
     | 
| 
       35 
35 
     | 
    
         
             
                  sprintf(@@DEFAULT_IFRAME, wwwhisper_path('auth/overlay.html'))
         
     | 
| 
      
 36 
     | 
    
         
            +
                @wwwhisper_iframe_bytesize = Rack::Utils::bytesize(@wwwhisper_iframe)
         
     | 
| 
       36 
37 
     | 
    
         | 
| 
       37 
38 
     | 
    
         
             
                @request_config = {
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # TODO: probably now auth can be removed.
         
     | 
| 
       38 
40 
     | 
    
         
             
                  :auth => {
         
     | 
| 
       39 
     | 
    
         
            -
                    :forwarded_headers => ['Cookie'],
         
     | 
| 
      
 41 
     | 
    
         
            +
                    :forwarded_headers => ['Accept', 'Accept-Language', 'Cookie'],
         
     | 
| 
       40 
42 
     | 
    
         
             
                    :http => wwwhisper_http,
         
     | 
| 
       41 
43 
     | 
    
         
             
                    :uri => wwwhisper_uri,
         
     | 
| 
       42 
44 
     | 
    
         
             
                    :send_site_url => true,
         
     | 
| 
         @@ -76,12 +78,45 @@ class WWWhisper 
     | 
|
| 
       76 
78 
     | 
    
         
             
                wwwhisper_path "auth/api/is-authorized/?path=#{queried_path}"
         
     | 
| 
       77 
79 
     | 
    
         
             
              end
         
     | 
| 
       78 
80 
     | 
    
         | 
| 
       79 
     | 
    
         
            -
              def  
     | 
| 
       80 
     | 
    
         
            -
                 
     | 
| 
      
 81 
     | 
    
         
            +
              def call(env)
         
     | 
| 
      
 82 
     | 
    
         
            +
                req = Rack::Request.new(env)
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                normalize_path req
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                if req.path =~ %r{^#{@@WWWHISPER_PREFIX}auth}
         
     | 
| 
      
 87 
     | 
    
         
            +
                  # Requests to /@@WWWHISPER_PREFIX/auth/ should not be authorized,
         
     | 
| 
      
 88 
     | 
    
         
            +
                  # every visitor can access login pages.
         
     | 
| 
      
 89 
     | 
    
         
            +
                  return dispatch(req)
         
     | 
| 
      
 90 
     | 
    
         
            +
                end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                debug req, "sending auth request for #{req.path}"
         
     | 
| 
      
 93 
     | 
    
         
            +
                auth_resp = wwwhisper_auth_request(req)
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                if auth_resp.code == '200'
         
     | 
| 
      
 96 
     | 
    
         
            +
                  debug req, 'access granted'
         
     | 
| 
      
 97 
     | 
    
         
            +
                  status, headers, body = dispatch(req)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  if should_inject_iframe(status, headers)
         
     | 
| 
      
 99 
     | 
    
         
            +
                    body = inject_iframe(headers, body)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  end
         
     | 
| 
      
 101 
     | 
    
         
            +
                  [status, headers, body]
         
     | 
| 
      
 102 
     | 
    
         
            +
                else
         
     | 
| 
      
 103 
     | 
    
         
            +
                  debug req, {
         
     | 
| 
      
 104 
     | 
    
         
            +
                    '401' => 'user not authenticated',
         
     | 
| 
      
 105 
     | 
    
         
            +
                    '403' => 'access_denied',
         
     | 
| 
      
 106 
     | 
    
         
            +
                  }[auth_resp.code] || 'auth request failed'
         
     | 
| 
      
 107 
     | 
    
         
            +
                  sub_response_to_rack(req, auth_resp)
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
       81 
109 
     | 
    
         
             
              end
         
     | 
| 
       82 
110 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
               
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
      
 111 
     | 
    
         
            +
              private
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
              def debug(req, message)
         
     | 
| 
      
 114 
     | 
    
         
            +
                req.logger.debug "wwwhisper #{message}" if req.logger
         
     | 
| 
      
 115 
     | 
    
         
            +
              end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
              def normalize_path(req)
         
     | 
| 
      
 118 
     | 
    
         
            +
                req.script_name = Addressable::URI.normalize_path(req.script_name)
         
     | 
| 
      
 119 
     | 
    
         
            +
                req.path_info = Addressable::URI.normalize_path(req.path_info)
         
     | 
| 
       85 
120 
     | 
    
         
             
              end
         
     | 
| 
       86 
121 
     | 
    
         | 
| 
       87 
122 
     | 
    
         
             
              def parse_uri(uri)
         
     | 
| 
         @@ -92,15 +127,6 @@ class WWWhisper 
     | 
|
| 
       92 
127 
     | 
    
         
             
                parsed_uri
         
     | 
| 
       93 
128 
     | 
    
         
             
              end
         
     | 
| 
       94 
129 
     | 
    
         | 
| 
       95 
     | 
    
         
            -
              def http_init(connection_id)
         
     | 
| 
       96 
     | 
    
         
            -
                http = Net::HTTP::Persistent.new(connection_id)
         
     | 
| 
       97 
     | 
    
         
            -
                store = OpenSSL::X509::Store.new()
         
     | 
| 
       98 
     | 
    
         
            -
                store.set_default_paths
         
     | 
| 
       99 
     | 
    
         
            -
                http.cert_store = store
         
     | 
| 
       100 
     | 
    
         
            -
                http.verify_mode = OpenSSL::SSL::VERIFY_PEER
         
     | 
| 
       101 
     | 
    
         
            -
                return http
         
     | 
| 
       102 
     | 
    
         
            -
              end
         
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
130 
     | 
    
         
             
              def default_port(proto)
         
     | 
| 
       105 
131 
     | 
    
         
             
                {
         
     | 
| 
       106 
132 
     | 
    
         
             
                  'http' => 80,
         
     | 
| 
         @@ -125,143 +151,124 @@ class WWWhisper 
     | 
|
| 
       125 
151 
     | 
    
         
             
                "#{proto}://#{host}#{port_str}"
         
     | 
| 
       126 
152 
     | 
    
         
             
              end
         
     | 
| 
       127 
153 
     | 
    
         | 
| 
       128 
     | 
    
         
            -
              def  
     | 
| 
      
 154 
     | 
    
         
            +
              def http_init(connection_id)
         
     | 
| 
      
 155 
     | 
    
         
            +
                http = Net::HTTP::Persistent.new(connection_id)
         
     | 
| 
      
 156 
     | 
    
         
            +
                store = OpenSSL::X509::Store.new()
         
     | 
| 
      
 157 
     | 
    
         
            +
                store.set_default_paths
         
     | 
| 
      
 158 
     | 
    
         
            +
                http.cert_store = store
         
     | 
| 
      
 159 
     | 
    
         
            +
                http.verify_mode = OpenSSL::SSL::VERIFY_PEER
         
     | 
| 
      
 160 
     | 
    
         
            +
                return http
         
     | 
| 
      
 161 
     | 
    
         
            +
              end
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
              def sub_request_init(config, rack_req, method, path)
         
     | 
| 
       129 
164 
     | 
    
         
             
                path = @aliases[path] || path
         
     | 
| 
       130 
     | 
    
         
            -
                 
     | 
| 
       131 
     | 
    
         
            -
                copy_headers(config[:forwarded_headers], env,  
     | 
| 
       132 
     | 
    
         
            -
                 
     | 
| 
      
 165 
     | 
    
         
            +
                sub_req = Net::HTTP.const_get(method).new(path)
         
     | 
| 
      
 166 
     | 
    
         
            +
                copy_headers(config[:forwarded_headers], rack_req.env, sub_req)
         
     | 
| 
      
 167 
     | 
    
         
            +
                sub_req['Site-Url'] = site_url(rack_req.env) if config[:send_site_url]
         
     | 
| 
       133 
168 
     | 
    
         
             
                uri = config[:uri]
         
     | 
| 
       134 
     | 
    
         
            -
                 
     | 
| 
       135 
     | 
    
         
            -
                 
     | 
| 
      
 169 
     | 
    
         
            +
                sub_req.basic_auth(uri.user, uri.password) if uri.user and uri.password
         
     | 
| 
      
 170 
     | 
    
         
            +
                sub_req
         
     | 
| 
       136 
171 
     | 
    
         
             
              end
         
     | 
| 
       137 
172 
     | 
    
         | 
| 
       138 
173 
     | 
    
         
             
              def has_value(dict, key)
         
     | 
| 
       139 
174 
     | 
    
         
             
                dict[key] != nil and !dict[key].empty?
         
     | 
| 
       140 
175 
     | 
    
         
             
              end
         
     | 
| 
       141 
176 
     | 
    
         | 
| 
       142 
     | 
    
         
            -
              def copy_headers(headers_names, env,  
     | 
| 
      
 177 
     | 
    
         
            +
              def copy_headers(headers_names, env, sub_req)
         
     | 
| 
       143 
178 
     | 
    
         
             
                headers_names.each do |header|
         
     | 
| 
       144 
179 
     | 
    
         
             
                  key = "HTTP_#{header.upcase}".gsub(/-/, '_')
         
     | 
| 
       145 
     | 
    
         
            -
                   
     | 
| 
       146 
     | 
    
         
            -
                  #puts "Sending header #{header} #{request[header]} #{key} #{env[key]}"
         
     | 
| 
      
 180 
     | 
    
         
            +
                  sub_req[header] = env[key] if has_value(env, key)
         
     | 
| 
       147 
181 
     | 
    
         
             
                end
         
     | 
| 
       148 
182 
     | 
    
         
             
              end
         
     | 
| 
       149 
183 
     | 
    
         | 
| 
       150 
     | 
    
         
            -
              def copy_body( 
     | 
| 
       151 
     | 
    
         
            -
                if  
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
                   
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
      
 184 
     | 
    
         
            +
              def copy_body(rack_req, sub_req)
         
     | 
| 
      
 185 
     | 
    
         
            +
                if sub_req.request_body_permitted? and rack_req.body and
         
     | 
| 
      
 186 
     | 
    
         
            +
                    (rack_req.content_length or
         
     | 
| 
      
 187 
     | 
    
         
            +
                     rack_req.env['HTTP_TRANSFER_ENCODING'] == 'chunked')
         
     | 
| 
      
 188 
     | 
    
         
            +
                  sub_req.body_stream = rack_req.body
         
     | 
| 
      
 189 
     | 
    
         
            +
                  sub_req.content_length =
         
     | 
| 
      
 190 
     | 
    
         
            +
                    rack_req.content_length if rack_req.content_length
         
     | 
| 
      
 191 
     | 
    
         
            +
                  sub_req.content_type = rack_req.content_type if rack_req.content_type
         
     | 
| 
       156 
192 
     | 
    
         
             
                end
         
     | 
| 
       157 
193 
     | 
    
         
             
              end
         
     | 
| 
       158 
194 
     | 
    
         | 
| 
       159 
     | 
    
         
            -
              def  
     | 
| 
       160 
     | 
    
         
            -
                 
     | 
| 
       161 
     | 
    
         
            -
                 
     | 
| 
       162 
     | 
    
         
            -
                   
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
                    location  
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
                     
     | 
| 
      
 195 
     | 
    
         
            +
              def sub_response_headers_to_rack(rack_req, sub_resp)
         
     | 
| 
      
 196 
     | 
    
         
            +
                rack_headers = Rack::Utils::HeaderHash.new()
         
     | 
| 
      
 197 
     | 
    
         
            +
                sub_resp.each_capitalized do |header, value|
         
     | 
| 
      
 198 
     | 
    
         
            +
                  if header == 'Location'
         
     | 
| 
      
 199 
     | 
    
         
            +
                    location = Addressable::URI.parse(value)
         
     | 
| 
      
 200 
     | 
    
         
            +
                    location.scheme, location.host, location.port =
         
     | 
| 
      
 201 
     | 
    
         
            +
                      proto_host_port(rack_req.env)
         
     | 
| 
      
 202 
     | 
    
         
            +
                    value = location.to_s
         
     | 
| 
       167 
203 
     | 
    
         
             
                  end
         
     | 
| 
       168 
     | 
    
         
            -
                   
     | 
| 
       169 
     | 
    
         
            -
                  # TODO: what is transfer encoding?
         
     | 
| 
       170 
     | 
    
         
            -
                  headers[k] = v unless k.to_s =~ /transfer-encoding|content-length/i
         
     | 
| 
       171 
     | 
    
         
            -
                end
         
     | 
| 
       172 
     | 
    
         
            -
                return headers
         
     | 
| 
       173 
     | 
    
         
            -
              end
         
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
              def dispatch(env)
         
     | 
| 
       176 
     | 
    
         
            -
                orig_request = Rack::Request.new(env)
         
     | 
| 
       177 
     | 
    
         
            -
                if orig_request.path =~ %r{^#{@@WWWHISPER_PREFIX}}
         
     | 
| 
       178 
     | 
    
         
            -
                  debug orig_request, "passing request to wwwhisper service"
         
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
                  config =
         
     | 
| 
       181 
     | 
    
         
            -
                    if orig_request.path =~ %r{^#{@@WWWHISPER_PREFIX}(auth|admin)/api/}
         
     | 
| 
       182 
     | 
    
         
            -
                      @request_config[:api]
         
     | 
| 
       183 
     | 
    
         
            -
                    else
         
     | 
| 
       184 
     | 
    
         
            -
                      @request_config[:assets]
         
     | 
| 
       185 
     | 
    
         
            -
                    end
         
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
                  method = orig_request.request_method.capitalize
         
     | 
| 
       188 
     | 
    
         
            -
                  request = request_init(config, env, method, orig_request.fullpath)
         
     | 
| 
       189 
     | 
    
         
            -
                  copy_body(orig_request, request)
         
     | 
| 
       190 
     | 
    
         
            -
             
     | 
| 
       191 
     | 
    
         
            -
                  response = config[:http].request(config[:uri], request)
         
     | 
| 
       192 
     | 
    
         
            -
                  net_http_response_to_rack(env, response)
         
     | 
| 
       193 
     | 
    
         
            -
                else
         
     | 
| 
       194 
     | 
    
         
            -
                  debug orig_request, "passing request to Rack stack"
         
     | 
| 
       195 
     | 
    
         
            -
                  @app.call(env)
         
     | 
| 
      
 204 
     | 
    
         
            +
                  rack_headers[header] = value
         
     | 
| 
       196 
205 
     | 
    
         
             
                end
         
     | 
| 
      
 206 
     | 
    
         
            +
                return rack_headers
         
     | 
| 
       197 
207 
     | 
    
         
             
              end
         
     | 
| 
       198 
208 
     | 
    
         | 
| 
       199 
     | 
    
         
            -
              def  
     | 
| 
      
 209 
     | 
    
         
            +
              def sub_response_to_rack(rack_req, sub_resp)
         
     | 
| 
       200 
210 
     | 
    
         
             
                [
         
     | 
| 
       201 
     | 
    
         
            -
                  
     | 
| 
       202 
     | 
    
         
            -
                  
     | 
| 
       203 
     | 
    
         
            -
                 [( 
     | 
| 
      
 211 
     | 
    
         
            +
                 sub_resp.code.to_i,
         
     | 
| 
      
 212 
     | 
    
         
            +
                 sub_response_headers_to_rack(rack_req, sub_resp),
         
     | 
| 
      
 213 
     | 
    
         
            +
                 [(sub_resp.read_body() or '')]
         
     | 
| 
       204 
214 
     | 
    
         
             
                ]
         
     | 
| 
       205 
215 
     | 
    
         
             
              end
         
     | 
| 
       206 
216 
     | 
    
         | 
| 
       207 
     | 
    
         
            -
              def wwwhisper_auth_request( 
     | 
| 
      
 217 
     | 
    
         
            +
              def wwwhisper_auth_request(req)
         
     | 
| 
       208 
218 
     | 
    
         
             
                config = @request_config[:auth]
         
     | 
| 
       209 
     | 
    
         
            -
                 
     | 
| 
       210 
     | 
    
         
            -
                 
     | 
| 
       211 
     | 
    
         
            -
                net_http_response_to_rack(env, auth_response)
         
     | 
| 
      
 219 
     | 
    
         
            +
                auth_req = sub_request_init(config, req, 'Get', auth_query(req.path))
         
     | 
| 
      
 220 
     | 
    
         
            +
                config[:http].request(config[:uri], auth_req)
         
     | 
| 
       212 
221 
     | 
    
         
             
              end
         
     | 
| 
       213 
222 
     | 
    
         | 
| 
       214 
223 
     | 
    
         
             
              def should_inject_iframe(status, headers)
         
     | 
| 
       215 
     | 
    
         
            -
                 
     | 
| 
      
 224 
     | 
    
         
            +
                # Do not attempt to inject iframe if result is already chunked,
         
     | 
| 
      
 225 
     | 
    
         
            +
                # compressed or checksummed.
         
     | 
| 
      
 226 
     | 
    
         
            +
                (status == 200 and
         
     | 
| 
      
 227 
     | 
    
         
            +
                 headers['Content-Type'] =~ /text\/html/i and
         
     | 
| 
      
 228 
     | 
    
         
            +
                 not headers['Transfer-Encoding'] and
         
     | 
| 
      
 229 
     | 
    
         
            +
                 not headers['Content-Range'] and
         
     | 
| 
      
 230 
     | 
    
         
            +
                 not headers['Content-Encoding'] and
         
     | 
| 
      
 231 
     | 
    
         
            +
                 not headers['Content-MD5']
         
     | 
| 
      
 232 
     | 
    
         
            +
                 )
         
     | 
| 
       216 
233 
     | 
    
         
             
              end
         
     | 
| 
       217 
234 
     | 
    
         | 
| 
       218 
235 
     | 
    
         
             
              def inject_iframe(headers, body)
         
     | 
| 
       219 
     | 
    
         
            -
                 
     | 
| 
       220 
     | 
    
         
            -
                 
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
       222 
     | 
    
         
            -
                 
     | 
| 
      
 236 
     | 
    
         
            +
                total = []
         
     | 
| 
      
 237 
     | 
    
         
            +
                body.each { |part|
         
     | 
| 
      
 238 
     | 
    
         
            +
                  total << part
         
     | 
| 
      
 239 
     | 
    
         
            +
                }
         
     | 
| 
      
 240 
     | 
    
         
            +
                total = total.join()
         
     | 
| 
      
 241 
     | 
    
         
            +
                if idx = total.rindex('</body>')
         
     | 
| 
      
 242 
     | 
    
         
            +
                  total.insert(idx, @wwwhisper_iframe)
         
     | 
| 
      
 243 
     | 
    
         
            +
                  headers['Content-Length'] &&= (headers['Content-Length'].to_i +
         
     | 
| 
      
 244 
     | 
    
         
            +
                                                 @wwwhisper_iframe_bytesize).to_s
         
     | 
| 
      
 245 
     | 
    
         
            +
                end
         
     | 
| 
      
 246 
     | 
    
         
            +
                [total]
         
     | 
| 
       223 
247 
     | 
    
         
             
              end
         
     | 
| 
       224 
248 
     | 
    
         | 
| 
       225 
     | 
    
         
            -
              def  
     | 
| 
       226 
     | 
    
         
            -
                 
     | 
| 
      
 249 
     | 
    
         
            +
              def dispatch(orig_req)
         
     | 
| 
      
 250 
     | 
    
         
            +
                if orig_req.path =~ %r{^#{@@WWWHISPER_PREFIX}}
         
     | 
| 
      
 251 
     | 
    
         
            +
                  debug orig_req, "passing request to wwwhisper service #{orig_req.path}"
         
     | 
| 
       227 
252 
     | 
    
         | 
| 
       228 
     | 
    
         
            -
             
     | 
| 
       229 
     | 
    
         
            -
             
     | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
       231 
     | 
    
         
            -
             
     | 
| 
       232 
     | 
    
         
            -
             
     | 
| 
       233 
     | 
    
         
            -
             
     | 
| 
       234 
     | 
    
         
            -
                debug req, "sending auth request for #{req.path}"
         
     | 
| 
       235 
     | 
    
         
            -
                auth_status, auth_headers, auth_body = wwwhisper_auth_request(env, req)
         
     | 
| 
      
 253 
     | 
    
         
            +
                  config =
         
     | 
| 
      
 254 
     | 
    
         
            +
                    if orig_req.path =~ %r{^#{@@WWWHISPER_PREFIX}(auth|admin)/api/}
         
     | 
| 
      
 255 
     | 
    
         
            +
                      @request_config[:api]
         
     | 
| 
      
 256 
     | 
    
         
            +
                    else
         
     | 
| 
      
 257 
     | 
    
         
            +
                      @request_config[:assets]
         
     | 
| 
      
 258 
     | 
    
         
            +
                    end
         
     | 
| 
       236 
259 
     | 
    
         | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
             
     | 
| 
       239 
     | 
    
         
            -
                   
     | 
| 
       240 
     | 
    
         
            -
             
     | 
| 
       241 
     | 
    
         
            -
                   
     | 
| 
       242 
     | 
    
         
            -
                   
     | 
| 
       243 
     | 
    
         
            -
                when 401, 403
         
     | 
| 
       244 
     | 
    
         
            -
                  login_needed = (auth_status == 401)
         
     | 
| 
       245 
     | 
    
         
            -
                  debug req,  login_needed ? "user not authenticated" : "access_denied"
         
     | 
| 
       246 
     | 
    
         
            -
                  req.path_info = login_needed ? auth_login_path() : auth_denied_path()
         
     | 
| 
       247 
     | 
    
         
            -
                  status, headers, body = dispatch(env)
         
     | 
| 
       248 
     | 
    
         
            -
                  auth_headers['Content-Type'] = headers['Content-Type']
         
     | 
| 
       249 
     | 
    
         
            -
                  # TODO: only here?
         
     | 
| 
       250 
     | 
    
         
            -
                  auth_headers['Content-Encoding'] = headers['Content-Encoding']
         
     | 
| 
       251 
     | 
    
         
            -
                  [auth_status, auth_headers, body]
         
     | 
| 
      
 260 
     | 
    
         
            +
                  method = orig_req.request_method.capitalize
         
     | 
| 
      
 261 
     | 
    
         
            +
                  sub_req = sub_request_init(config, orig_req, method, orig_req.fullpath)
         
     | 
| 
      
 262 
     | 
    
         
            +
                  copy_body(orig_req, sub_req)
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                  sub_resp = config[:http].request(config[:uri], sub_req)
         
     | 
| 
      
 265 
     | 
    
         
            +
                  sub_response_to_rack(orig_req, sub_resp)
         
     | 
| 
       252 
266 
     | 
    
         
             
                else
         
     | 
| 
       253 
     | 
    
         
            -
                  debug  
     | 
| 
       254 
     | 
    
         
            -
                   
     | 
| 
      
 267 
     | 
    
         
            +
                  debug orig_req, 'passing request to Rack stack'
         
     | 
| 
      
 268 
     | 
    
         
            +
                  @app.call(orig_req.env)
         
     | 
| 
       255 
269 
     | 
    
         
             
                end
         
     | 
| 
       256 
270 
     | 
    
         
             
              end
         
     | 
| 
       257 
271 
     | 
    
         | 
| 
       258 
     | 
    
         
            -
              # TODO: more private
         
     | 
| 
       259 
     | 
    
         
            -
              private
         
     | 
| 
       260 
     | 
    
         
            -
             
     | 
| 
       261 
     | 
    
         
            -
              def debug(req, message)
         
     | 
| 
       262 
     | 
    
         
            -
                req.logger.debug "wwwhisper #{message}" if req.logger
         
     | 
| 
       263 
     | 
    
         
            -
              end
         
     | 
| 
       264 
     | 
    
         
            -
             
     | 
| 
       265 
272 
     | 
    
         
             
            end
         
     | 
| 
       266 
273 
     | 
    
         | 
| 
       267 
274 
     | 
    
         
             
            end
         
     | 
    
        data/test/test_wwwhisper.rb
    CHANGED
    
    | 
         @@ -83,31 +83,25 @@ class TestWWWhisper < Test::Unit::TestCase 
     | 
|
| 
       83 
83 
     | 
    
         
             
              def test_login_required
         
     | 
| 
       84 
84 
     | 
    
         
             
                path = '/foo/bar'
         
     | 
| 
       85 
85 
     | 
    
         
             
                stub_request(:get, full_url(@wwwhisper.auth_query(path))).
         
     | 
| 
       86 
     | 
    
         
            -
                  to_return(:status => 401, :body => '', :headers => {})
         
     | 
| 
       87 
     | 
    
         
            -
                stub_request(:get, full_assets_url(@wwwhisper.auth_login_path())).
         
     | 
| 
       88 
     | 
    
         
            -
                  to_return(:status => 200, :body => 'Login required', :headers => {})
         
     | 
| 
      
 86 
     | 
    
         
            +
                  to_return(:status => 401, :body => 'Login required', :headers => {})
         
     | 
| 
       89 
87 
     | 
    
         | 
| 
       90 
88 
     | 
    
         
             
                get path
         
     | 
| 
       91 
89 
     | 
    
         
             
                assert !last_response.ok?
         
     | 
| 
       92 
90 
     | 
    
         
             
                assert_equal 401, last_response.status
         
     | 
| 
       93 
91 
     | 
    
         
             
                assert_equal 'Login required', last_response.body
         
     | 
| 
       94 
92 
     | 
    
         
             
                assert_requested :get, full_url(@wwwhisper.auth_query(path))
         
     | 
| 
       95 
     | 
    
         
            -
                assert_requested :get, full_assets_url(@wwwhisper.auth_login_path())
         
     | 
| 
       96 
93 
     | 
    
         
             
              end
         
     | 
| 
       97 
94 
     | 
    
         | 
| 
       98 
95 
     | 
    
         
             
              def test_request_denied
         
     | 
| 
       99 
96 
     | 
    
         
             
                path = '/foo/bar'
         
     | 
| 
       100 
97 
     | 
    
         
             
                stub_request(:get, full_url(@wwwhisper.auth_query(path))).
         
     | 
| 
       101 
     | 
    
         
            -
                  to_return(:status => 403, :body => '', :headers => {})
         
     | 
| 
       102 
     | 
    
         
            -
                stub_request(:get, full_assets_url(@wwwhisper.auth_denied_path())).
         
     | 
| 
       103 
     | 
    
         
            -
                  to_return(:status => 200, :body => 'Not authorized', :headers => {})
         
     | 
| 
      
 98 
     | 
    
         
            +
                  to_return(:status => 403, :body => 'Not authorized', :headers => {})
         
     | 
| 
       104 
99 
     | 
    
         | 
| 
       105 
100 
     | 
    
         
             
                get path
         
     | 
| 
       106 
101 
     | 
    
         
             
                assert !last_response.ok?
         
     | 
| 
       107 
102 
     | 
    
         
             
                assert_equal 403, last_response.status
         
     | 
| 
       108 
103 
     | 
    
         
             
                assert_equal 'Not authorized', last_response.body
         
     | 
| 
       109 
104 
     | 
    
         
             
                assert_requested :get, full_url(@wwwhisper.auth_query(path))
         
     | 
| 
       110 
     | 
    
         
            -
                assert_requested :get, full_assets_url(@wwwhisper.auth_denied_path())
         
     | 
| 
       111 
105 
     | 
    
         
             
              end
         
     | 
| 
       112 
106 
     | 
    
         | 
| 
       113 
107 
     | 
    
         
             
              def test_iframe_injected_to_html_response
         
     | 
| 
         @@ -161,11 +155,12 @@ class TestWWWhisper < Test::Unit::TestCase 
     | 
|
| 
       161 
155 
     | 
    
         
             
                assert_requested :get, full_url(@wwwhisper.auth_query(path))
         
     | 
| 
       162 
156 
     | 
    
         
             
              end
         
     | 
| 
       163 
157 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
              def assert_path_normalized(normalized, requested)
         
     | 
| 
      
 158 
     | 
    
         
            +
              def assert_path_normalized(normalized, requested, script_name=nil)
         
     | 
| 
       165 
159 
     | 
    
         
             
                stub_request(:get, full_url(@wwwhisper.auth_query(normalized))).
         
     | 
| 
       166 
160 
     | 
    
         
             
                  to_return(:status => 200, :body => '', :headers => {})
         
     | 
| 
       167 
161 
     | 
    
         | 
| 
       168 
     | 
    
         
            -
                 
     | 
| 
      
 162 
     | 
    
         
            +
                env = script_name ? { 'SCRIPT_NAME' => script_name } : {}
         
     | 
| 
      
 163 
     | 
    
         
            +
                get(requested, {}, env)
         
     | 
| 
       169 
164 
     | 
    
         
             
                assert last_response.ok?
         
     | 
| 
       170 
165 
     | 
    
         
             
                assert_equal 'Hello World', last_response.body
         
     | 
| 
       171 
166 
     | 
    
         
             
                assert_requested :get, full_url(@wwwhisper.auth_query(normalized))
         
     | 
| 
         @@ -192,6 +187,19 @@ class TestWWWhisper < Test::Unit::TestCase 
     | 
|
| 
       192 
187 
     | 
    
         
             
                assert_path_normalized '//', '/./././/'
         
     | 
| 
       193 
188 
     | 
    
         
             
              end
         
     | 
| 
       194 
189 
     | 
    
         | 
| 
      
 190 
     | 
    
         
            +
              def test_path_normalization_with_script_name
         
     | 
| 
      
 191 
     | 
    
         
            +
                assert_path_normalized '/foo/', '/', '/foo'
         
     | 
| 
      
 192 
     | 
    
         
            +
                assert_path_normalized '/foo/bar/hello', '/bar/hello', '/foo'
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                assert_path_normalized '/baz/bar/hello', '/bar/hello', '/foo/../baz'
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                assert_path_normalized '/foo/baz/bar/hello', 'bar/hello', '/foo/./baz'
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
                # Not handled too well (see comment above).
         
     | 
| 
      
 199 
     | 
    
         
            +
                assert_path_normalized '/foo//', '/', '/foo/'
         
     | 
| 
      
 200 
     | 
    
         
            +
                assert_path_normalized '//bar/hello', '/bar/hello', '/foo/..'
         
     | 
| 
      
 201 
     | 
    
         
            +
              end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
       195 
203 
     | 
    
         
             
              def test_admin_request
         
     | 
| 
       196 
204 
     | 
    
         
             
                path = '/wwwhisper/admin/api/users/xyz'
         
     | 
| 
       197 
205 
     | 
    
         
             
                stub_request(:get, full_url(@wwwhisper.auth_query(path))).
         
     | 
| 
         @@ -218,22 +226,23 @@ class TestWWWhisper < Test::Unit::TestCase 
     | 
|
| 
       218 
226 
     | 
    
         
             
              end
         
     | 
| 
       219 
227 
     | 
    
         | 
| 
       220 
228 
     | 
    
         
             
              def test_site_url
         
     | 
| 
       221 
     | 
    
         
            -
                path = '/ 
     | 
| 
      
 229 
     | 
    
         
            +
                path = '/wwwhisper/admin/index.html'
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
       222 
231 
     | 
    
         
             
                # Site-Url header should be sent to wwwhisper backend but not to
         
     | 
| 
       223 
232 
     | 
    
         
             
                # assets server.
         
     | 
| 
       224 
233 
     | 
    
         
             
                stub_request(:get, full_url(@wwwhisper.auth_query(path))).
         
     | 
| 
       225 
234 
     | 
    
         
             
                  with(:headers => {'Site-Url' => "#{SITE_PROTO}://#{SITE_HOST}"}).
         
     | 
| 
       226 
     | 
    
         
            -
                  to_return(:status =>  
     | 
| 
       227 
     | 
    
         
            -
                stub_request(:get, full_assets_url( 
     | 
| 
      
 235 
     | 
    
         
            +
                  to_return(:status => 200, :body => '', :headers => {})
         
     | 
| 
      
 236 
     | 
    
         
            +
                stub_request(:get, full_assets_url(path)).
         
     | 
| 
       228 
237 
     | 
    
         
             
                  with { |request| request.headers['Site-Url'] == nil}.
         
     | 
| 
       229 
     | 
    
         
            -
                  to_return(:status => 200, :body => ' 
     | 
| 
      
 238 
     | 
    
         
            +
                  to_return(:status => 200, :body => 'Admin page', :headers => {})
         
     | 
| 
       230 
239 
     | 
    
         | 
| 
       231 
240 
     | 
    
         
             
                get path
         
     | 
| 
       232 
     | 
    
         
            -
                assert  
     | 
| 
       233 
     | 
    
         
            -
                assert_equal  
     | 
| 
       234 
     | 
    
         
            -
                assert_equal ' 
     | 
| 
      
 241 
     | 
    
         
            +
                assert last_response.ok?
         
     | 
| 
      
 242 
     | 
    
         
            +
                assert_equal 200, last_response.status
         
     | 
| 
      
 243 
     | 
    
         
            +
                assert_equal 'Admin page', last_response.body
         
     | 
| 
       235 
244 
     | 
    
         
             
                assert_requested :get, full_url(@wwwhisper.auth_query(path))
         
     | 
| 
       236 
     | 
    
         
            -
                assert_requested :get, full_assets_url( 
     | 
| 
      
 245 
     | 
    
         
            +
                assert_requested :get, full_assets_url(path)
         
     | 
| 
       237 
246 
     | 
    
         
             
              end
         
     | 
| 
       238 
247 
     | 
    
         | 
| 
       239 
248 
     | 
    
         
             
              def test_site_url_with_non_default_port
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: rack-wwwhisper
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1.0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.0.2.pre
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 6
         
     | 
| 
       6 
6 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       7 
7 
     | 
    
         
             
            authors:
         
     | 
| 
         @@ -9,7 +9,7 @@ authors: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       10 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
     | 
    
         
            -
            date: 2013-01- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2013-01-11 00:00:00.000000000 Z
         
     | 
| 
       13 
13 
     | 
    
         
             
            dependencies:
         
     | 
| 
       14 
14 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       15 
15 
     | 
    
         
             
              name: rack
         
     | 
| 
         @@ -129,6 +129,9 @@ required_ruby_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       129 
129 
     | 
    
         
             
              - - ! '>='
         
     | 
| 
       130 
130 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       131 
131 
     | 
    
         
             
                  version: '0'
         
     | 
| 
      
 132 
     | 
    
         
            +
                  segments:
         
     | 
| 
      
 133 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 134 
     | 
    
         
            +
                  hash: 3933889389209313993
         
     | 
| 
       132 
135 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       133 
136 
     | 
    
         
             
              none: false
         
     | 
| 
       134 
137 
     | 
    
         
             
              requirements:
         
     |