Class: HTTP::Session::Redirector

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

Overview

Mostly borrowed from http/lib/http/redirector.rb

Constant Summary collapse

REDIRECT_CODES =

HTTP status codes which indicate redirects

HTTP::Redirector::REDIRECT_CODES
STRICT_SENSITIVE_CODES =

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

HTTP::Redirector::STRICT_SENSITIVE_CODES
UNSAFE_VERBS =

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

HTTP::Redirector::UNSAFE_VERBS
SEE_OTHER_ALLOWED_VERBS =

Verbs which will remain unchanged upon See Other response.

HTTP::Redirector::SEE_OTHER_ALLOWED_VERBS

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



21
22
23
24
25
# File 'lib/http/session/redirector.rb', line 21

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

Instance Method Details

#perform(response, &blk) ⇒ Object



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
# File 'lib/http/session/redirector.rb', line 27

def perform(response, &blk)
  request = response.request
  visited = []
  history = []

  while REDIRECT_CODES.include?(response.status.code)
    history << response
    visited << "#{request.verb} #{request.uri}"
    raise HTTP::Session::Exceptions::RedirectError, "too many hops" if too_many_hops?(visited)
    raise HTTP::Session::Exceptions::RedirectError, "endless loop" if endless_loop?(visited)

    location = response.headers.get(HTTP::Headers::LOCATION).inject(:+)
    raise HTTP::Session::Exceptions::RedirectError, "no Location header in redirect" unless location

    verb = make_redirect_to_verb(response, request)
    uri = make_redirect_to_uri(response, request, location)
    ctx = make_redirect_to_ctx(response, request, verb, uri)

    @on_redirect.call(response, request) if @on_redirect.respond_to?(:call)
    response = blk.call(verb, uri, ctx)
    request = response.request
  end

  response.history = history
  response
end