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.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +241 -41
  3. data/LICENSE.txt +1 -1
  4. data/README.md +110 -13
  5. data/UPGRADING.md +491 -0
  6. data/http.gemspec +32 -29
  7. data/lib/http/base64.rb +11 -1
  8. data/lib/http/chainable/helpers.rb +62 -0
  9. data/lib/http/chainable/verbs.rb +136 -0
  10. data/lib/http/chainable.rb +232 -136
  11. data/lib/http/client.rb +158 -127
  12. data/lib/http/connection/internals.rb +141 -0
  13. data/lib/http/connection.rb +126 -97
  14. data/lib/http/content_type.rb +61 -6
  15. data/lib/http/errors.rb +25 -1
  16. data/lib/http/feature.rb +65 -5
  17. data/lib/http/features/auto_deflate.rb +124 -17
  18. data/lib/http/features/auto_inflate.rb +38 -15
  19. data/lib/http/features/caching/entry.rb +178 -0
  20. data/lib/http/features/caching/in_memory_store.rb +63 -0
  21. data/lib/http/features/caching.rb +216 -0
  22. data/lib/http/features/digest_auth.rb +234 -0
  23. data/lib/http/features/instrumentation.rb +97 -17
  24. data/lib/http/features/logging.rb +183 -5
  25. data/lib/http/features/normalize_uri.rb +17 -0
  26. data/lib/http/features/raise_error.rb +18 -3
  27. data/lib/http/form_data/composite_io.rb +106 -0
  28. data/lib/http/form_data/file.rb +95 -0
  29. data/lib/http/form_data/multipart/param.rb +62 -0
  30. data/lib/http/form_data/multipart.rb +106 -0
  31. data/lib/http/form_data/part.rb +52 -0
  32. data/lib/http/form_data/readable.rb +58 -0
  33. data/lib/http/form_data/urlencoded.rb +175 -0
  34. data/lib/http/form_data/version.rb +8 -0
  35. data/lib/http/form_data.rb +102 -0
  36. data/lib/http/headers/known.rb +3 -0
  37. data/lib/http/headers/normalizer.rb +17 -36
  38. data/lib/http/headers.rb +172 -65
  39. data/lib/http/mime_type/adapter.rb +24 -9
  40. data/lib/http/mime_type/json.rb +19 -4
  41. data/lib/http/mime_type.rb +21 -3
  42. data/lib/http/options/definitions.rb +189 -0
  43. data/lib/http/options.rb +172 -125
  44. data/lib/http/redirector.rb +80 -75
  45. data/lib/http/request/body.rb +87 -6
  46. data/lib/http/request/builder.rb +184 -0
  47. data/lib/http/request/proxy.rb +83 -0
  48. data/lib/http/request/writer.rb +76 -16
  49. data/lib/http/request.rb +214 -98
  50. data/lib/http/response/body.rb +103 -18
  51. data/lib/http/response/inflater.rb +35 -7
  52. data/lib/http/response/parser.rb +98 -4
  53. data/lib/http/response/status/reasons.rb +2 -4
  54. data/lib/http/response/status.rb +141 -31
  55. data/lib/http/response.rb +219 -61
  56. data/lib/http/retriable/delay_calculator.rb +38 -11
  57. data/lib/http/retriable/errors.rb +21 -0
  58. data/lib/http/retriable/performer.rb +82 -38
  59. data/lib/http/session.rb +280 -0
  60. data/lib/http/timeout/global.rb +147 -34
  61. data/lib/http/timeout/null.rb +155 -9
  62. data/lib/http/timeout/per_operation.rb +139 -18
  63. data/lib/http/uri/normalizer.rb +82 -0
  64. data/lib/http/uri/parsing.rb +182 -0
  65. data/lib/http/uri.rb +289 -124
  66. data/lib/http/version.rb +2 -1
  67. data/lib/http.rb +11 -2
  68. data/sig/deps.rbs +122 -0
  69. data/sig/http.rbs +1619 -0
  70. data/test/http/base64_test.rb +28 -0
  71. data/test/http/client_test.rb +739 -0
  72. data/test/http/connection_test.rb +1533 -0
  73. data/test/http/content_type_test.rb +190 -0
  74. data/test/http/errors_test.rb +28 -0
  75. data/test/http/feature_test.rb +49 -0
  76. data/test/http/features/auto_deflate_test.rb +317 -0
  77. data/test/http/features/auto_inflate_test.rb +213 -0
  78. data/test/http/features/caching_test.rb +942 -0
  79. data/test/http/features/digest_auth_test.rb +996 -0
  80. data/test/http/features/instrumentation_test.rb +246 -0
  81. data/test/http/features/logging_test.rb +654 -0
  82. data/test/http/features/normalize_uri_test.rb +41 -0
  83. data/test/http/features/raise_error_test.rb +77 -0
  84. data/test/http/form_data/composite_io_test.rb +215 -0
  85. data/test/http/form_data/file_test.rb +255 -0
  86. data/test/http/form_data/fixtures/the-http-gem.info +1 -0
  87. data/test/http/form_data/multipart_test.rb +303 -0
  88. data/test/http/form_data/part_test.rb +90 -0
  89. data/test/http/form_data/urlencoded_test.rb +164 -0
  90. data/test/http/form_data_test.rb +232 -0
  91. data/test/http/headers/normalizer_test.rb +93 -0
  92. data/test/http/headers_test.rb +888 -0
  93. data/test/http/mime_type/json_test.rb +39 -0
  94. data/test/http/mime_type_test.rb +150 -0
  95. data/test/http/options/base_uri_test.rb +148 -0
  96. data/test/http/options/body_test.rb +21 -0
  97. data/test/http/options/features_test.rb +38 -0
  98. data/test/http/options/form_test.rb +21 -0
  99. data/test/http/options/headers_test.rb +32 -0
  100. data/test/http/options/json_test.rb +21 -0
  101. data/test/http/options/merge_test.rb +78 -0
  102. data/test/http/options/new_test.rb +37 -0
  103. data/test/http/options/proxy_test.rb +32 -0
  104. data/test/http/options_test.rb +575 -0
  105. data/test/http/redirector_test.rb +639 -0
  106. data/test/http/request/body_test.rb +318 -0
  107. data/test/http/request/builder_test.rb +623 -0
  108. data/test/http/request/writer_test.rb +391 -0
  109. data/test/http/request_test.rb +1733 -0
  110. data/test/http/response/body_test.rb +292 -0
  111. data/test/http/response/parser_test.rb +105 -0
  112. data/test/http/response/status_test.rb +322 -0
  113. data/test/http/response_test.rb +502 -0
  114. data/test/http/retriable/delay_calculator_test.rb +194 -0
  115. data/test/http/retriable/errors_test.rb +71 -0
  116. data/test/http/retriable/performer_test.rb +551 -0
  117. data/test/http/session_test.rb +424 -0
  118. data/test/http/timeout/global_test.rb +239 -0
  119. data/test/http/timeout/null_test.rb +218 -0
  120. data/test/http/timeout/per_operation_test.rb +220 -0
  121. data/test/http/uri/normalizer_test.rb +89 -0
  122. data/test/http/uri_test.rb +1140 -0
  123. data/test/http/version_test.rb +15 -0
  124. data/test/http_test.rb +818 -0
  125. data/test/regression_tests.rb +27 -0
  126. data/test/support/dummy_server/encoding_routes.rb +47 -0
  127. data/test/support/dummy_server/routes.rb +201 -0
  128. data/test/support/dummy_server/servlet.rb +81 -0
  129. data/test/support/dummy_server.rb +200 -0
  130. data/{spec → test}/support/fakeio.rb +2 -2
  131. data/test/support/http_handling_shared/connection_reuse_tests.rb +97 -0
  132. data/test/support/http_handling_shared/timeout_tests.rb +134 -0
  133. data/test/support/http_handling_shared.rb +11 -0
  134. data/test/support/proxy_server.rb +207 -0
  135. data/test/support/servers/runner.rb +67 -0
  136. data/{spec → test}/support/simplecov.rb +11 -2
  137. data/test/support/ssl_helper.rb +108 -0
  138. data/test/test_helper.rb +38 -0
  139. metadata +108 -168
  140. data/.github/workflows/ci.yml +0 -67
  141. data/.gitignore +0 -15
  142. data/.rspec +0 -1
  143. data/.rubocop/layout.yml +0 -8
  144. data/.rubocop/metrics.yml +0 -4
  145. data/.rubocop/rspec.yml +0 -9
  146. data/.rubocop/style.yml +0 -32
  147. data/.rubocop.yml +0 -11
  148. data/.rubocop_todo.yml +0 -219
  149. data/.yardopts +0 -2
  150. data/CHANGES_OLD.md +0 -1002
  151. data/Gemfile +0 -51
  152. data/Guardfile +0 -18
  153. data/Rakefile +0 -64
  154. data/lib/http/headers/mixin.rb +0 -34
  155. data/lib/http/retriable/client.rb +0 -37
  156. data/logo.png +0 -0
  157. data/spec/lib/http/client_spec.rb +0 -556
  158. data/spec/lib/http/connection_spec.rb +0 -88
  159. data/spec/lib/http/content_type_spec.rb +0 -47
  160. data/spec/lib/http/features/auto_deflate_spec.rb +0 -77
  161. data/spec/lib/http/features/auto_inflate_spec.rb +0 -86
  162. data/spec/lib/http/features/instrumentation_spec.rb +0 -81
  163. data/spec/lib/http/features/logging_spec.rb +0 -65
  164. data/spec/lib/http/features/raise_error_spec.rb +0 -62
  165. data/spec/lib/http/headers/mixin_spec.rb +0 -36
  166. data/spec/lib/http/headers/normalizer_spec.rb +0 -52
  167. data/spec/lib/http/headers_spec.rb +0 -527
  168. data/spec/lib/http/options/body_spec.rb +0 -15
  169. data/spec/lib/http/options/features_spec.rb +0 -33
  170. data/spec/lib/http/options/form_spec.rb +0 -15
  171. data/spec/lib/http/options/headers_spec.rb +0 -24
  172. data/spec/lib/http/options/json_spec.rb +0 -15
  173. data/spec/lib/http/options/merge_spec.rb +0 -68
  174. data/spec/lib/http/options/new_spec.rb +0 -30
  175. data/spec/lib/http/options/proxy_spec.rb +0 -20
  176. data/spec/lib/http/options_spec.rb +0 -13
  177. data/spec/lib/http/redirector_spec.rb +0 -530
  178. data/spec/lib/http/request/body_spec.rb +0 -211
  179. data/spec/lib/http/request/writer_spec.rb +0 -121
  180. data/spec/lib/http/request_spec.rb +0 -234
  181. data/spec/lib/http/response/body_spec.rb +0 -85
  182. data/spec/lib/http/response/parser_spec.rb +0 -74
  183. data/spec/lib/http/response/status_spec.rb +0 -253
  184. data/spec/lib/http/response_spec.rb +0 -262
  185. data/spec/lib/http/retriable/delay_calculator_spec.rb +0 -69
  186. data/spec/lib/http/retriable/performer_spec.rb +0 -302
  187. data/spec/lib/http/uri/normalizer_spec.rb +0 -95
  188. data/spec/lib/http/uri_spec.rb +0 -71
  189. data/spec/lib/http_spec.rb +0 -535
  190. data/spec/regression_specs.rb +0 -24
  191. data/spec/spec_helper.rb +0 -89
  192. data/spec/support/black_hole.rb +0 -13
  193. data/spec/support/dummy_server/servlet.rb +0 -203
  194. data/spec/support/dummy_server.rb +0 -44
  195. data/spec/support/fuubar.rb +0 -21
  196. data/spec/support/http_handling_shared.rb +0 -190
  197. data/spec/support/proxy_server.rb +0 -39
  198. data/spec/support/servers/config.rb +0 -11
  199. data/spec/support/servers/runner.rb +0 -19
  200. data/spec/support/ssl_helper.rb +0 -104
  201. /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