http 5.3.1 → 6.0.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.md +241 -41
- data/LICENSE.txt +1 -1
- data/README.md +110 -13
- data/UPGRADING.md +491 -0
- data/http.gemspec +32 -29
- data/lib/http/base64.rb +11 -1
- data/lib/http/chainable/helpers.rb +62 -0
- data/lib/http/chainable/verbs.rb +136 -0
- data/lib/http/chainable.rb +232 -136
- data/lib/http/client.rb +158 -127
- data/lib/http/connection/internals.rb +141 -0
- data/lib/http/connection.rb +126 -97
- data/lib/http/content_type.rb +61 -6
- data/lib/http/errors.rb +25 -1
- data/lib/http/feature.rb +65 -5
- data/lib/http/features/auto_deflate.rb +124 -17
- data/lib/http/features/auto_inflate.rb +38 -15
- data/lib/http/features/caching/entry.rb +178 -0
- data/lib/http/features/caching/in_memory_store.rb +63 -0
- data/lib/http/features/caching.rb +216 -0
- data/lib/http/features/digest_auth.rb +234 -0
- data/lib/http/features/instrumentation.rb +97 -17
- data/lib/http/features/logging.rb +183 -5
- data/lib/http/features/normalize_uri.rb +17 -0
- data/lib/http/features/raise_error.rb +18 -3
- data/lib/http/form_data/composite_io.rb +106 -0
- data/lib/http/form_data/file.rb +95 -0
- data/lib/http/form_data/multipart/param.rb +62 -0
- data/lib/http/form_data/multipart.rb +106 -0
- data/lib/http/form_data/part.rb +52 -0
- data/lib/http/form_data/readable.rb +58 -0
- data/lib/http/form_data/urlencoded.rb +175 -0
- data/lib/http/form_data/version.rb +8 -0
- data/lib/http/form_data.rb +102 -0
- data/lib/http/headers/known.rb +3 -0
- data/lib/http/headers/normalizer.rb +17 -36
- data/lib/http/headers.rb +172 -65
- data/lib/http/mime_type/adapter.rb +24 -9
- data/lib/http/mime_type/json.rb +19 -4
- data/lib/http/mime_type.rb +21 -3
- data/lib/http/options/definitions.rb +189 -0
- data/lib/http/options.rb +172 -125
- data/lib/http/redirector.rb +80 -75
- data/lib/http/request/body.rb +87 -6
- data/lib/http/request/builder.rb +184 -0
- data/lib/http/request/proxy.rb +83 -0
- data/lib/http/request/writer.rb +76 -16
- data/lib/http/request.rb +214 -98
- data/lib/http/response/body.rb +103 -18
- data/lib/http/response/inflater.rb +35 -7
- data/lib/http/response/parser.rb +98 -4
- data/lib/http/response/status/reasons.rb +2 -4
- data/lib/http/response/status.rb +141 -31
- data/lib/http/response.rb +219 -61
- data/lib/http/retriable/delay_calculator.rb +38 -11
- data/lib/http/retriable/errors.rb +21 -0
- data/lib/http/retriable/performer.rb +82 -38
- data/lib/http/session.rb +280 -0
- data/lib/http/timeout/global.rb +147 -34
- data/lib/http/timeout/null.rb +155 -9
- data/lib/http/timeout/per_operation.rb +139 -18
- data/lib/http/uri/normalizer.rb +82 -0
- data/lib/http/uri/parsing.rb +182 -0
- data/lib/http/uri.rb +289 -124
- data/lib/http/version.rb +2 -1
- data/lib/http.rb +11 -2
- data/sig/deps.rbs +122 -0
- data/sig/http.rbs +1619 -0
- data/test/http/base64_test.rb +28 -0
- data/test/http/client_test.rb +739 -0
- data/test/http/connection_test.rb +1533 -0
- data/test/http/content_type_test.rb +190 -0
- data/test/http/errors_test.rb +28 -0
- data/test/http/feature_test.rb +49 -0
- data/test/http/features/auto_deflate_test.rb +317 -0
- data/test/http/features/auto_inflate_test.rb +213 -0
- data/test/http/features/caching_test.rb +942 -0
- data/test/http/features/digest_auth_test.rb +996 -0
- data/test/http/features/instrumentation_test.rb +246 -0
- data/test/http/features/logging_test.rb +654 -0
- data/test/http/features/normalize_uri_test.rb +41 -0
- data/test/http/features/raise_error_test.rb +77 -0
- data/test/http/form_data/composite_io_test.rb +215 -0
- data/test/http/form_data/file_test.rb +255 -0
- data/test/http/form_data/fixtures/the-http-gem.info +1 -0
- data/test/http/form_data/multipart_test.rb +303 -0
- data/test/http/form_data/part_test.rb +90 -0
- data/test/http/form_data/urlencoded_test.rb +164 -0
- data/test/http/form_data_test.rb +232 -0
- data/test/http/headers/normalizer_test.rb +93 -0
- data/test/http/headers_test.rb +888 -0
- data/test/http/mime_type/json_test.rb +39 -0
- data/test/http/mime_type_test.rb +150 -0
- data/test/http/options/base_uri_test.rb +148 -0
- data/test/http/options/body_test.rb +21 -0
- data/test/http/options/features_test.rb +38 -0
- data/test/http/options/form_test.rb +21 -0
- data/test/http/options/headers_test.rb +32 -0
- data/test/http/options/json_test.rb +21 -0
- data/test/http/options/merge_test.rb +78 -0
- data/test/http/options/new_test.rb +37 -0
- data/test/http/options/proxy_test.rb +32 -0
- data/test/http/options_test.rb +575 -0
- data/test/http/redirector_test.rb +639 -0
- data/test/http/request/body_test.rb +318 -0
- data/test/http/request/builder_test.rb +623 -0
- data/test/http/request/writer_test.rb +391 -0
- data/test/http/request_test.rb +1733 -0
- data/test/http/response/body_test.rb +292 -0
- data/test/http/response/parser_test.rb +105 -0
- data/test/http/response/status_test.rb +322 -0
- data/test/http/response_test.rb +502 -0
- data/test/http/retriable/delay_calculator_test.rb +194 -0
- data/test/http/retriable/errors_test.rb +71 -0
- data/test/http/retriable/performer_test.rb +551 -0
- data/test/http/session_test.rb +424 -0
- data/test/http/timeout/global_test.rb +239 -0
- data/test/http/timeout/null_test.rb +218 -0
- data/test/http/timeout/per_operation_test.rb +220 -0
- data/test/http/uri/normalizer_test.rb +89 -0
- data/test/http/uri_test.rb +1140 -0
- data/test/http/version_test.rb +15 -0
- data/test/http_test.rb +818 -0
- data/test/regression_tests.rb +27 -0
- data/test/support/dummy_server/encoding_routes.rb +47 -0
- data/test/support/dummy_server/routes.rb +201 -0
- data/test/support/dummy_server/servlet.rb +81 -0
- data/test/support/dummy_server.rb +200 -0
- data/{spec → test}/support/fakeio.rb +2 -2
- data/test/support/http_handling_shared/connection_reuse_tests.rb +97 -0
- data/test/support/http_handling_shared/timeout_tests.rb +134 -0
- data/test/support/http_handling_shared.rb +11 -0
- data/test/support/proxy_server.rb +207 -0
- data/test/support/servers/runner.rb +67 -0
- data/{spec → test}/support/simplecov.rb +11 -2
- data/test/support/ssl_helper.rb +108 -0
- data/test/test_helper.rb +38 -0
- metadata +108 -168
- data/.github/workflows/ci.yml +0 -67
- data/.gitignore +0 -15
- data/.rspec +0 -1
- data/.rubocop/layout.yml +0 -8
- data/.rubocop/metrics.yml +0 -4
- data/.rubocop/rspec.yml +0 -9
- data/.rubocop/style.yml +0 -32
- data/.rubocop.yml +0 -11
- data/.rubocop_todo.yml +0 -219
- data/.yardopts +0 -2
- data/CHANGES_OLD.md +0 -1002
- data/Gemfile +0 -51
- data/Guardfile +0 -18
- data/Rakefile +0 -64
- data/lib/http/headers/mixin.rb +0 -34
- data/lib/http/retriable/client.rb +0 -37
- data/logo.png +0 -0
- data/spec/lib/http/client_spec.rb +0 -556
- data/spec/lib/http/connection_spec.rb +0 -88
- data/spec/lib/http/content_type_spec.rb +0 -47
- data/spec/lib/http/features/auto_deflate_spec.rb +0 -77
- data/spec/lib/http/features/auto_inflate_spec.rb +0 -86
- data/spec/lib/http/features/instrumentation_spec.rb +0 -81
- data/spec/lib/http/features/logging_spec.rb +0 -65
- data/spec/lib/http/features/raise_error_spec.rb +0 -62
- data/spec/lib/http/headers/mixin_spec.rb +0 -36
- data/spec/lib/http/headers/normalizer_spec.rb +0 -52
- data/spec/lib/http/headers_spec.rb +0 -527
- data/spec/lib/http/options/body_spec.rb +0 -15
- data/spec/lib/http/options/features_spec.rb +0 -33
- data/spec/lib/http/options/form_spec.rb +0 -15
- data/spec/lib/http/options/headers_spec.rb +0 -24
- data/spec/lib/http/options/json_spec.rb +0 -15
- data/spec/lib/http/options/merge_spec.rb +0 -68
- data/spec/lib/http/options/new_spec.rb +0 -30
- data/spec/lib/http/options/proxy_spec.rb +0 -20
- data/spec/lib/http/options_spec.rb +0 -13
- data/spec/lib/http/redirector_spec.rb +0 -530
- data/spec/lib/http/request/body_spec.rb +0 -211
- data/spec/lib/http/request/writer_spec.rb +0 -121
- data/spec/lib/http/request_spec.rb +0 -234
- data/spec/lib/http/response/body_spec.rb +0 -85
- data/spec/lib/http/response/parser_spec.rb +0 -74
- data/spec/lib/http/response/status_spec.rb +0 -253
- data/spec/lib/http/response_spec.rb +0 -262
- data/spec/lib/http/retriable/delay_calculator_spec.rb +0 -69
- data/spec/lib/http/retriable/performer_spec.rb +0 -302
- data/spec/lib/http/uri/normalizer_spec.rb +0 -95
- data/spec/lib/http/uri_spec.rb +0 -71
- data/spec/lib/http_spec.rb +0 -535
- data/spec/regression_specs.rb +0 -24
- data/spec/spec_helper.rb +0 -89
- data/spec/support/black_hole.rb +0 -13
- data/spec/support/dummy_server/servlet.rb +0 -203
- data/spec/support/dummy_server.rb +0 -44
- data/spec/support/fuubar.rb +0 -21
- data/spec/support/http_handling_shared.rb +0 -190
- data/spec/support/proxy_server.rb +0 -39
- data/spec/support/servers/config.rb +0 -11
- data/spec/support/servers/runner.rb +0 -19
- data/spec/support/ssl_helper.rb +0 -104
- /data/{spec → test}/support/capture_warning.rb +0 -0
|
@@ -1,527 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe HTTP::Headers do
|
|
4
|
-
subject(:headers) { described_class.new }
|
|
5
|
-
|
|
6
|
-
it "is Enumerable" do
|
|
7
|
-
expect(headers).to be_an Enumerable
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
describe "#set" do
|
|
11
|
-
it "sets header value" do
|
|
12
|
-
headers.set "Accept", "application/json"
|
|
13
|
-
expect(headers["Accept"]).to eq "application/json"
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it "allows retrieval via normalized header name" do
|
|
17
|
-
headers.set :content_type, "application/json"
|
|
18
|
-
expect(headers["Content-Type"]).to eq "application/json"
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
it "overwrites previous value" do
|
|
22
|
-
headers.set :set_cookie, "hoo=ray"
|
|
23
|
-
headers.set :set_cookie, "woo=hoo"
|
|
24
|
-
expect(headers["Set-Cookie"]).to eq "woo=hoo"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "allows set multiple values" do
|
|
28
|
-
headers.set :set_cookie, "hoo=ray"
|
|
29
|
-
headers.set :set_cookie, %w[hoo=ray woo=hoo]
|
|
30
|
-
expect(headers["Set-Cookie"]).to eq %w[hoo=ray woo=hoo]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it "fails with empty header name" do
|
|
34
|
-
expect { headers.set "", "foo bar" }.
|
|
35
|
-
to raise_error HTTP::HeaderError
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
["foo bar", "foo bar: ok\nfoo", "evil-header: evil-value\nfoo"].each do |name|
|
|
39
|
-
it "fails with invalid header name (#{name.inspect})" do
|
|
40
|
-
expect { headers.set name, "baz" }.
|
|
41
|
-
to raise_error HTTP::HeaderError
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it "fails with invalid header value" do
|
|
46
|
-
expect { headers.set "foo", "bar\nEvil-Header: evil-value" }.
|
|
47
|
-
to raise_error HTTP::HeaderError
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
describe "#[]=" do
|
|
52
|
-
it "sets header value" do
|
|
53
|
-
headers["Accept"] = "application/json"
|
|
54
|
-
expect(headers["Accept"]).to eq "application/json"
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
it "allows retrieval via normalized header name" do
|
|
58
|
-
headers[:content_type] = "application/json"
|
|
59
|
-
expect(headers["Content-Type"]).to eq "application/json"
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it "overwrites previous value" do
|
|
63
|
-
headers[:set_cookie] = "hoo=ray"
|
|
64
|
-
headers[:set_cookie] = "woo=hoo"
|
|
65
|
-
expect(headers["Set-Cookie"]).to eq "woo=hoo"
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it "allows set multiple values" do
|
|
69
|
-
headers[:set_cookie] = "hoo=ray"
|
|
70
|
-
headers[:set_cookie] = %w[hoo=ray woo=hoo]
|
|
71
|
-
expect(headers["Set-Cookie"]).to eq %w[hoo=ray woo=hoo]
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
describe "#delete" do
|
|
76
|
-
before { headers.set "Content-Type", "application/json" }
|
|
77
|
-
|
|
78
|
-
it "removes given header" do
|
|
79
|
-
headers.delete "Content-Type"
|
|
80
|
-
expect(headers["Content-Type"]).to be_nil
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
it "removes header that matches normalized version of specified name" do
|
|
84
|
-
headers.delete :content_type
|
|
85
|
-
expect(headers["Content-Type"]).to be_nil
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
it "fails with empty header name" do
|
|
89
|
-
expect { headers.delete "" }.
|
|
90
|
-
to raise_error HTTP::HeaderError
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
["foo bar", "foo bar: ok\nfoo"].each do |name|
|
|
94
|
-
it "fails with invalid header name (#{name.inspect})" do
|
|
95
|
-
expect { headers.delete name }.
|
|
96
|
-
to raise_error HTTP::HeaderError
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
describe "#add" do
|
|
102
|
-
it "sets header value" do
|
|
103
|
-
headers.add "Accept", "application/json"
|
|
104
|
-
expect(headers["Accept"]).to eq "application/json"
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
it "allows retrieval via normalized header name" do
|
|
108
|
-
headers.add :content_type, "application/json"
|
|
109
|
-
expect(headers["Content-Type"]).to eq "application/json"
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
it "appends new value if header exists" do
|
|
113
|
-
headers.add "Set-Cookie", "hoo=ray"
|
|
114
|
-
headers.add :set_cookie, "woo=hoo"
|
|
115
|
-
expect(headers["Set-Cookie"]).to eq %w[hoo=ray woo=hoo]
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
it "allows append multiple values" do
|
|
119
|
-
headers.add :set_cookie, "hoo=ray"
|
|
120
|
-
headers.add :set_cookie, %w[woo=hoo yup=pie]
|
|
121
|
-
expect(headers["Set-Cookie"]).to eq %w[hoo=ray woo=hoo yup=pie]
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
it "fails with empty header name" do
|
|
125
|
-
expect { headers.add("", "foobar") }.
|
|
126
|
-
to raise_error HTTP::HeaderError
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
["foo bar", "foo bar: ok\nfoo"].each do |name|
|
|
130
|
-
it "fails with invalid header name (#{name.inspect})" do
|
|
131
|
-
expect { headers.add name, "baz" }.
|
|
132
|
-
to raise_error HTTP::HeaderError
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
it "fails with invalid header value" do
|
|
137
|
-
expect { headers.add "foo", "bar\nEvil-Header: evil-value" }.
|
|
138
|
-
to raise_error HTTP::HeaderError
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
it "fails when header name is not a String or Symbol" do
|
|
142
|
-
expect { headers.add 2, "foo" }.
|
|
143
|
-
to raise_error HTTP::HeaderError
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
describe "#get" do
|
|
148
|
-
before { headers.set("Content-Type", "application/json") }
|
|
149
|
-
|
|
150
|
-
it "returns array of associated values" do
|
|
151
|
-
expect(headers.get("Content-Type")).to eq %w[application/json]
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
it "normalizes header name" do
|
|
155
|
-
expect(headers.get(:content_type)).to eq %w[application/json]
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
context "when header does not exists" do
|
|
159
|
-
it "returns empty array" do
|
|
160
|
-
expect(headers.get(:accept)).to eq []
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
it "fails with empty header name" do
|
|
165
|
-
expect { headers.get("") }.
|
|
166
|
-
to raise_error HTTP::HeaderError
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
["foo bar", "foo bar: ok\nfoo"].each do |name|
|
|
170
|
-
it "fails with invalid header name (#{name.inspect})" do
|
|
171
|
-
expect { headers.get name }.
|
|
172
|
-
to raise_error HTTP::HeaderError
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
describe "#[]" do
|
|
178
|
-
context "when header does not exists" do
|
|
179
|
-
it "returns nil" do
|
|
180
|
-
expect(headers[:accept]).to be_nil
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
context "when header has a single value" do
|
|
185
|
-
before { headers.set "Content-Type", "application/json" }
|
|
186
|
-
|
|
187
|
-
it "normalizes header name" do
|
|
188
|
-
expect(headers[:content_type]).to_not be_nil
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
it "returns it returns a single value" do
|
|
192
|
-
expect(headers[:content_type]).to eq "application/json"
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
context "when header has a multiple values" do
|
|
197
|
-
before do
|
|
198
|
-
headers.add :set_cookie, "hoo=ray"
|
|
199
|
-
headers.add :set_cookie, "woo=hoo"
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
it "normalizes header name" do
|
|
203
|
-
expect(headers[:set_cookie]).to_not be_nil
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
it "returns array of associated values" do
|
|
207
|
-
expect(headers[:set_cookie]).to eq %w[hoo=ray woo=hoo]
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
describe "#include?" do
|
|
213
|
-
before do
|
|
214
|
-
headers.add :content_type, "application/json"
|
|
215
|
-
headers.add :set_cookie, "hoo=ray"
|
|
216
|
-
headers.add :set_cookie, "woo=hoo"
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
it "tells whenever given headers is set or not" do
|
|
220
|
-
expect(headers.include?("Content-Type")).to be true
|
|
221
|
-
expect(headers.include?("Set-Cookie")).to be true
|
|
222
|
-
expect(headers.include?("Accept")).to be false
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
it "normalizes given header name" do
|
|
226
|
-
expect(headers.include?(:content_type)).to be true
|
|
227
|
-
expect(headers.include?(:set_cookie)).to be true
|
|
228
|
-
expect(headers.include?(:accept)).to be false
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
describe "#to_h" do
|
|
233
|
-
before do
|
|
234
|
-
headers.add :content_type, "application/json"
|
|
235
|
-
headers.add :set_cookie, "hoo=ray"
|
|
236
|
-
headers.add :set_cookie, "woo=hoo"
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
it "returns a Hash" do
|
|
240
|
-
expect(headers.to_h).to be_a ::Hash
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
it "returns Hash with normalized keys" do
|
|
244
|
-
expect(headers.to_h.keys).to match_array %w[Content-Type Set-Cookie]
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
context "for a header with single value" do
|
|
248
|
-
it "provides a value as is" do
|
|
249
|
-
expect(headers.to_h["Content-Type"]).to eq "application/json"
|
|
250
|
-
end
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
context "for a header with multiple values" do
|
|
254
|
-
it "provides an array of values" do
|
|
255
|
-
expect(headers.to_h["Set-Cookie"]).to eq %w[hoo=ray woo=hoo]
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
describe "#to_a" do
|
|
261
|
-
before do
|
|
262
|
-
headers.add :content_type, "application/json"
|
|
263
|
-
headers.add :set_cookie, "hoo=ray"
|
|
264
|
-
headers.add :set_cookie, "woo=hoo"
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
it "returns an Array" do
|
|
268
|
-
expect(headers.to_a).to be_a Array
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
it "returns Array of key/value pairs with normalized keys" do
|
|
272
|
-
expect(headers.to_a).to eq [
|
|
273
|
-
%w[Content-Type application/json],
|
|
274
|
-
%w[Set-Cookie hoo=ray],
|
|
275
|
-
%w[Set-Cookie woo=hoo]
|
|
276
|
-
]
|
|
277
|
-
end
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
describe "#inspect" do
|
|
281
|
-
before { headers.set :set_cookie, %w[hoo=ray woo=hoo] }
|
|
282
|
-
subject { headers.inspect }
|
|
283
|
-
|
|
284
|
-
it { is_expected.to eq '#<HTTP::Headers {"Set-Cookie"=>["hoo=ray", "woo=hoo"]}>' }
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
describe "#keys" do
|
|
288
|
-
before do
|
|
289
|
-
headers.add :content_type, "application/json"
|
|
290
|
-
headers.add :set_cookie, "hoo=ray"
|
|
291
|
-
headers.add :set_cookie, "woo=hoo"
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
it "returns uniq keys only" do
|
|
295
|
-
expect(headers.keys.size).to eq 2
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
it "normalizes keys" do
|
|
299
|
-
expect(headers.keys).to include("Content-Type", "Set-Cookie")
|
|
300
|
-
end
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
describe "#each" do
|
|
304
|
-
before do
|
|
305
|
-
headers.add :set_cookie, "hoo=ray"
|
|
306
|
-
headers.add :content_type, "application/json"
|
|
307
|
-
headers.add :set_cookie, "woo=hoo"
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
it "yields each key/value pair separatedly" do
|
|
311
|
-
expect { |b| headers.each(&b) }.to yield_control.exactly(3).times
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
it "yields headers in the same order they were added" do
|
|
315
|
-
expect { |b| headers.each(&b) }.to yield_successive_args(
|
|
316
|
-
%w[Set-Cookie hoo=ray],
|
|
317
|
-
%w[Content-Type application/json],
|
|
318
|
-
%w[Set-Cookie woo=hoo]
|
|
319
|
-
)
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
it "yields header keys specified as symbols in normalized form" do
|
|
323
|
-
keys = headers.each.map(&:first)
|
|
324
|
-
expect(keys).to eq(%w[Set-Cookie Content-Type Set-Cookie])
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
it "yields headers specified as strings without conversion" do
|
|
328
|
-
headers.add "X_kEy", "value"
|
|
329
|
-
keys = headers.each.map(&:first)
|
|
330
|
-
expect(keys).to eq(%w[Set-Cookie Content-Type Set-Cookie X_kEy])
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
it "returns self instance if block given" do
|
|
334
|
-
expect(headers.each { |*| }).to be headers # rubocop:disable Lint/EmptyBlock
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
it "returns Enumerator if no block given" do
|
|
338
|
-
expect(headers.each).to be_a Enumerator
|
|
339
|
-
end
|
|
340
|
-
end
|
|
341
|
-
|
|
342
|
-
describe ".empty?" do
|
|
343
|
-
subject { headers.empty? }
|
|
344
|
-
|
|
345
|
-
context "initially" do
|
|
346
|
-
it { is_expected.to be true }
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
context "when header exists" do
|
|
350
|
-
before { headers.add :accept, "text/plain" }
|
|
351
|
-
it { is_expected.to be false }
|
|
352
|
-
end
|
|
353
|
-
|
|
354
|
-
context "when last header was removed" do
|
|
355
|
-
before do
|
|
356
|
-
headers.add :accept, "text/plain"
|
|
357
|
-
headers.delete :accept
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
it { is_expected.to be true }
|
|
361
|
-
end
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
describe "#hash" do
|
|
365
|
-
let(:left) { described_class.new }
|
|
366
|
-
let(:right) { described_class.new }
|
|
367
|
-
|
|
368
|
-
it "equals if two headers equals" do
|
|
369
|
-
left.add :accept, "text/plain"
|
|
370
|
-
right.add :accept, "text/plain"
|
|
371
|
-
|
|
372
|
-
expect(left.hash).to eq right.hash
|
|
373
|
-
end
|
|
374
|
-
end
|
|
375
|
-
|
|
376
|
-
describe "#==" do
|
|
377
|
-
let(:left) { described_class.new }
|
|
378
|
-
let(:right) { described_class.new }
|
|
379
|
-
|
|
380
|
-
it "compares header keys and values" do
|
|
381
|
-
left.add :accept, "text/plain"
|
|
382
|
-
right.add :accept, "text/plain"
|
|
383
|
-
|
|
384
|
-
expect(left).to eq right
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
it "allows comparison with Array of key/value pairs" do
|
|
388
|
-
left.add :accept, "text/plain"
|
|
389
|
-
expect(left).to eq [%w[Accept text/plain]]
|
|
390
|
-
end
|
|
391
|
-
|
|
392
|
-
it "sensitive to headers order" do
|
|
393
|
-
left.add :accept, "text/plain"
|
|
394
|
-
left.add :cookie, "woo=hoo"
|
|
395
|
-
right.add :cookie, "woo=hoo"
|
|
396
|
-
right.add :accept, "text/plain"
|
|
397
|
-
|
|
398
|
-
expect(left).to_not eq right
|
|
399
|
-
end
|
|
400
|
-
|
|
401
|
-
it "sensitive to header values order" do
|
|
402
|
-
left.add :cookie, "hoo=ray"
|
|
403
|
-
left.add :cookie, "woo=hoo"
|
|
404
|
-
right.add :cookie, "woo=hoo"
|
|
405
|
-
right.add :cookie, "hoo=ray"
|
|
406
|
-
|
|
407
|
-
expect(left).to_not eq right
|
|
408
|
-
end
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
describe "#dup" do
|
|
412
|
-
before { headers.set :content_type, "application/json" }
|
|
413
|
-
|
|
414
|
-
subject(:dupped) { headers.dup }
|
|
415
|
-
|
|
416
|
-
it { is_expected.to be_a described_class }
|
|
417
|
-
it { is_expected.not_to be headers }
|
|
418
|
-
|
|
419
|
-
it "has headers copied" do
|
|
420
|
-
expect(dupped[:content_type]).to eq "application/json"
|
|
421
|
-
end
|
|
422
|
-
|
|
423
|
-
context "modifying a copy" do
|
|
424
|
-
before { dupped.set :content_type, "text/plain" }
|
|
425
|
-
|
|
426
|
-
it "modifies dupped copy" do
|
|
427
|
-
expect(dupped[:content_type]).to eq "text/plain"
|
|
428
|
-
end
|
|
429
|
-
|
|
430
|
-
it "does not affects original headers" do
|
|
431
|
-
expect(headers[:content_type]).to eq "application/json"
|
|
432
|
-
end
|
|
433
|
-
end
|
|
434
|
-
end
|
|
435
|
-
|
|
436
|
-
describe "#merge!" do
|
|
437
|
-
before do
|
|
438
|
-
headers.set :host, "example.com"
|
|
439
|
-
headers.set :accept, "application/json"
|
|
440
|
-
headers.merge! :accept => "plain/text", :cookie => %w[hoo=ray woo=hoo]
|
|
441
|
-
end
|
|
442
|
-
|
|
443
|
-
it "leaves headers not presented in other as is" do
|
|
444
|
-
expect(headers[:host]).to eq "example.com"
|
|
445
|
-
end
|
|
446
|
-
|
|
447
|
-
it "overwrites existing values" do
|
|
448
|
-
expect(headers[:accept]).to eq "plain/text"
|
|
449
|
-
end
|
|
450
|
-
|
|
451
|
-
it "appends other headers, not presented in base" do
|
|
452
|
-
expect(headers[:cookie]).to eq %w[hoo=ray woo=hoo]
|
|
453
|
-
end
|
|
454
|
-
end
|
|
455
|
-
|
|
456
|
-
describe "#merge" do
|
|
457
|
-
before do
|
|
458
|
-
headers.set :host, "example.com"
|
|
459
|
-
headers.set :accept, "application/json"
|
|
460
|
-
end
|
|
461
|
-
|
|
462
|
-
subject(:merged) do
|
|
463
|
-
headers.merge :accept => "plain/text", :cookie => %w[hoo=ray woo=hoo]
|
|
464
|
-
end
|
|
465
|
-
|
|
466
|
-
it { is_expected.to be_a described_class }
|
|
467
|
-
it { is_expected.not_to be headers }
|
|
468
|
-
|
|
469
|
-
it "does not affects original headers" do
|
|
470
|
-
expect(merged.to_h).to_not eq headers.to_h
|
|
471
|
-
end
|
|
472
|
-
|
|
473
|
-
it "leaves headers not presented in other as is" do
|
|
474
|
-
expect(merged[:host]).to eq "example.com"
|
|
475
|
-
end
|
|
476
|
-
|
|
477
|
-
it "overwrites existing values" do
|
|
478
|
-
expect(merged[:accept]).to eq "plain/text"
|
|
479
|
-
end
|
|
480
|
-
|
|
481
|
-
it "appends other headers, not presented in base" do
|
|
482
|
-
expect(merged[:cookie]).to eq %w[hoo=ray woo=hoo]
|
|
483
|
-
end
|
|
484
|
-
end
|
|
485
|
-
|
|
486
|
-
describe ".coerce" do
|
|
487
|
-
let(:dummyClass) { Class.new { def respond_to?(*); end } }
|
|
488
|
-
|
|
489
|
-
it "accepts any object that respond to #to_hash" do
|
|
490
|
-
hashie = double :to_hash => {"accept" => "json"}
|
|
491
|
-
expect(described_class.coerce(hashie)["accept"]).to eq "json"
|
|
492
|
-
end
|
|
493
|
-
|
|
494
|
-
it "accepts any object that respond to #to_h" do
|
|
495
|
-
hashie = double :to_h => {"accept" => "json"}
|
|
496
|
-
expect(described_class.coerce(hashie)["accept"]).to eq "json"
|
|
497
|
-
end
|
|
498
|
-
|
|
499
|
-
it "accepts any object that respond to #to_a" do
|
|
500
|
-
hashie = double :to_a => [%w[accept json]]
|
|
501
|
-
expect(described_class.coerce(hashie)["accept"]).to eq "json"
|
|
502
|
-
end
|
|
503
|
-
|
|
504
|
-
it "fails if given object cannot be coerced" do
|
|
505
|
-
expect { described_class.coerce dummyClass.new }.to raise_error HTTP::Error
|
|
506
|
-
end
|
|
507
|
-
|
|
508
|
-
context "with duplicate header keys (mixed case)" do
|
|
509
|
-
let(:headers) { {"Set-Cookie" => "hoo=ray", "set_cookie" => "woo=hoo", :set_cookie => "ta=da"} }
|
|
510
|
-
|
|
511
|
-
it "adds all headers" do
|
|
512
|
-
expect(described_class.coerce(headers).to_a).
|
|
513
|
-
to match_array(
|
|
514
|
-
[
|
|
515
|
-
%w[Set-Cookie hoo=ray],
|
|
516
|
-
%w[set_cookie woo=hoo],
|
|
517
|
-
%w[Set-Cookie ta=da]
|
|
518
|
-
]
|
|
519
|
-
)
|
|
520
|
-
end
|
|
521
|
-
end
|
|
522
|
-
|
|
523
|
-
it "is aliased as .[]" do
|
|
524
|
-
expect(described_class.method(:coerce)).to eq described_class.method(:[])
|
|
525
|
-
end
|
|
526
|
-
end
|
|
527
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe HTTP::Options, "body" do
|
|
4
|
-
let(:opts) { HTTP::Options.new }
|
|
5
|
-
|
|
6
|
-
it "defaults to nil" do
|
|
7
|
-
expect(opts.body).to be nil
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it "may be specified with with_body" do
|
|
11
|
-
opts2 = opts.with_body("foo")
|
|
12
|
-
expect(opts.body).to be nil
|
|
13
|
-
expect(opts2.body).to eq("foo")
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe HTTP::Options, "features" do
|
|
4
|
-
let(:opts) { HTTP::Options.new }
|
|
5
|
-
|
|
6
|
-
it "defaults to be empty" do
|
|
7
|
-
expect(opts.features).to be_empty
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it "accepts plain symbols in array" do
|
|
11
|
-
opts2 = opts.with_features([:auto_inflate])
|
|
12
|
-
expect(opts.features).to be_empty
|
|
13
|
-
expect(opts2.features.keys).to eq([:auto_inflate])
|
|
14
|
-
expect(opts2.features[:auto_inflate]).
|
|
15
|
-
to be_instance_of(HTTP::Features::AutoInflate)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it "accepts feature name with its options in array" do
|
|
19
|
-
opts2 = opts.with_features([{:auto_deflate => {:method => :deflate}}])
|
|
20
|
-
expect(opts.features).to be_empty
|
|
21
|
-
expect(opts2.features.keys).to eq([:auto_deflate])
|
|
22
|
-
expect(opts2.features[:auto_deflate]).
|
|
23
|
-
to be_instance_of(HTTP::Features::AutoDeflate)
|
|
24
|
-
expect(opts2.features[:auto_deflate].method).to eq("deflate")
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "raises error for not supported features" do
|
|
28
|
-
expect { opts.with_features([:wrong_feature]) }.
|
|
29
|
-
to raise_error(HTTP::Error) { |error|
|
|
30
|
-
expect(error.message).to eq("Unsupported feature: wrong_feature")
|
|
31
|
-
}
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe HTTP::Options, "form" do
|
|
4
|
-
let(:opts) { HTTP::Options.new }
|
|
5
|
-
|
|
6
|
-
it "defaults to nil" do
|
|
7
|
-
expect(opts.form).to be nil
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it "may be specified with with_form_data" do
|
|
11
|
-
opts2 = opts.with_form(:foo => 42)
|
|
12
|
-
expect(opts.form).to be nil
|
|
13
|
-
expect(opts2.form).to eq(:foo => 42)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe HTTP::Options, "headers" do
|
|
4
|
-
let(:opts) { HTTP::Options.new }
|
|
5
|
-
|
|
6
|
-
it "defaults to be empty" do
|
|
7
|
-
expect(opts.headers).to be_empty
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it "may be specified with with_headers" do
|
|
11
|
-
opts2 = opts.with_headers(:accept => "json")
|
|
12
|
-
expect(opts.headers).to be_empty
|
|
13
|
-
expect(opts2.headers).to eq([%w[Accept json]])
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it "accepts any object that respond to :to_hash" do
|
|
17
|
-
x = if RUBY_VERSION >= "3.2.0"
|
|
18
|
-
Data.define(:to_hash).new(:to_hash => { "accept" => "json" })
|
|
19
|
-
else
|
|
20
|
-
Struct.new(:to_hash).new({ "accept" => "json" })
|
|
21
|
-
end
|
|
22
|
-
expect(opts.with_headers(x).headers["accept"]).to eq("json")
|
|
23
|
-
end
|
|
24
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe HTTP::Options, "json" do
|
|
4
|
-
let(:opts) { HTTP::Options.new }
|
|
5
|
-
|
|
6
|
-
it "defaults to nil" do
|
|
7
|
-
expect(opts.json).to be nil
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it "may be specified with with_json data" do
|
|
11
|
-
opts2 = opts.with_json(:foo => 42)
|
|
12
|
-
expect(opts.json).to be nil
|
|
13
|
-
expect(opts2.json).to eq(:foo => 42)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe HTTP::Options, "merge" do
|
|
4
|
-
let(:opts) { HTTP::Options.new }
|
|
5
|
-
|
|
6
|
-
it "supports a Hash" do
|
|
7
|
-
old_response = opts.response
|
|
8
|
-
expect(opts.merge(:response => :body).response).to eq(:body)
|
|
9
|
-
expect(opts.response).to eq(old_response)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
it "supports another Options" do
|
|
13
|
-
merged = opts.merge(HTTP::Options.new(:response => :body))
|
|
14
|
-
expect(merged.response).to eq(:body)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it "merges as excepted in complex cases" do
|
|
18
|
-
# FIXME: yuck :(
|
|
19
|
-
|
|
20
|
-
foo = HTTP::Options.new(
|
|
21
|
-
:response => :body,
|
|
22
|
-
:params => {:baz => "bar"},
|
|
23
|
-
:form => {:foo => "foo"},
|
|
24
|
-
:body => "body-foo",
|
|
25
|
-
:json => {:foo => "foo"},
|
|
26
|
-
:headers => {:accept => "json", :foo => "foo"},
|
|
27
|
-
:proxy => {},
|
|
28
|
-
:features => {}
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
bar = HTTP::Options.new(
|
|
32
|
-
:response => :parsed_body,
|
|
33
|
-
:persistent => "https://www.googe.com",
|
|
34
|
-
:params => {:plop => "plip"},
|
|
35
|
-
:form => {:bar => "bar"},
|
|
36
|
-
:body => "body-bar",
|
|
37
|
-
:json => {:bar => "bar"},
|
|
38
|
-
:keep_alive_timeout => 10,
|
|
39
|
-
:headers => {:accept => "xml", :bar => "bar"},
|
|
40
|
-
:timeout_options => {:foo => :bar},
|
|
41
|
-
:ssl => {:foo => "bar"},
|
|
42
|
-
:proxy => {:proxy_address => "127.0.0.1", :proxy_port => 8080}
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
expect(foo.merge(bar).to_hash).to eq(
|
|
46
|
-
:response => :parsed_body,
|
|
47
|
-
:timeout_class => described_class.default_timeout_class,
|
|
48
|
-
:timeout_options => {:foo => :bar},
|
|
49
|
-
:params => {:plop => "plip"},
|
|
50
|
-
:form => {:bar => "bar"},
|
|
51
|
-
:body => "body-bar",
|
|
52
|
-
:json => {:bar => "bar"},
|
|
53
|
-
:persistent => "https://www.googe.com",
|
|
54
|
-
:keep_alive_timeout => 10,
|
|
55
|
-
:ssl => {:foo => "bar"},
|
|
56
|
-
:headers => {"Foo" => "foo", "Accept" => "xml", "Bar" => "bar"},
|
|
57
|
-
:proxy => {:proxy_address => "127.0.0.1", :proxy_port => 8080},
|
|
58
|
-
:follow => nil,
|
|
59
|
-
:socket_class => described_class.default_socket_class,
|
|
60
|
-
:nodelay => false,
|
|
61
|
-
:ssl_socket_class => described_class.default_ssl_socket_class,
|
|
62
|
-
:ssl_context => nil,
|
|
63
|
-
:cookies => {},
|
|
64
|
-
:encoding => nil,
|
|
65
|
-
:features => {}
|
|
66
|
-
)
|
|
67
|
-
end
|
|
68
|
-
end
|