Class: Async::HTTP::RelativeLocation

Inherits:
Middleware 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'.freeze

Instance Attribute Summary collapse

Attributes inherited from Middleware

#delegate

Instance Method Summary collapse

Methods inherited from Middleware

build, #close

Constructor Details

#initialize(app, maximum_hops = 4) ⇒ RelativeLocation

Returns a new instance of RelativeLocation.



32
33
34
35
36
# File 'lib/async/http/relative_location.rb', line 32

def initialize(app, maximum_hops = 4)
	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.



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

def maximum_hops
  @maximum_hops
end

Instance Method Details

#call(request) ⇒ Object

Raises:

  • (ArgumentError)


41
42
43
44
45
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
# File 'lib/async/http/relative_location.rb', line 41

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)
		hops += 1
			
		if response.redirection?
			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 ArgumentError, "Redirected #{hops} times, exceeded maximum!"
end