patient_http 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ARCHITECTURE.md +8 -7
- data/CHANGELOG.md +29 -0
- data/README.md +539 -515
- data/VERSION +1 -1
- data/lib/patient_http/callback_args.rb +53 -48
- data/lib/patient_http/callback_validator.rb +11 -7
- data/lib/patient_http/class_helper.rb +6 -7
- data/lib/patient_http/client.rb +28 -22
- data/lib/patient_http/client_pool.rb +134 -39
- data/lib/patient_http/completion_executor.rb +20 -20
- data/lib/patient_http/configuration.rb +367 -119
- data/lib/patient_http/connection_endpoint.rb +150 -0
- data/lib/patient_http/encryptor.rb +28 -18
- data/lib/patient_http/error.rb +24 -18
- data/lib/patient_http/external_storage.rb +42 -38
- data/lib/patient_http/http_error.rb +30 -26
- data/lib/patient_http/http_headers.rb +35 -29
- data/lib/patient_http/immediate_retries.rb +98 -0
- data/lib/patient_http/inline_task_handler.rb +15 -10
- data/lib/patient_http/lifecycle_manager.rb +39 -40
- data/lib/patient_http/outgoing_request.rb +25 -23
- data/lib/patient_http/payload.rb +28 -26
- data/lib/patient_http/payload_store/active_record_store.rb +31 -34
- data/lib/patient_http/payload_store/base.rb +42 -46
- data/lib/patient_http/payload_store/file_store.rb +22 -26
- data/lib/patient_http/payload_store/redis_store.rb +28 -34
- data/lib/patient_http/payload_store/s3_store.rb +25 -28
- data/lib/patient_http/payload_store.rb +2 -0
- data/lib/patient_http/processor.rb +111 -79
- data/lib/patient_http/processor_observer.rb +65 -59
- data/lib/patient_http/rails/engine.rb +13 -8
- data/lib/patient_http/redirect_error.rb +50 -41
- data/lib/patient_http/redirect_helper.rb +38 -38
- data/lib/patient_http/request.rb +70 -46
- data/lib/patient_http/request_error.rb +47 -42
- data/lib/patient_http/request_helper.rb +142 -119
- data/lib/patient_http/request_preparer.rb +13 -10
- data/lib/patient_http/request_task.rb +113 -84
- data/lib/patient_http/request_template.rb +87 -64
- data/lib/patient_http/response.rb +58 -52
- data/lib/patient_http/response_reader.rb +66 -65
- data/lib/patient_http/secret_manager.rb +34 -30
- data/lib/patient_http/secret_reference.rb +33 -26
- data/lib/patient_http/synchronous_executor.rb +67 -95
- data/lib/patient_http/task_handler.rb +23 -19
- data/lib/patient_http/time_helper.rb +8 -8
- data/lib/patient_http.rb +311 -186
- data/patient_http.gemspec +3 -2
- metadata +21 -5
|
@@ -1,57 +1,77 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module PatientHttp
|
|
4
|
-
# A
|
|
5
|
-
#
|
|
6
|
-
#
|
|
4
|
+
# A {Request} with the callback service and the task handler that the
|
|
5
|
+
# processor needs to run it. The task tracks the request from enqueue to
|
|
6
|
+
# completion, and delivers the result through its task handler.
|
|
7
|
+
#
|
|
8
|
+
# @example Create a task and enqueue it
|
|
9
|
+
# task = PatientHttp::RequestTask.new(
|
|
10
|
+
# request: PatientHttp::Request.new(:get, "https://api.example.com/users/123"),
|
|
11
|
+
# task_handler: MyTaskHandler.new("job-123"),
|
|
12
|
+
# callback: "FetchUserCallback",
|
|
13
|
+
# callback_args: {user_id: 123}
|
|
14
|
+
# )
|
|
15
|
+
# processor.enqueue(task)
|
|
7
16
|
class RequestTask
|
|
8
17
|
include TimeHelper
|
|
9
18
|
|
|
10
|
-
#
|
|
19
|
+
# The headers that are removed on a cross-origin redirect.
|
|
11
20
|
SENSITIVE_HEADERS = %w[authorization cookie].freeze
|
|
12
21
|
|
|
13
|
-
#
|
|
22
|
+
# The headers that describe a request body. They're removed when a redirect
|
|
23
|
+
# drops the body.
|
|
14
24
|
BODY_HEADERS = %w[content-type content-length content-encoding content-language content-location].freeze
|
|
15
25
|
|
|
16
|
-
# @return [String]
|
|
26
|
+
# @return [String] The unique task ID. A task that follows a redirect has
|
|
27
|
+
# the ID of the original task with a suffix.
|
|
17
28
|
attr_reader :id
|
|
18
29
|
|
|
19
|
-
# @return [Request] The HTTP request
|
|
30
|
+
# @return [Request] The HTTP request.
|
|
20
31
|
attr_reader :request
|
|
21
32
|
|
|
22
|
-
# @return [TaskHandler] The handler
|
|
33
|
+
# @return [TaskHandler] The task handler that delivers the result.
|
|
23
34
|
attr_reader :task_handler
|
|
24
35
|
|
|
25
|
-
# @return [String]
|
|
36
|
+
# @return [String] The callback service class name.
|
|
26
37
|
attr_reader :callback
|
|
27
38
|
|
|
28
|
-
# @return [Hash]
|
|
39
|
+
# @return [Hash] The callback arguments for the {Response} or {Error}. Never
|
|
40
|
+
# `nil`.
|
|
29
41
|
attr_reader :callback_args
|
|
30
42
|
|
|
31
|
-
# @return [Boolean] Whether
|
|
43
|
+
# @return [Boolean] Whether non-2xx responses go to the `on_error` callback
|
|
44
|
+
# as an {HttpError}.
|
|
32
45
|
attr_reader :raise_error_responses
|
|
33
46
|
|
|
34
|
-
# @return [Array<String>] URLs
|
|
47
|
+
# @return [Array<String>] The URLs of the redirects that were followed.
|
|
35
48
|
attr_reader :redirects
|
|
36
49
|
|
|
37
|
-
# @return [Response, nil] The HTTP response,
|
|
50
|
+
# @return [Response, nil] The HTTP response, after the request succeeds.
|
|
38
51
|
attr_reader :response
|
|
39
52
|
|
|
40
|
-
# @return [Exception, nil] The error,
|
|
53
|
+
# @return [Exception, nil] The error, after the request fails.
|
|
41
54
|
attr_reader :error
|
|
42
55
|
|
|
43
|
-
#
|
|
56
|
+
# Creates a task.
|
|
44
57
|
#
|
|
45
|
-
# @param request [Request] The HTTP request
|
|
46
|
-
# @param task_handler [TaskHandler] The handler
|
|
47
|
-
#
|
|
48
|
-
# @param
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
# @param
|
|
53
|
-
#
|
|
54
|
-
# @param
|
|
58
|
+
# @param request [Request] The HTTP request.
|
|
59
|
+
# @param task_handler [TaskHandler] The task handler that delivers the
|
|
60
|
+
# result.
|
|
61
|
+
# @param callback [String, Class] The callback service class, or its name.
|
|
62
|
+
# @param callback_args [Hash] The JSON-compatible arguments to pass to the
|
|
63
|
+
# callback. The callback reads them from `response.callback_args` or
|
|
64
|
+
# `error.callback_args`.
|
|
65
|
+
# @param raise_error_responses [Boolean] Whether non-2xx responses go to the
|
|
66
|
+
# `on_error` callback as an {HttpError}.
|
|
67
|
+
# @param redirects [Array<String>] The URLs of the redirects that were
|
|
68
|
+
# followed.
|
|
69
|
+
# @param id [String, nil] The unique task ID. If `nil`, a new UUID is
|
|
70
|
+
# generated.
|
|
71
|
+
# @param default_max_redirects [Integer] The maximum number of redirects to
|
|
72
|
+
# follow if the request doesn't set one.
|
|
73
|
+
# @raise [ArgumentError] If a required argument is missing, or if the
|
|
74
|
+
# callback service or callback arguments aren't valid.
|
|
55
75
|
def initialize(
|
|
56
76
|
request:,
|
|
57
77
|
task_handler:,
|
|
@@ -83,74 +103,81 @@ module PatientHttp
|
|
|
83
103
|
CallbackValidator.validate!(@callback)
|
|
84
104
|
end
|
|
85
105
|
|
|
86
|
-
#
|
|
106
|
+
# Records the time that the task was enqueued.
|
|
107
|
+
#
|
|
87
108
|
# @return [void]
|
|
88
109
|
def enqueued!
|
|
89
110
|
@enqueued_at = monotonic_time
|
|
90
111
|
end
|
|
91
112
|
|
|
92
|
-
#
|
|
113
|
+
# Records the time that the request started.
|
|
114
|
+
#
|
|
93
115
|
# @return [void]
|
|
94
116
|
def started!
|
|
95
117
|
@started_at = monotonic_time
|
|
96
118
|
end
|
|
97
119
|
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
# balanced when a task is re-enqueued during shutdown.
|
|
120
|
+
# Returns whether the request started. The processor uses this value to
|
|
121
|
+
# send `request_end` to observers only for tasks that got `request_start`.
|
|
101
122
|
#
|
|
102
|
-
# @return [Boolean]
|
|
123
|
+
# @return [Boolean] `true` if {#started!} was called.
|
|
103
124
|
def started?
|
|
104
125
|
!@started_at.nil?
|
|
105
126
|
end
|
|
106
127
|
|
|
107
|
-
# Returns the
|
|
128
|
+
# Returns the time that the task was enqueued.
|
|
108
129
|
#
|
|
109
|
-
# @return [Time, nil] The
|
|
130
|
+
# @return [Time, nil] The time, or `nil` if the task isn't enqueued.
|
|
110
131
|
def enqueued_at
|
|
111
132
|
wall_clock_time(@enqueued_at) if @enqueued_at
|
|
112
133
|
end
|
|
113
134
|
|
|
114
|
-
# Returns the
|
|
135
|
+
# Returns the time that the request started.
|
|
115
136
|
#
|
|
116
|
-
# @return [Time, nil] The
|
|
137
|
+
# @return [Time, nil] The time, or `nil` if the request didn't start.
|
|
117
138
|
def started_at
|
|
118
139
|
wall_clock_time(@started_at) if @started_at
|
|
119
140
|
end
|
|
120
141
|
|
|
121
|
-
# Returns the
|
|
142
|
+
# Returns the time that the request finished.
|
|
122
143
|
#
|
|
123
|
-
# @return [Time, nil] The
|
|
144
|
+
# @return [Time, nil] The time, or `nil` if the request didn't finish.
|
|
124
145
|
def completed_at
|
|
125
146
|
wall_clock_time(@completed_at) if @completed_at
|
|
126
147
|
end
|
|
127
148
|
|
|
128
|
-
#
|
|
129
|
-
#
|
|
149
|
+
# Returns the time that the task waited in the queue before the request
|
|
150
|
+
# started.
|
|
151
|
+
#
|
|
152
|
+
# @return [Float, nil] The duration in seconds, or `nil` if the task isn't
|
|
153
|
+
# enqueued.
|
|
130
154
|
def enqueued_duration
|
|
131
155
|
return nil unless @enqueued_at
|
|
132
156
|
|
|
133
157
|
(@started_at || monotonic_time) - @enqueued_at
|
|
134
158
|
end
|
|
135
159
|
|
|
136
|
-
#
|
|
137
|
-
#
|
|
160
|
+
# Returns the time that the request ran.
|
|
161
|
+
#
|
|
162
|
+
# @return [Float, nil] The duration in seconds, or `nil` if the request
|
|
163
|
+
# didn't start.
|
|
138
164
|
def duration
|
|
139
165
|
return nil unless @started_at
|
|
140
166
|
|
|
141
167
|
((@completed_at || monotonic_time) - @started_at).round(9)
|
|
142
168
|
end
|
|
143
169
|
|
|
144
|
-
# Re-
|
|
145
|
-
#
|
|
170
|
+
# Re-enqueues the original job through the task handler.
|
|
171
|
+
#
|
|
172
|
+
# @return [String] The new job ID.
|
|
146
173
|
def retry
|
|
147
174
|
@task_handler.retry
|
|
148
175
|
end
|
|
149
176
|
|
|
150
|
-
#
|
|
151
|
-
#
|
|
177
|
+
# Records the response, and delivers it through the task handler. The
|
|
178
|
+
# response can have an HTTP error status (4xx or 5xx).
|
|
152
179
|
#
|
|
153
|
-
# @param response [Response]
|
|
180
|
+
# @param response [Response] The HTTP response.
|
|
154
181
|
# @return [void]
|
|
155
182
|
def completed!(response)
|
|
156
183
|
@completed_at = monotonic_time
|
|
@@ -159,9 +186,10 @@ module PatientHttp
|
|
|
159
186
|
@task_handler.on_complete(response, @callback)
|
|
160
187
|
end
|
|
161
188
|
|
|
162
|
-
#
|
|
189
|
+
# Records the error, and delivers it through the task handler. An exception
|
|
190
|
+
# that isn't an {Error} is wrapped in a {RequestError}.
|
|
163
191
|
#
|
|
164
|
-
# @param exception [Exception]
|
|
192
|
+
# @param exception [Exception] The error.
|
|
165
193
|
# @return [void]
|
|
166
194
|
def error!(exception)
|
|
167
195
|
@completed_at = monotonic_time
|
|
@@ -182,45 +210,45 @@ module PatientHttp
|
|
|
182
210
|
@task_handler.on_error(wrapped_error, @callback)
|
|
183
211
|
end
|
|
184
212
|
|
|
185
|
-
#
|
|
186
|
-
#
|
|
213
|
+
# Returns whether the server sent a response. The response can have an HTTP
|
|
214
|
+
# error status (4xx or 5xx).
|
|
187
215
|
#
|
|
188
|
-
# @return [Boolean]
|
|
216
|
+
# @return [Boolean] `true` if a response was received.
|
|
189
217
|
def success?
|
|
190
218
|
!@response.nil?
|
|
191
219
|
end
|
|
192
220
|
|
|
193
|
-
#
|
|
221
|
+
# Returns whether the request raised an error.
|
|
194
222
|
#
|
|
195
|
-
# @return [Boolean]
|
|
223
|
+
# @return [Boolean] `true` if the request failed.
|
|
196
224
|
def error?
|
|
197
225
|
!@error.nil?
|
|
198
226
|
end
|
|
199
227
|
|
|
200
|
-
# Returns the maximum number of redirects to follow.
|
|
201
|
-
#
|
|
228
|
+
# Returns the maximum number of redirects to follow. The request value
|
|
229
|
+
# applies if it's set. Otherwise, the default applies.
|
|
202
230
|
#
|
|
203
|
-
# @return [Integer] maximum number of redirects
|
|
231
|
+
# @return [Integer] The maximum number of redirects.
|
|
204
232
|
def max_redirects
|
|
205
233
|
request.max_redirects || @default_max_redirects
|
|
206
234
|
end
|
|
207
235
|
|
|
208
|
-
#
|
|
236
|
+
# Creates a task that follows a redirect.
|
|
209
237
|
#
|
|
210
|
-
# The HTTP method follows RFC 9110
|
|
211
|
-
# changes
|
|
212
|
-
#
|
|
213
|
-
#
|
|
238
|
+
# The HTTP method follows RFC 9110. A 301 or 302 changes POST to GET. A 303
|
|
239
|
+
# changes all methods except GET and HEAD to GET. A 300, 307, or 308 keeps
|
|
240
|
+
# the method. When the method changes, the body and the headers that
|
|
241
|
+
# describe it are removed.
|
|
214
242
|
#
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
# headers and preprocessors are removed
|
|
243
|
+
# The headers named in the request's `redirect_strip_headers` or in
|
|
244
|
+
# `strip_headers` are removed. On a cross-origin redirect, the
|
|
245
|
+
# `Authorization` and `Cookie` headers and the preprocessors are removed.
|
|
218
246
|
#
|
|
219
|
-
# @param location [String] The
|
|
220
|
-
# @param status [Integer] The HTTP status
|
|
221
|
-
# @param strip_headers [Array<String>]
|
|
222
|
-
#
|
|
223
|
-
# @return [RequestTask]
|
|
247
|
+
# @param location [String] The URL from the `Location` header.
|
|
248
|
+
# @param status [Integer] The HTTP status of the redirect response.
|
|
249
|
+
# @param strip_headers [Array<String>] More header names to remove, usually
|
|
250
|
+
# from the {Configuration}.
|
|
251
|
+
# @return [RequestTask] The task for the redirect.
|
|
224
252
|
def redirect_task(location:, status:, strip_headers: [])
|
|
225
253
|
redirect_method = RedirectHelper.redirect_method(request.http_method, status)
|
|
226
254
|
method_changed = (redirect_method != request.http_method)
|
|
@@ -268,12 +296,12 @@ module PatientHttp
|
|
|
268
296
|
)
|
|
269
297
|
end
|
|
270
298
|
|
|
271
|
-
#
|
|
299
|
+
# Builds a {Response} for this task.
|
|
272
300
|
#
|
|
273
|
-
# @param status [Integer] HTTP status code
|
|
274
|
-
# @param headers [Hash]
|
|
275
|
-
# @param body [String, nil]
|
|
276
|
-
# @return [Response]
|
|
301
|
+
# @param status [Integer] The HTTP status code.
|
|
302
|
+
# @param headers [Hash] The response headers.
|
|
303
|
+
# @param body [String, nil] The response body.
|
|
304
|
+
# @return [Response] The response.
|
|
277
305
|
# @api private
|
|
278
306
|
def build_response(status:, headers:, body:)
|
|
279
307
|
original_id = id.split("/").first
|
|
@@ -291,21 +319,22 @@ module PatientHttp
|
|
|
291
319
|
)
|
|
292
320
|
end
|
|
293
321
|
|
|
294
|
-
#
|
|
295
|
-
#
|
|
322
|
+
# Returns the ID of the first task, before any redirects. Use it to track a
|
|
323
|
+
# request across its redirect tasks.
|
|
296
324
|
#
|
|
297
|
-
# @return [String]
|
|
325
|
+
# @return [String] The original task ID.
|
|
298
326
|
def original_id
|
|
299
327
|
id.split("/").first
|
|
300
328
|
end
|
|
301
329
|
|
|
302
330
|
private
|
|
303
331
|
|
|
304
|
-
#
|
|
332
|
+
# Returns whether two URLs have different origins. The origin is the
|
|
333
|
+
# scheme, host, and port.
|
|
305
334
|
#
|
|
306
|
-
# @param original_url [String] The original request URL
|
|
307
|
-
# @param target_url [String] The redirect
|
|
308
|
-
# @return [Boolean] true if the origins
|
|
335
|
+
# @param original_url [String] The original request URL.
|
|
336
|
+
# @param target_url [String] The redirect URL.
|
|
337
|
+
# @return [Boolean] `true` if the origins are different.
|
|
309
338
|
def cross_origin?(original_url, target_url)
|
|
310
339
|
original = URI.parse(original_url)
|
|
311
340
|
target = URI.parse(target_url)
|
|
@@ -315,10 +344,10 @@ module PatientHttp
|
|
|
315
344
|
original.port != target.port
|
|
316
345
|
end
|
|
317
346
|
|
|
318
|
-
#
|
|
347
|
+
# Resolves a redirect URL. A relative URL is joined with the request URL.
|
|
319
348
|
#
|
|
320
|
-
# @param location [String] The Location header value
|
|
321
|
-
# @return [String] The
|
|
349
|
+
# @param location [String] The `Location` header value.
|
|
350
|
+
# @return [String] The absolute URL.
|
|
322
351
|
def resolve_redirect_url(location)
|
|
323
352
|
base_uri = URI.parse(request.url)
|
|
324
353
|
redirect_uri = URI.parse(location)
|
|
@@ -1,41 +1,45 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module PatientHttp
|
|
4
|
-
#
|
|
4
|
+
# Builds requests that share settings, such as a base URL, headers, and a
|
|
5
|
+
# timeout. Use a template to make many requests to the same API.
|
|
5
6
|
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
7
|
+
# The template joins each path with the base URL, and merges the headers and
|
|
8
|
+
# query parameters of each request with its own.
|
|
8
9
|
#
|
|
9
|
-
# @example
|
|
10
|
+
# @example Build a request
|
|
10
11
|
# template = PatientHttp::RequestTemplate.new(
|
|
11
12
|
# base_url: "https://api.example.com",
|
|
12
13
|
# headers: {"Authorization" => "Bearer token"},
|
|
13
14
|
# timeout: 60
|
|
14
15
|
# )
|
|
15
16
|
# request = template.get("/users/123")
|
|
16
|
-
#
|
|
17
|
-
# The RequestTemplate handles building HTTP requests with proper URL joining, header merging,
|
|
18
|
-
# and parameter encoding.
|
|
17
|
+
# PatientHttp.execute(request: request, callback: FetchUserCallback)
|
|
19
18
|
class RequestTemplate
|
|
20
|
-
# @return [String, URI::HTTP, nil]
|
|
19
|
+
# @return [String, URI::HTTP, nil] The base URL that relative paths are
|
|
20
|
+
# joined with.
|
|
21
21
|
attr_accessor :base_url
|
|
22
22
|
|
|
23
|
-
# @return [HttpHeaders]
|
|
23
|
+
# @return [HttpHeaders] The default headers for all requests.
|
|
24
24
|
attr_accessor :headers
|
|
25
25
|
|
|
26
|
-
# @return [
|
|
26
|
+
# @return [Numeric, nil] The default request timeout in seconds. If `nil`,
|
|
27
|
+
# the configured `request_timeout` applies.
|
|
27
28
|
attr_accessor :timeout
|
|
28
29
|
|
|
29
|
-
#
|
|
30
|
+
# Creates a template.
|
|
30
31
|
#
|
|
31
|
-
# @param base_url [String, URI::HTTP, nil]
|
|
32
|
-
#
|
|
33
|
-
# @param
|
|
34
|
-
# @param
|
|
35
|
-
# @param
|
|
36
|
-
#
|
|
37
|
-
# @param
|
|
38
|
-
|
|
32
|
+
# @param base_url [String, URI::HTTP, nil] The base URL that relative paths
|
|
33
|
+
# are joined with.
|
|
34
|
+
# @param headers [Hash] The default headers for all requests.
|
|
35
|
+
# @param params [Hash, nil] The default query parameters for all requests.
|
|
36
|
+
# @param timeout [Numeric, nil] The default request timeout in seconds. If
|
|
37
|
+
# `nil`, the configured `request_timeout` applies.
|
|
38
|
+
# @param preprocessors [String, Symbol, Array<String, Symbol>, nil] The names
|
|
39
|
+
# of the default preprocessors for all requests.
|
|
40
|
+
# @param processor [String, Symbol, nil] The name of the default processor for
|
|
41
|
+
# all requests.
|
|
42
|
+
def initialize(base_url: nil, headers: {}, params: nil, timeout: nil, preprocessors: nil, processor: nil)
|
|
39
43
|
@base_url = base_url
|
|
40
44
|
@headers = HttpHeaders.new(headers)
|
|
41
45
|
@params = params
|
|
@@ -44,24 +48,34 @@ module PatientHttp
|
|
|
44
48
|
@processor = processor
|
|
45
49
|
end
|
|
46
50
|
|
|
47
|
-
#
|
|
51
|
+
# Builds a request.
|
|
48
52
|
#
|
|
49
|
-
# @param method [Symbol] HTTP method
|
|
50
|
-
#
|
|
51
|
-
# @param
|
|
52
|
-
#
|
|
53
|
-
# @param
|
|
54
|
-
# @param
|
|
55
|
-
#
|
|
56
|
-
# @param
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
# @
|
|
53
|
+
# @param method [Symbol] The HTTP method: `:get`, `:head`, `:post`, `:put`,
|
|
54
|
+
# `:patch`, `:delete`, or `:query`.
|
|
55
|
+
# @param uri [String, URI::HTTP] The URL. A relative path is joined with the
|
|
56
|
+
# base URL.
|
|
57
|
+
# @param body [String, nil] The request body.
|
|
58
|
+
# @param json [Object, nil] An object to send as a JSON body. Can't be combined
|
|
59
|
+
# with `body`.
|
|
60
|
+
# @param headers [Hash, nil] The headers to merge with the template headers.
|
|
61
|
+
# @param params [Hash, nil] The query parameters to merge with the template
|
|
62
|
+
# parameters.
|
|
63
|
+
# @param timeout [Numeric, nil] The request timeout in seconds. Overrides the
|
|
64
|
+
# template timeout.
|
|
65
|
+
# @param max_redirects [Integer, nil] The maximum number of redirects to
|
|
66
|
+
# follow. If `0`, redirects aren't followed. If `nil`, the configuration
|
|
67
|
+
# value applies.
|
|
68
|
+
# @param follow_method_changing_redirects [Boolean, nil] Whether to follow a
|
|
69
|
+
# redirect that changes the HTTP method. If `nil`, the configuration value
|
|
70
|
+
# applies.
|
|
71
|
+
# @param redirect_strip_headers [String, Array<String>, nil] The names of headers
|
|
72
|
+
# to remove from redirected requests, in addition to the configured names.
|
|
73
|
+
# Names are case insensitive.
|
|
74
|
+
# @param preprocessors [String, Symbol, Array<String, Symbol>, nil] The names of
|
|
75
|
+
# the preprocessors for the request. Overrides the template preprocessors.
|
|
76
|
+
# @param processor [String, Symbol, nil] The name of the processor for the
|
|
77
|
+
# request. Overrides the template processor.
|
|
78
|
+
# @return [Request] The request.
|
|
65
79
|
def request(
|
|
66
80
|
method,
|
|
67
81
|
uri,
|
|
@@ -70,6 +84,7 @@ module PatientHttp
|
|
|
70
84
|
headers: nil,
|
|
71
85
|
params: nil,
|
|
72
86
|
timeout: nil,
|
|
87
|
+
max_redirects: nil,
|
|
73
88
|
follow_method_changing_redirects: nil,
|
|
74
89
|
redirect_strip_headers: nil,
|
|
75
90
|
preprocessors: nil,
|
|
@@ -89,6 +104,7 @@ module PatientHttp
|
|
|
89
104
|
json: json,
|
|
90
105
|
params: merged_params,
|
|
91
106
|
timeout: timeout || @timeout,
|
|
107
|
+
max_redirects: max_redirects,
|
|
92
108
|
follow_method_changing_redirects: follow_method_changing_redirects,
|
|
93
109
|
redirect_strip_headers: redirect_strip_headers,
|
|
94
110
|
preprocessors: preprocessors || @preprocessors,
|
|
@@ -96,65 +112,72 @@ module PatientHttp
|
|
|
96
112
|
)
|
|
97
113
|
end
|
|
98
114
|
|
|
99
|
-
#
|
|
115
|
+
# Builds a GET request.
|
|
100
116
|
#
|
|
101
|
-
# @param uri [String, URI::HTTP]
|
|
102
|
-
#
|
|
103
|
-
# @
|
|
117
|
+
# @param uri [String, URI::HTTP] The URL. A relative path is joined with the
|
|
118
|
+
# base URL.
|
|
119
|
+
# @param kwargs [Hash] The request options. See {#request}.
|
|
120
|
+
# @return [Request] The request.
|
|
104
121
|
def get(uri, **kwargs)
|
|
105
122
|
request(:get, uri, **kwargs)
|
|
106
123
|
end
|
|
107
124
|
|
|
108
|
-
#
|
|
125
|
+
# Builds a HEAD request.
|
|
109
126
|
#
|
|
110
|
-
# @param uri [String, URI::HTTP]
|
|
111
|
-
#
|
|
112
|
-
# @
|
|
127
|
+
# @param uri [String, URI::HTTP] The URL. A relative path is joined with the
|
|
128
|
+
# base URL.
|
|
129
|
+
# @param kwargs [Hash] The request options. See {#request}.
|
|
130
|
+
# @return [Request] The request.
|
|
113
131
|
def head(uri, **kwargs)
|
|
114
132
|
request(:head, uri, **kwargs)
|
|
115
133
|
end
|
|
116
134
|
|
|
117
|
-
#
|
|
135
|
+
# Builds a POST request.
|
|
118
136
|
#
|
|
119
|
-
# @param uri [String, URI::HTTP]
|
|
120
|
-
#
|
|
121
|
-
# @
|
|
137
|
+
# @param uri [String, URI::HTTP] The URL. A relative path is joined with the
|
|
138
|
+
# base URL.
|
|
139
|
+
# @param kwargs [Hash] The request options. See {#request}.
|
|
140
|
+
# @return [Request] The request.
|
|
122
141
|
def post(uri, **kwargs)
|
|
123
142
|
request(:post, uri, **kwargs)
|
|
124
143
|
end
|
|
125
144
|
|
|
126
|
-
#
|
|
145
|
+
# Builds a PUT request.
|
|
127
146
|
#
|
|
128
|
-
# @param uri [String, URI::HTTP]
|
|
129
|
-
#
|
|
130
|
-
# @
|
|
147
|
+
# @param uri [String, URI::HTTP] The URL. A relative path is joined with the
|
|
148
|
+
# base URL.
|
|
149
|
+
# @param kwargs [Hash] The request options. See {#request}.
|
|
150
|
+
# @return [Request] The request.
|
|
131
151
|
def put(uri, **kwargs)
|
|
132
152
|
request(:put, uri, **kwargs)
|
|
133
153
|
end
|
|
134
154
|
|
|
135
|
-
#
|
|
155
|
+
# Builds a PATCH request.
|
|
136
156
|
#
|
|
137
|
-
# @param uri [String, URI::HTTP]
|
|
138
|
-
#
|
|
139
|
-
# @
|
|
157
|
+
# @param uri [String, URI::HTTP] The URL. A relative path is joined with the
|
|
158
|
+
# base URL.
|
|
159
|
+
# @param kwargs [Hash] The request options. See {#request}.
|
|
160
|
+
# @return [Request] The request.
|
|
140
161
|
def patch(uri, **kwargs)
|
|
141
162
|
request(:patch, uri, **kwargs)
|
|
142
163
|
end
|
|
143
164
|
|
|
144
|
-
#
|
|
165
|
+
# Builds a DELETE request.
|
|
145
166
|
#
|
|
146
|
-
# @param uri [String, URI::HTTP]
|
|
147
|
-
#
|
|
148
|
-
# @
|
|
167
|
+
# @param uri [String, URI::HTTP] The URL. A relative path is joined with the
|
|
168
|
+
# base URL.
|
|
169
|
+
# @param kwargs [Hash] The request options. See {#request}.
|
|
170
|
+
# @return [Request] The request.
|
|
149
171
|
def delete(uri, **kwargs)
|
|
150
172
|
request(:delete, uri, **kwargs)
|
|
151
173
|
end
|
|
152
174
|
|
|
153
|
-
#
|
|
175
|
+
# Builds a QUERY request.
|
|
154
176
|
#
|
|
155
|
-
# @param uri [String, URI::HTTP]
|
|
156
|
-
#
|
|
157
|
-
# @
|
|
177
|
+
# @param uri [String, URI::HTTP] The URL. A relative path is joined with the
|
|
178
|
+
# base URL.
|
|
179
|
+
# @param kwargs [Hash] The request options. See {#request}.
|
|
180
|
+
# @return [Request] The request.
|
|
158
181
|
def query(uri, **kwargs)
|
|
159
182
|
request(:query, uri, **kwargs)
|
|
160
183
|
end
|