Class: HTTP::Redirector

Inherits:
Object
  • Object
show all
Defined in:
lib/http/redirector.rb

Defined Under Namespace

Classes: EndlessRedirectError, TooManyRedirectsError

Constant Summary collapse

REDIRECT_CODES =

HTTP status codes which indicate redirects

[300, 301, 302, 303, 307, 308].to_set.freeze
STRICT_SENSITIVE_CODES =

Codes which which should raise StateError in strict mode if original request was any of UNSAFE_VERBS

[300, 301, 302].to_set.freeze
UNSAFE_VERBS =

Insecure http verbs, which should trigger StateError in strict mode upon STRICT_SENSITIVE_CODES

[:put, :delete, :post].to_set.freeze
SEE_OTHER_ALLOWED_VERBS =

Verbs which will remain unchanged upon See Other response.

[:get, :head].to_set.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Redirector

Returns a new instance of Redirector.

Parameters:

  • opts (Hash)


38
39
40
41
# File 'lib/http/redirector.rb', line 38

def initialize(options = {})
  @strict   = options.fetch(:strict, true)
  @max_hops = options.fetch(:max_hops, 5).to_i
end

Instance Attribute Details

#max_hopsObject (readonly)

Returns the value of attribute max_hops.



33
34
35
# File 'lib/http/redirector.rb', line 33

def max_hops
  @max_hops
end

#strictObject (readonly)

Returns the value of attribute strict.



28
29
30
# File 'lib/http/redirector.rb', line 28

def strict
  @strict
end

Instance Method Details

#perform(request, response) ⇒ Object

Follows redirects until non-redirect response found



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/http/redirector.rb', line 44

def perform(request, response)
  @request  = request
  @response = response
  @visited  = []

  while REDIRECT_CODES.include? @response.status.code
    @visited << "#{@request.verb} #{@request.uri}"

    fail TooManyRedirectsError if too_many_hops?
    fail EndlessRedirectError  if endless_loop?

    @request  = redirect_to @response.headers["Location"]
    @response = yield @request
  end

  @response
end