Class: Sus::Fixtures::Protocol::HTTP::Client

Inherits:
Protocol::HTTP::Middleware
  • Object
show all
Defined in:
lib/sus/fixtures/protocol/http/client.rb

Overview

An in-process client for exercising protocol HTTP middleware.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(delegate, scheme: "http", authority: "localhost") ⇒ Client

Initialize the client.



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/sus/fixtures/protocol/http/client.rb', line 22

def initialize(delegate, scheme: "http", authority: "localhost")
	super(delegate)
	
	@scheme = scheme
	@authority = authority
	
	@headers = {}
	@cookies = {}
	@closed = false
	@exchange_closed = true
end

Instance Attribute Details

#authorityObject (readonly)

Returns the value of attribute authority.



38
39
40
# File 'lib/sus/fixtures/protocol/http/client.rb', line 38

def authority
  @authority
end

#cookiesObject (readonly)

Returns the value of attribute cookies.



44
45
46
# File 'lib/sus/fixtures/protocol/http/client.rb', line 44

def cookies
  @cookies
end

#Cookies retained between requests.(retainedbetweenrequests.) ⇒ Object (readonly)



44
# File 'lib/sus/fixtures/protocol/http/client.rb', line 44

attr :cookies

#headersObject (readonly)

Returns the value of attribute headers.



41
42
43
# File 'lib/sus/fixtures/protocol/http/client.rb', line 41

def headers
  @headers
end

#Headers added to every request.(addedtoeveryrequest.) ⇒ Object (readonly)



41
# File 'lib/sus/fixtures/protocol/http/client.rb', line 41

attr :headers

#last_requestObject (readonly)

Returns the value of attribute last_request.



47
48
49
# File 'lib/sus/fixtures/protocol/http/client.rb', line 47

def last_request
  @last_request
end

#last_responseObject (readonly)

Returns the value of attribute last_response.



50
51
52
# File 'lib/sus/fixtures/protocol/http/client.rb', line 50

def last_response
  @last_response
end

#schemeObject (readonly)

Returns the value of attribute scheme.



35
36
37
# File 'lib/sus/fixtures/protocol/http/client.rb', line 35

def scheme
  @scheme
end

#The default request authority.(defaultrequestauthority.) ⇒ Object (readonly)



38
# File 'lib/sus/fixtures/protocol/http/client.rb', line 38

attr :authority

#The default request scheme.(defaultrequestscheme.) ⇒ Object (readonly)



35
# File 'lib/sus/fixtures/protocol/http/client.rb', line 35

attr :scheme

#The most recent request.(mostrecentrequest.) ⇒ Object (readonly)



47
# File 'lib/sus/fixtures/protocol/http/client.rb', line 47

attr :last_request

#The most recent response.(mostrecentresponse.) ⇒ Object (readonly)



50
# File 'lib/sus/fixtures/protocol/http/client.rb', line 50

attr :last_response

Instance Method Details

#call(request) ⇒ Object

Perform a prepared request against the application.



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/sus/fixtures/protocol/http/client.rb', line 100

def call(request)
	if @closed
		raise IOError, "Client is closed!"
	end
	
	self.close_exchange
	self.prepare_request(request)
	
	@last_request = request
	@last_response = nil
	@exchange_closed = false
	
	begin
		@last_response = super(request)
		self.store_cookies(@last_response.headers["set-cookie"])
		
		return @last_response
	rescue => error
		self.close_exchange(error)
		raise
	end
end

#close(error = nil) ⇒ Object

Close the current exchange and application.



172
173
174
175
176
177
178
179
180
181
182
# File 'lib/sus/fixtures/protocol/http/client.rb', line 172

def close(error = nil)
	return if @closed
	
	@closed = true
	
	begin
		self.close_exchange(error)
	ensure
		super()
	end
end

#follow_redirect!Object

Follow the location in the most recent redirect response.

Statuses 307 and 308 preserve the original method and body. Other redirects use GET, except that HEAD remains HEAD.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/sus/fixtures/protocol/http/client.rb', line 128

def follow_redirect!
	response = @last_response
	request = @last_request
	
	unless response&.redirection?
		raise RuntimeError, "The last response is not a redirect!"
	end
	
	location = response.headers["location"]
	unless location
		raise RuntimeError, "The redirect response has no location!"
	end
	
	base = "#{request.scheme}://#{request.authority}#{request.path}"
	target = ::URI.join(base, location.to_s)
	
	if response.preserve_method?
		if @request_had_body && !@replay_body
			raise IOError, "The request body cannot be replayed!"
		end
		
		method = request.method
		body = @replay_body
	elsif request.head?
		method = ::Protocol::HTTP::Methods::HEAD
		body = nil
	else
		method = ::Protocol::HTTP::Methods::GET
		body = nil
	end
	
	return self.request(
		method,
		target.request_uri,
		nil,
		body,
		scheme: target.scheme,
		authority: target.authority,
	)
end

#header(name, value) ⇒ Object

Set a default request header.



56
57
58
# File 'lib/sus/fixtures/protocol/http/client.rb', line 56

def header(name, value)
	@headers[name.downcase] = value
end

#request(method, path, headers = nil, body = nil, **options) ⇒ Object

Construct and perform a request.



90
91
92
93
94
# File 'lib/sus/fixtures/protocol/http/client.rb', line 90

def request(method, path, headers = nil, body = nil, **options)
	return self.call(
		::Protocol::HTTP::Request[method, path, headers, body, **options]
	)
end

Store a cookie for subsequent requests.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/sus/fixtures/protocol/http/client.rb', line 63

def set_cookie(value)
	case value
	when String
		cookie = ::Protocol::HTTP::Cookie.parse(value)
	when ::Protocol::HTTP::Cookie
		cookie = value
	else
		raise ArgumentError, "Unsupported cookie: #{value.inspect}"
	end
	
	if cookie.value
		@cookies[cookie.name] = cookie.value
	else
		@cookies.delete(cookie.name)
	end
	
	return cookie
end