http.rb 1.2.1 → 1.3.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/CHANGELOG +19 -2
- data/README.md +3 -3
- data/lib/HTTP/METHODS.rb +29 -0
- data/lib/HTTP/RETRY.rb +4 -2
- data/lib/HTTP/VERSION.rb +1 -1
- data/lib/HTTP/request.rb +4 -4
- data/lib/HTTP.rb +1 -1
- data/test/HTTP/METHODS_test.rb +39 -0
- data/test/HTTP/RETRY_test.rb +20 -0
- metadata +3 -2
- data/lib/HTTP/verbs.rb +0 -26
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 06d8c18c5bfecb35e07a63571d9f4a874da28ae9c20a368781e2ecb01f3ebf7f
|
|
4
|
+
data.tar.gz: f2f58d2f70bb3aeaa7b03d7a2ad3c234fe23536a0e53a8dec312b22da8f0f695
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 989858d90f01ab5b85678baf5241ff61a1e620a3c338442dd8ba512d11c5de81fa6cdb92abb39431e88d4e4372c9df4cd11883d06d111bc7a7e3bec91c1c8b55
|
|
7
|
+
data.tar.gz: ace86800c9010db5b30b6d6814196ba0d689781757076f0fab6b1b0c0b235d2557e350180010b20e6e0face72d55eb2a2c8c9933ebaed51b9ec2c49a3f4b3fc7
|
data/CHANGELOG
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 20260610
|
|
4
|
+
|
|
5
|
+
1.3.0: Rename VERBS to METHODS; VERBS retained as a deprecated alias.
|
|
6
|
+
|
|
7
|
+
RFC 9110 calls these "methods", not "verbs". HTTP::VERBS becomes HTTP::METHODS and HTTP::RETRY::VERBS becomes HTTP::RETRY::METHODS, with the old names kept as deprecated aliases (via deprecate_constant) so nothing breaks. The call surface — the named methods, the options hash, HTTP.request, request_with_body/request_without_body — is unchanged. The aliases are scheduled for removal in 2.0.0; that removal is the breaking change the major bump is reserved for.
|
|
8
|
+
|
|
9
|
+
1. /lib/HTTP/verbs.rb/lib/HTTP/METHODS.rb/: the file is now named for the METHODS module it defines, matching RETRY.rb and VERSION.rb.
|
|
10
|
+
2. ~ HTTP/METHODS.rb: /VERBS/METHODS/ for the WITHOUT_BODY/WITH_BODY container; + VERBS deprecated alias; /verb/request_method/ in the block variable.
|
|
11
|
+
3. ~ HTTP.rb: require 'HTTP/METHODS' in place of require 'HTTP/verbs'.
|
|
12
|
+
4. ~ HTTP/RETRY.rb: /VERBS/METHODS/ for the default retry method list; + VERBS deprecated alias. retry_config now accepts the :retry_methods option (preferred) and still honours :retry_verbs as a backwards-compatible alias; its internal config key is /verbs/methods/.
|
|
13
|
+
5. ~ HTTP/request.rb: the 307/308 redirect handler now references METHODS::WITH_BODY, and the retry guard reads config[:methods]; /verb/request_method/.
|
|
14
|
+
6. ~ test/HTTP/RETRY_test.rb: + retry_methods opt-in and retry_methods-over-retry_verbs precedence cases; the option-leak test now covers both :retry_methods and :retry_verbs.
|
|
15
|
+
7. + test/HTTP/METHODS_test.rb
|
|
16
|
+
8. ~ README.md: retry_methods documented as the option key, with retry_verbs noted as still accepted; the retry default is shown as HTTP::RETRY::METHODS.
|
|
17
|
+
9. ~ HTTP::VERSION: /1.2.1/1.3.0/
|
|
18
|
+
10. ~ CHANGELOG: + 1.3.0 entry
|
|
19
|
+
|
|
20
|
+
## 20260610
|
|
4
21
|
|
|
5
22
|
1.2.1: Split the request builders into their own files.
|
|
6
23
|
|
|
@@ -12,7 +29,7 @@ request_with_body and request_without_body, added in 1.2.0, each move into their
|
|
|
12
29
|
4. ~ HTTP::VERSION: /1.2.0/1.2.1/
|
|
13
30
|
5. ~ CHANGELOG: + 1.2.1 entry
|
|
14
31
|
|
|
15
|
-
##
|
|
32
|
+
## 20260610
|
|
16
33
|
|
|
17
34
|
1.2.0: Extract request_without_body and request_with_body.
|
|
18
35
|
|
data/README.md
CHANGED
|
@@ -110,10 +110,10 @@ HTTP.get('http://example.com', {}, {}, {retries: 3})
|
|
|
110
110
|
|
|
111
111
|
When enabled, transient network exceptions and retry-worthy HTTP status codes (429, 502, 503, 504) are retried with exponential backoff and jitter. If the response carries a `Retry-After` header, it is honoured in place of the calculated delay.
|
|
112
112
|
|
|
113
|
-
Only idempotent
|
|
113
|
+
Only idempotent methods (`get`, `head`, `options`, `put`, `delete`, `trace`) are retried by default. POST and PATCH are not — retrying a non-idempotent write can create duplicate resources against APIs that don't deduplicate. Opt in per-call via `retry_methods:` (the older `retry_verbs:` is still accepted).
|
|
114
114
|
|
|
115
115
|
```ruby
|
|
116
|
-
HTTP.post('http://example.com', {a: 1}, {}, {retries: 3,
|
|
116
|
+
HTTP.post('http://example.com', {a: 1}, {}, {retries: 3, retry_methods: %i{get post}})
|
|
117
117
|
```
|
|
118
118
|
|
|
119
119
|
Configurable options:
|
|
@@ -124,7 +124,7 @@ options = {
|
|
|
124
124
|
retry_delay: 1.0, # base delay (seconds) for exponential backoff
|
|
125
125
|
retry_status_codes: [429, 502, 503, 504], # HTTP status codes to retry
|
|
126
126
|
retry_exceptions: HTTP::RETRY::EXCEPTIONS, # exceptions to retry
|
|
127
|
-
|
|
127
|
+
retry_methods: HTTP::RETRY::METHODS # methods that retry by default (retry_verbs still accepted)
|
|
128
128
|
}
|
|
129
129
|
```
|
|
130
130
|
|
data/lib/HTTP/METHODS.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# HTTP/METHODS.rb
|
|
2
|
+
# HTTP::METHODS
|
|
3
|
+
|
|
4
|
+
require_relative './request_without_body'
|
|
5
|
+
require_relative './request_with_body'
|
|
6
|
+
|
|
7
|
+
module HTTP
|
|
8
|
+
module METHODS
|
|
9
|
+
WITHOUT_BODY = %i{get delete head options trace}
|
|
10
|
+
WITH_BODY = %i{post put patch}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
VERBS = METHODS # Deprecated alias for METHODS; to be removed in 2.0.0.
|
|
14
|
+
deprecate_constant :VERBS
|
|
15
|
+
|
|
16
|
+
METHODS::WITHOUT_BODY.each do |request_method|
|
|
17
|
+
define_method(request_method) do |uri, args = {}, headers = {}, options = {}, &block|
|
|
18
|
+
request_without_body(request_method, uri, args, headers, options, &block)
|
|
19
|
+
end
|
|
20
|
+
module_function request_method
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
METHODS::WITH_BODY.each do |request_method|
|
|
24
|
+
define_method(request_method) do |uri, data = {}, headers = {}, options = {}, &block|
|
|
25
|
+
request_with_body(request_method, uri, data, headers, options, &block)
|
|
26
|
+
end
|
|
27
|
+
module_function request_method
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/HTTP/RETRY.rb
CHANGED
|
@@ -19,7 +19,9 @@ module HTTP
|
|
|
19
19
|
EOFError
|
|
20
20
|
].freeze
|
|
21
21
|
STATUS_CODES = [429, 502, 503, 504].freeze
|
|
22
|
-
|
|
22
|
+
METHODS = %i{get head options put delete trace}.freeze
|
|
23
|
+
VERBS = METHODS # Deprecated alias for METHODS; to be removed in 2.0.0.
|
|
24
|
+
deprecate_constant :VERBS
|
|
23
25
|
|
|
24
26
|
def self.sleep(seconds)
|
|
25
27
|
Kernel.sleep(seconds)
|
|
@@ -32,7 +34,7 @@ module HTTP
|
|
|
32
34
|
delay: options.delete(:retry_delay) || 1.0,
|
|
33
35
|
status_codes: options.delete(:retry_status_codes) || RETRY::STATUS_CODES,
|
|
34
36
|
exceptions: options.delete(:retry_exceptions) || RETRY::EXCEPTIONS,
|
|
35
|
-
|
|
37
|
+
methods: [options.delete(:retry_methods), options.delete(:retry_verbs)].compact.first || RETRY::METHODS
|
|
36
38
|
}
|
|
37
39
|
end
|
|
38
40
|
module_function :retry_config
|
data/lib/HTTP/VERSION.rb
CHANGED
data/lib/HTTP/request.rb
CHANGED
|
@@ -29,9 +29,9 @@ module HTTP
|
|
|
29
29
|
elsif uri.user
|
|
30
30
|
request_object.basic_auth(uri.user, uri.password)
|
|
31
31
|
end
|
|
32
|
-
|
|
32
|
+
request_method = request_object.method.downcase.to_sym
|
|
33
33
|
response = (
|
|
34
|
-
if config[:retries] > 0 && config[:
|
|
34
|
+
if config[:retries] > 0 && config[:methods].include?(request_method)
|
|
35
35
|
with_retries(http, request_object, config)
|
|
36
36
|
else
|
|
37
37
|
http.request(request_object)
|
|
@@ -45,8 +45,8 @@ module HTTP
|
|
|
45
45
|
end
|
|
46
46
|
redirect_uri = uri.merge(response['location'])
|
|
47
47
|
if response.code =~ /^30[78]$/
|
|
48
|
-
data =
|
|
49
|
-
response = send(
|
|
48
|
+
data = METHODS::WITH_BODY.include?(request_method) ? request_object.body : {}
|
|
49
|
+
response = send(request_method, redirect_uri.to_s, data, headers, options, &block)
|
|
50
50
|
else
|
|
51
51
|
response = get(redirect_uri.to_s, {}, {}, options, &block)
|
|
52
52
|
end
|
data/lib/HTTP.rb
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# test/HTTP/METHODS_test.rb
|
|
2
|
+
|
|
3
|
+
require_relative '../helper'
|
|
4
|
+
|
|
5
|
+
def without_deprecation_warnings
|
|
6
|
+
original = Warning[:deprecated]
|
|
7
|
+
Warning[:deprecated] = false
|
|
8
|
+
yield
|
|
9
|
+
ensure
|
|
10
|
+
Warning[:deprecated] = original
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "HTTP::METHODS" do
|
|
14
|
+
it "groups the methods sent without a body" do
|
|
15
|
+
_(HTTP::METHODS::WITHOUT_BODY).must_equal(%i{get delete head options trace})
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "groups the methods sent with a body" do
|
|
19
|
+
_(HTTP::METHODS::WITH_BODY).must_equal(%i{post put patch})
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "remains reachable under the deprecated VERBS name" do
|
|
23
|
+
without_deprecation_warnings do
|
|
24
|
+
_(HTTP::VERBS).must_equal(HTTP::METHODS)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "HTTP::RETRY::METHODS" do
|
|
30
|
+
it "lists the idempotent methods retried by default" do
|
|
31
|
+
_(HTTP::RETRY::METHODS).must_equal(%i{get head options put delete trace})
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "remains reachable under the deprecated VERBS name" do
|
|
35
|
+
without_deprecation_warnings do
|
|
36
|
+
_(HTTP::RETRY::VERBS).must_equal(HTTP::RETRY::METHODS)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/test/HTTP/RETRY_test.rb
CHANGED
|
@@ -177,6 +177,7 @@ describe "retry behaviour" do
|
|
|
177
177
|
retry_delay: 0.1,
|
|
178
178
|
retry_status_codes: [500],
|
|
179
179
|
retry_exceptions: [Errno::ECONNRESET],
|
|
180
|
+
retry_methods: %i{get},
|
|
180
181
|
retry_verbs: %i{get}
|
|
181
182
|
})
|
|
182
183
|
end
|
|
@@ -184,6 +185,7 @@ describe "retry behaviour" do
|
|
|
184
185
|
_(received_opts).wont_include(:retry_delay)
|
|
185
186
|
_(received_opts).wont_include(:retry_status_codes)
|
|
186
187
|
_(received_opts).wont_include(:retry_exceptions)
|
|
188
|
+
_(received_opts).wont_include(:retry_methods)
|
|
187
189
|
_(received_opts).wont_include(:retry_verbs)
|
|
188
190
|
end
|
|
189
191
|
end
|
|
@@ -240,6 +242,24 @@ describe "retry behaviour" do
|
|
|
240
242
|
assert_requested(:post, uri, times: 2)
|
|
241
243
|
end
|
|
242
244
|
end
|
|
245
|
+
|
|
246
|
+
it "retries POST when opted in via retry_methods" do
|
|
247
|
+
HTTP::RETRY.stub(:sleep, nil) do
|
|
248
|
+
stub_request(:post, uri).to_return({status: 503}, {status: 200, body: ''})
|
|
249
|
+
response = HTTP.post(uri, {}, {}, {retries: 3, retry_methods: %i{get post}})
|
|
250
|
+
_(response.success?).must_equal(true)
|
|
251
|
+
assert_requested(:post, uri, times: 2)
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
it "prefers retry_methods over retry_verbs when both are given" do
|
|
256
|
+
HTTP::RETRY.stub(:sleep, nil) do
|
|
257
|
+
stub_request(:post, uri).to_return({status: 503}, {status: 200, body: ''})
|
|
258
|
+
response = HTTP.post(uri, {}, {}, {retries: 3, retry_methods: %i{get post}, retry_verbs: %i{get}})
|
|
259
|
+
_(response.success?).must_equal(true)
|
|
260
|
+
assert_requested(:post, uri, times: 2)
|
|
261
|
+
end
|
|
262
|
+
end
|
|
243
263
|
end
|
|
244
264
|
end
|
|
245
265
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: http.rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- thoran
|
|
@@ -94,18 +94,19 @@ files:
|
|
|
94
94
|
- Rakefile
|
|
95
95
|
- http.rb.gemspec
|
|
96
96
|
- lib/HTTP.rb
|
|
97
|
+
- lib/HTTP/METHODS.rb
|
|
97
98
|
- lib/HTTP/RETRY.rb
|
|
98
99
|
- lib/HTTP/VERSION.rb
|
|
99
100
|
- lib/HTTP/request.rb
|
|
100
101
|
- lib/HTTP/request_with_body.rb
|
|
101
102
|
- lib/HTTP/request_without_body.rb
|
|
102
|
-
- lib/HTTP/verbs.rb
|
|
103
103
|
- lib/Hash/x_www_form_urlencode.rb
|
|
104
104
|
- lib/Net/HTTP/set_options.rb
|
|
105
105
|
- lib/Net/HTTPRequest/set_headers.rb
|
|
106
106
|
- lib/Net/HTTPResponse/StatusPredicates.rb
|
|
107
107
|
- lib/String/url_encode.rb
|
|
108
108
|
- lib/URI/Generic/use_sslQ.rb
|
|
109
|
+
- test/HTTP/METHODS_test.rb
|
|
109
110
|
- test/HTTP/RETRY_test.rb
|
|
110
111
|
- test/HTTP/basic_auth_test.rb
|
|
111
112
|
- test/HTTP/delete_test.rb
|
data/lib/HTTP/verbs.rb
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# HTTP/verbs.rb
|
|
2
|
-
# HTTP.verb
|
|
3
|
-
|
|
4
|
-
require_relative './request_without_body'
|
|
5
|
-
require_relative './request_with_body'
|
|
6
|
-
|
|
7
|
-
module HTTP
|
|
8
|
-
module VERBS
|
|
9
|
-
WITHOUT_BODY = %i{get delete head options trace}
|
|
10
|
-
WITH_BODY = %i{post put patch}
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
VERBS::WITHOUT_BODY.each do |verb|
|
|
14
|
-
define_method(verb) do |uri, args = {}, headers = {}, options = {}, &block|
|
|
15
|
-
request_without_body(verb, uri, args, headers, options, &block)
|
|
16
|
-
end
|
|
17
|
-
module_function verb
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
VERBS::WITH_BODY.each do |verb|
|
|
21
|
-
define_method(verb) do |uri, data = {}, headers = {}, options = {}, &block|
|
|
22
|
-
request_with_body(verb, uri, data, headers, options, &block)
|
|
23
|
-
end
|
|
24
|
-
module_function verb
|
|
25
|
-
end
|
|
26
|
-
end
|