http 5.1.0 → 5.1.1
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/.github/workflows/ci.yml +20 -0
- data/.rubocop_todo.yml +2 -1
- data/CHANGES.md +12 -0
- data/README.md +2 -1
- data/lib/http/redirector.rb +4 -2
- data/lib/http/uri.rb +46 -1
- data/lib/http/version.rb +1 -1
- data/spec/lib/http/client_spec.rb +3 -1
- data/spec/lib/http/redirector_spec.rb +26 -0
- data/spec/lib/http/uri_spec.rb +39 -0
- data/spec/support/dummy_server/servlet.rb +2 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef55bbff996952784d0917931b8eaa6f12a1adfc9cc480daf098cbc8cd8f6107
|
4
|
+
data.tar.gz: 222f8e8723969f89994fe2a0692c41786e450c200c45b84f5c8418f736254a64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49b0c9e508fb02fca9d9e8a26d707202c5ac67bbdf73fce15b616b321545a3a32be96eb9e23f4d389687ad1720372eaba4412e18d800c5d29fab5bb0f4bc0d93
|
7
|
+
data.tar.gz: 1b2e22b2b33abe8059e78535556a15c53959b321fb225cd84153d5a8ea608ba4d03ead9cf018720f63b1e7c27c477f8c3f1b151cae60f2d50b6811e7dd9f5bcc
|
data/.github/workflows/ci.yml
CHANGED
@@ -38,6 +38,26 @@ jobs:
|
|
38
38
|
path-to-lcov: ./coverage/lcov/lcov.info
|
39
39
|
parallel: true
|
40
40
|
|
41
|
+
test-flaky:
|
42
|
+
runs-on: ${{ matrix.os }}
|
43
|
+
|
44
|
+
strategy:
|
45
|
+
matrix:
|
46
|
+
ruby: [ jruby-9.3 ]
|
47
|
+
os: [ ubuntu-latest ]
|
48
|
+
|
49
|
+
steps:
|
50
|
+
- uses: actions/checkout@v3
|
51
|
+
|
52
|
+
- uses: ruby/setup-ruby@v1
|
53
|
+
with:
|
54
|
+
ruby-version: ${{ matrix.ruby }}
|
55
|
+
bundler-cache: true
|
56
|
+
|
57
|
+
- name: bundle exec rspec
|
58
|
+
continue-on-error: true
|
59
|
+
run: bundle exec rspec --format progress --force-colour
|
60
|
+
|
41
61
|
coveralls:
|
42
62
|
needs: test
|
43
63
|
runs-on: ubuntu-latest
|
data/.rubocop_todo.yml
CHANGED
@@ -74,7 +74,7 @@ Metrics/AbcSize:
|
|
74
74
|
- 'lib/http/request.rb'
|
75
75
|
- 'lib/http/response.rb'
|
76
76
|
|
77
|
-
# Offense count:
|
77
|
+
# Offense count: 70
|
78
78
|
# Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods, IgnoredMethods.
|
79
79
|
# IgnoredMethods: refine
|
80
80
|
Metrics/BlockLength:
|
@@ -98,6 +98,7 @@ Metrics/BlockLength:
|
|
98
98
|
- 'spec/lib/http/response/parser_spec.rb'
|
99
99
|
- 'spec/lib/http/response/status_spec.rb'
|
100
100
|
- 'spec/lib/http/response_spec.rb'
|
101
|
+
- 'spec/lib/http/uri_spec.rb'
|
101
102
|
- 'spec/lib/http_spec.rb'
|
102
103
|
- 'spec/support/http_handling_shared.rb'
|
103
104
|
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 5.1.1 (2022-12-17)
|
2
|
+
|
3
|
+
* [#731](https://github.com/httprb/http/pull/731)
|
4
|
+
Strip brackets from IPv6 addresses in `HTTP::URI`.
|
5
|
+
([@jeraki])
|
6
|
+
|
7
|
+
* [#722](https://github.com/httprb/http/pull/722)
|
8
|
+
Add `on_redirect` callback.
|
9
|
+
([@benubois])
|
10
|
+
|
1
11
|
## 5.1.0 (2022-06-17)
|
2
12
|
|
3
13
|
* Drop ruby-2.5 support.
|
@@ -988,3 +998,5 @@ end
|
|
988
998
|
[@YuLeven]: https://github.com/YuLeven
|
989
999
|
[@drwl]: https://github.com/drwl
|
990
1000
|
[@tkellogg]: https://github.com/tkellogg
|
1001
|
+
[@jeraki]: https://github.com/jeraki
|
1002
|
+
[@benubois]: https://github.com/benubois
|
data/README.md
CHANGED
data/lib/http/redirector.rb
CHANGED
@@ -40,8 +40,9 @@ module HTTP
|
|
40
40
|
# @option opts [Boolean] :strict (true) redirector hops policy
|
41
41
|
# @option opts [#to_i] :max_hops (5) maximum allowed amount of hops
|
42
42
|
def initialize(opts = {})
|
43
|
-
@strict
|
44
|
-
@max_hops
|
43
|
+
@strict = opts.fetch(:strict, true)
|
44
|
+
@max_hops = opts.fetch(:max_hops, 5).to_i
|
45
|
+
@on_redirect = opts.fetch(:on_redirect, nil)
|
45
46
|
end
|
46
47
|
|
47
48
|
# Follows redirects until non-redirect response found
|
@@ -65,6 +66,7 @@ module HTTP
|
|
65
66
|
unless cookie_jar.empty?
|
66
67
|
@request.headers.set(Headers::COOKIE, cookie_jar.cookies.map { |c| "#{c.name}=#{c.value}" }.join("; "))
|
67
68
|
end
|
69
|
+
@on_redirect.call @response, @request if @on_redirect.respond_to?(:call)
|
68
70
|
@response = yield @request
|
69
71
|
collect_cookies_from_response
|
70
72
|
end
|
data/lib/http/uri.rb
CHANGED
@@ -9,7 +9,6 @@ module HTTP
|
|
9
9
|
def_delegators :@uri, :scheme, :normalized_scheme, :scheme=
|
10
10
|
def_delegators :@uri, :user, :normalized_user, :user=
|
11
11
|
def_delegators :@uri, :password, :normalized_password, :password=
|
12
|
-
def_delegators :@uri, :host, :normalized_host, :host=
|
13
12
|
def_delegators :@uri, :authority, :normalized_authority, :authority=
|
14
13
|
def_delegators :@uri, :origin, :origin=
|
15
14
|
def_delegators :@uri, :normalized_port, :port=
|
@@ -20,6 +19,18 @@ module HTTP
|
|
20
19
|
def_delegators :@uri, :fragment, :normalized_fragment, :fragment=
|
21
20
|
def_delegators :@uri, :omit, :join, :normalize
|
22
21
|
|
22
|
+
# Host, either a domain name or IP address. If the host is an IPv6 address, it will be returned
|
23
|
+
# without brackets surrounding it.
|
24
|
+
#
|
25
|
+
# @return [String] The host of the URI
|
26
|
+
attr_reader :host
|
27
|
+
|
28
|
+
# Normalized host, either a domain name or IP address. If the host is an IPv6 address, it will
|
29
|
+
# be returned without brackets surrounding it.
|
30
|
+
#
|
31
|
+
# @return [String] The normalized host of the URI
|
32
|
+
attr_reader :normalized_host
|
33
|
+
|
23
34
|
# @private
|
24
35
|
HTTP_SCHEME = "http"
|
25
36
|
|
@@ -83,6 +94,9 @@ module HTTP
|
|
83
94
|
else
|
84
95
|
raise TypeError, "expected Hash for options, got #{options_or_uri.class}"
|
85
96
|
end
|
97
|
+
|
98
|
+
@host = process_ipv6_brackets(@uri.host)
|
99
|
+
@normalized_host = process_ipv6_brackets(@uri.normalized_host)
|
86
100
|
end
|
87
101
|
|
88
102
|
# Are these URI objects equal? Normalizes both URIs prior to comparison
|
@@ -110,6 +124,17 @@ module HTTP
|
|
110
124
|
@hash ||= to_s.hash * -1
|
111
125
|
end
|
112
126
|
|
127
|
+
# Sets the host component for the URI.
|
128
|
+
#
|
129
|
+
# @param [String, #to_str] new_host The new host component.
|
130
|
+
# @return [void]
|
131
|
+
def host=(new_host)
|
132
|
+
@uri.host = process_ipv6_brackets(new_host, :brackets => true)
|
133
|
+
|
134
|
+
@host = process_ipv6_brackets(@uri.host)
|
135
|
+
@normalized_host = process_ipv6_brackets(@uri.normalized_host)
|
136
|
+
end
|
137
|
+
|
113
138
|
# Port number, either as specified or the default if unspecified
|
114
139
|
#
|
115
140
|
# @return [Integer] port number
|
@@ -146,5 +171,25 @@ module HTTP
|
|
146
171
|
def inspect
|
147
172
|
format("#<%s:0x%014x URI:%s>", self.class.name, object_id << 1, to_s)
|
148
173
|
end
|
174
|
+
|
175
|
+
private
|
176
|
+
|
177
|
+
# Process a URI host, adding or removing surrounding brackets if the host is an IPv6 address.
|
178
|
+
#
|
179
|
+
# @param [Boolean] brackets When true, brackets will be added to IPv6 addresses if missing. When
|
180
|
+
# false, they will be removed if present.
|
181
|
+
#
|
182
|
+
# @return [String] Host with IPv6 address brackets added or removed
|
183
|
+
def process_ipv6_brackets(raw_host, brackets: false)
|
184
|
+
ip = IPAddr.new(raw_host)
|
185
|
+
|
186
|
+
if ip.ipv6?
|
187
|
+
brackets ? "[#{ip}]" : ip.to_s
|
188
|
+
else
|
189
|
+
raw_host
|
190
|
+
end
|
191
|
+
rescue IPAddr::Error
|
192
|
+
raw_host
|
193
|
+
end
|
149
194
|
end
|
150
195
|
end
|
data/lib/http/version.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "cgi"
|
5
|
+
require "logger"
|
6
|
+
|
4
7
|
require "support/http_handling_shared"
|
5
8
|
require "support/dummy_server"
|
6
9
|
require "support/ssl_helper"
|
7
|
-
require "logger"
|
8
10
|
|
9
11
|
RSpec.describe HTTP::Client do
|
10
12
|
run_server(:dummy) { DummyServer.new }
|
@@ -148,6 +148,32 @@ RSpec.describe HTTP::Redirector do
|
|
148
148
|
expect(cookies["deleted"]).to eq nil
|
149
149
|
end
|
150
150
|
|
151
|
+
context "with on_redirect callback" do
|
152
|
+
let(:options) do
|
153
|
+
{
|
154
|
+
:on_redirect => proc do |response, location|
|
155
|
+
@redirect_response = response
|
156
|
+
@redirect_location = location
|
157
|
+
end
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
it "calls on_redirect" do
|
162
|
+
req = HTTP::Request.new :verb => :head, :uri => "http://example.com"
|
163
|
+
hops = [
|
164
|
+
redirect_response(301, "http://example.com/1"),
|
165
|
+
redirect_response(301, "http://example.com/2"),
|
166
|
+
simple_response(200, "foo")
|
167
|
+
]
|
168
|
+
|
169
|
+
redirector.perform(req, hops.shift) do |prev_req, _|
|
170
|
+
expect(@redirect_location.uri.to_s).to eq prev_req.uri.to_s
|
171
|
+
expect(@redirect_response.code).to eq 301
|
172
|
+
hops.shift
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
151
177
|
context "following 300 redirect" do
|
152
178
|
context "with strict mode" do
|
153
179
|
let(:options) { {:strict => true} }
|
data/spec/lib/http/uri_spec.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe HTTP::URI do
|
4
|
+
let(:example_ipv6_address) { "2606:2800:220:1:248:1893:25c8:1946" }
|
5
|
+
|
4
6
|
let(:example_http_uri_string) { "http://example.com" }
|
5
7
|
let(:example_https_uri_string) { "https://example.com" }
|
8
|
+
let(:example_ipv6_uri_string) { "https://[#{example_ipv6_address}]" }
|
6
9
|
|
7
10
|
subject(:http_uri) { described_class.parse(example_http_uri_string) }
|
8
11
|
subject(:https_uri) { described_class.parse(example_https_uri_string) }
|
12
|
+
subject(:ipv6_uri) { described_class.parse(example_ipv6_uri_string) }
|
9
13
|
|
10
14
|
it "knows URI schemes" do
|
11
15
|
expect(http_uri.scheme).to eq "http"
|
@@ -20,6 +24,41 @@ RSpec.describe HTTP::URI do
|
|
20
24
|
expect(https_uri.port).to eq 443
|
21
25
|
end
|
22
26
|
|
27
|
+
describe "#host" do
|
28
|
+
it "strips brackets from IPv6 addresses" do
|
29
|
+
expect(ipv6_uri.host).to eq("2606:2800:220:1:248:1893:25c8:1946")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#normalized_host" do
|
34
|
+
it "strips brackets from IPv6 addresses" do
|
35
|
+
expect(ipv6_uri.normalized_host).to eq("2606:2800:220:1:248:1893:25c8:1946")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#host=" do
|
40
|
+
it "updates cached values for #host and #normalized_host" do
|
41
|
+
expect(http_uri.host).to eq("example.com")
|
42
|
+
expect(http_uri.normalized_host).to eq("example.com")
|
43
|
+
|
44
|
+
http_uri.host = "[#{example_ipv6_address}]"
|
45
|
+
|
46
|
+
expect(http_uri.host).to eq(example_ipv6_address)
|
47
|
+
expect(http_uri.normalized_host).to eq(example_ipv6_address)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "ensures IPv6 addresses are bracketed in the inner Addressable::URI" do
|
51
|
+
expect(http_uri.host).to eq("example.com")
|
52
|
+
expect(http_uri.normalized_host).to eq("example.com")
|
53
|
+
|
54
|
+
http_uri.host = example_ipv6_address
|
55
|
+
|
56
|
+
expect(http_uri.host).to eq(example_ipv6_address)
|
57
|
+
expect(http_uri.normalized_host).to eq(example_ipv6_address)
|
58
|
+
expect(http_uri.instance_variable_get(:@uri).host).to eq("[#{example_ipv6_address}]")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
23
62
|
describe "#dup" do
|
24
63
|
it "doesn't share internal value between duplicates" do
|
25
64
|
duplicated_uri = http_uri.dup
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.1.
|
4
|
+
version: 5.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Arcieri
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2022-
|
14
|
+
date: 2022-12-17 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: addressable
|
@@ -192,7 +192,7 @@ metadata:
|
|
192
192
|
source_code_uri: https://github.com/httprb/http
|
193
193
|
wiki_uri: https://github.com/httprb/http/wiki
|
194
194
|
bug_tracker_uri: https://github.com/httprb/http/issues
|
195
|
-
changelog_uri: https://github.com/httprb/http/blob/v5.1.
|
195
|
+
changelog_uri: https://github.com/httprb/http/blob/v5.1.1/CHANGES.md
|
196
196
|
rubygems_mfa_required: 'true'
|
197
197
|
post_install_message:
|
198
198
|
rdoc_options: []
|
@@ -209,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
209
209
|
- !ruby/object:Gem::Version
|
210
210
|
version: '0'
|
211
211
|
requirements: []
|
212
|
-
rubygems_version: 3.
|
212
|
+
rubygems_version: 3.0.3
|
213
213
|
signing_key:
|
214
214
|
specification_version: 4
|
215
215
|
summary: HTTP should be easy
|