Class: Async::HTTP::RelativeLocation

Inherits:
Protocol::HTTP::Middleware
  • Object
show all
Defined in:
lib/async/http/relative_location.rb

Overview

A client wrapper which transparently handles both relative and absolute redirects to a given maximum number of hops.

Constant Summary collapse

DEFAULT_METHOD =
GET

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, maximum_hops = 3) ⇒ RelativeLocation

maximum_hops is the max number of redirects. Set to 0 to allow 1 request with no redirects.



37
38
39
40
41
# File 'lib/async/http/relative_location.rb', line 37

def initialize(app, maximum_hops = 3)
  super(app)
  
  @maximum_hops = maximum_hops
end

Instance Attribute Details

#maximum_hopsObject (readonly)

The maximum number of hops which will limit the number of redirects until an error is thrown.



44
45
46
# File 'lib/async/http/relative_location.rb', line 44

def maximum_hops
  @maximum_hops
end

Instance Method Details

#call(request) ⇒ Object

Raises:



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/async/http/relative_location.rb', line 46

def call(request)
  hops = 0
  
  # We need to cache the body as it might be submitted multiple times.
  request.finish
  
  while hops <= @maximum_hops
    response = super(request)

    if response.redirection?
      hops += 1
      response.finish
      
      location = response.headers['location']
      uri = URI.parse(location)
      
      if uri.absolute?
        return response
      else
        request.path = Reference[request.path] + location
      end
      
      unless response.preserve_method?
        request.method = DEFAULT_METHOD
      end
    else
      return response
    end
  end
  
  raise TooManyRedirects, "Redirected #{hops} times, exceeded maximum!"
end