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(opts = {}) ⇒ Redirector

Returns a new instance of Redirector.

Parameters:

  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :strict (Boolean) — default: true

    redirector hops policy

  • :max_hops (#to_i) — default: 5

    maximum allowed amount of hops



40
41
42
43
# File 'lib/http/redirector.rb', line 40

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

Instance Attribute Details

#max_hopsObject (readonly)

Returns the value of attribute max_hops.



35
36
37
# File 'lib/http/redirector.rb', line 35

def max_hops
  @max_hops
end

#strictObject (readonly)

Returns the value of attribute strict.



30
31
32
# File 'lib/http/redirector.rb', line 30

def strict
  @strict
end

Instance Method Details

#perform(request, response) ⇒ Object

Follows redirects until non-redirect response found



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

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[Headers::LOCATION]
    @response = yield @request
  end

  @response
end