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,302 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe HTTP::Retriable::Performer do
4
- let(:client) do
5
- HTTP::Client.new
6
- end
7
-
8
- let(:response) do
9
- HTTP::Response.new(
10
- status: 200,
11
- version: "1.1",
12
- headers: {},
13
- body: "Hello world!",
14
- request: request
15
- )
16
- end
17
-
18
- let(:request) do
19
- HTTP::Request.new(
20
- verb: :get,
21
- uri: "http://example.com"
22
- )
23
- end
24
-
25
- let(:perform_spy) { { counter: 0 } }
26
- let(:counter_spy) { perform_spy[:counter] }
27
-
28
- before do
29
- stub_const("CustomException", Class.new(StandardError))
30
- end
31
-
32
- def perform(options = {}, client_arg = client, request_arg = request, &block)
33
- # by explicitly overwriting the default delay, we make a much faster test suite
34
- default_options = { delay: 0 }
35
- options = default_options.merge(options)
36
-
37
- HTTP::Retriable::Performer
38
- .new(options)
39
- .perform(client_arg, request_arg) do
40
- perform_spy[:counter] += 1
41
- block ? yield : response
42
- end
43
- end
44
-
45
- def measure_wait
46
- t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
47
- result = yield
48
- t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
49
- [t2 - t1, result]
50
- end
51
-
52
- describe "#perform" do
53
- describe "expected exception" do
54
- it "retries the request" do
55
- expect do
56
- perform(exceptions: [CustomException], tries: 2) do
57
- raise CustomException
58
- end
59
- end.to raise_error HTTP::OutOfRetriesError
60
-
61
- expect(counter_spy).to eq 2
62
- end
63
- end
64
-
65
- describe "unexpected exception" do
66
- it "does not retry the request" do
67
- expect do
68
- perform(exceptions: [], tries: 2) do
69
- raise CustomException
70
- end
71
- end.to raise_error CustomException
72
-
73
- expect(counter_spy).to eq 1
74
- end
75
- end
76
-
77
- describe "expected status codes" do
78
- def response(**options)
79
- HTTP::Response.new(
80
- {
81
- status: 200,
82
- version: "1.1",
83
- headers: {},
84
- body: "Hello world!",
85
- request: request
86
- }.merge(options)
87
- )
88
- end
89
-
90
- it "retries the request" do
91
- expect do
92
- perform(retry_statuses: [200], tries: 2)
93
- end.to raise_error HTTP::OutOfRetriesError
94
-
95
- expect(counter_spy).to eq 2
96
- end
97
-
98
- describe "status codes can be expressed in many ways" do
99
- [
100
- 301,
101
- [200, 301, 485],
102
- 250...400,
103
- [250...Float::INFINITY],
104
- ->(status_code) { status_code == 301 },
105
- [->(status_code) { status_code == 301 }]
106
- ].each do |retry_statuses|
107
- it retry_statuses.to_s do
108
- expect do
109
- perform(retry_statuses: retry_statuses, tries: 2) do
110
- response(status: 301)
111
- end
112
- end.to raise_error HTTP::OutOfRetriesError
113
- end
114
- end
115
- end
116
- end
117
-
118
- describe "unexpected status code" do
119
- it "does not retry the request" do
120
- expect(
121
- perform(retry_statuses: [], tries: 2)
122
- ).to eq response
123
-
124
- expect(counter_spy).to eq 1
125
- end
126
- end
127
-
128
- describe "on_retry callback" do
129
- it "calls the on_retry callback on each retry with exception" do
130
- callback_call_spy = 0
131
-
132
- callback_spy = proc do |callback_request, error, callback_response|
133
- expect(callback_request).to eq request
134
- expect(error).to be_a HTTP::TimeoutError
135
- expect(callback_response).to be_nil
136
- callback_call_spy += 1
137
- end
138
-
139
- expect do
140
- perform(tries: 3, on_retry: callback_spy) do
141
- raise HTTP::TimeoutError
142
- end
143
- end.to raise_error HTTP::OutOfRetriesError
144
-
145
- expect(callback_call_spy).to eq 2
146
- end
147
-
148
- it "calls the on_retry callback on each retry with response" do
149
- callback_call_spy = 0
150
-
151
- callback_spy = proc do |callback_request, error, callback_response|
152
- expect(callback_request).to eq request
153
- expect(error).to be_nil
154
- expect(callback_response).to be response
155
- callback_call_spy += 1
156
- end
157
-
158
- expect do
159
- perform(retry_statuses: [200], tries: 3, on_retry: callback_spy)
160
- end.to raise_error HTTP::OutOfRetriesError
161
-
162
- expect(callback_call_spy).to eq 2
163
- end
164
- end
165
-
166
- describe "delay option" do
167
- let(:timing_slack) { 0.05 }
168
-
169
- it "can be a positive number" do
170
- time, = measure_wait do
171
- perform(delay: 0.1, tries: 3, should_retry: ->(*) { true })
172
- rescue HTTP::OutOfRetriesError
173
- end
174
- expect(time).to be_within(timing_slack).of(0.2)
175
- end
176
-
177
- it "can be a proc number" do
178
- time, = measure_wait do
179
- perform(delay: ->(attempt) { attempt / 10.0 }, tries: 3, should_retry: ->(*) { true })
180
- rescue HTTP::OutOfRetriesError
181
- end
182
- expect(time).to be_within(timing_slack).of(0.3)
183
- end
184
-
185
- it "receives correct retry number when a proc" do
186
- retry_count = 0
187
- retry_proc = proc do |attempt|
188
- expect(attempt).to eq(retry_count).and(be > 0)
189
- 0
190
- end
191
- begin
192
- perform(delay: retry_proc, should_retry: ->(*) { true }) do
193
- retry_count += 1
194
- response
195
- end
196
- rescue HTTP::OutOfRetriesError
197
- end
198
- end
199
- end
200
-
201
- describe "should_retry option" do
202
- it "decides if the request should be retried" do # rubocop:disable RSpec/MultipleExpectations
203
- retry_proc = proc do |req, err, res, attempt|
204
- expect(req).to eq request
205
- if res
206
- expect(err).to be_nil
207
- expect(res).to be response
208
- else
209
- expect(err).to be_a CustomException
210
- expect(res).to be_nil
211
- end
212
-
213
- attempt < 5
214
- end
215
-
216
- begin
217
- perform(should_retry: retry_proc) do
218
- rand < 0.5 ? response : raise(CustomException)
219
- end
220
- rescue CustomException
221
- end
222
-
223
- expect(counter_spy).to eq 5
224
- end
225
-
226
- it "raises the original error if not retryable" do
227
- retry_proc = ->(*) { false }
228
-
229
- expect do
230
- perform(should_retry: retry_proc) do
231
- raise CustomException
232
- end
233
- end.to raise_error CustomException
234
-
235
- expect(counter_spy).to eq 1
236
- end
237
-
238
- it "raises HTTP::OutOfRetriesError if retryable" do
239
- retry_proc = ->(*) { true }
240
-
241
- expect do
242
- perform(should_retry: retry_proc) do
243
- raise CustomException
244
- end
245
- end.to raise_error HTTP::OutOfRetriesError
246
-
247
- expect(counter_spy).to eq 5
248
- end
249
- end
250
- end
251
-
252
- describe "connection closing" do
253
- let(:client) { double(:client) }
254
-
255
- it "does not close the connection if we get a propper response" do
256
- expect(client).not_to receive(:close)
257
- perform
258
- end
259
-
260
- it "closes the connection after each raiseed attempt" do
261
- expect(client).to receive(:close).exactly(3).times
262
- begin
263
- perform(should_retry: ->(*) { true }, tries: 3)
264
- rescue HTTP::OutOfRetriesError
265
- end
266
- end
267
-
268
- it "closes the connection on an unexpected exception" do
269
- expect(client).to receive(:close)
270
- begin
271
- perform do
272
- raise CustomException
273
- end
274
- rescue CustomException
275
- end
276
- end
277
- end
278
-
279
- describe HTTP::OutOfRetriesError do
280
- it "has the original exception as a cause if available" do
281
- err = nil
282
- begin
283
- perform(exceptions: [CustomException]) do
284
- raise CustomException
285
- end
286
- rescue described_class => e
287
- err = e
288
- end
289
- expect(err.cause).to be_a CustomException
290
- end
291
-
292
- it "has the last raiseed response as an attribute" do
293
- err = nil
294
- begin
295
- perform(should_retry: ->(*) { true })
296
- rescue described_class => e
297
- err = e
298
- end
299
- expect(err.response).to be response
300
- end
301
- end
302
- end
@@ -1,95 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe HTTP::URI::NORMALIZER do
4
- describe "scheme" do
5
- it "lower-cases scheme" do
6
- expect(HTTP::URI::NORMALIZER.call("HttP://example.com").scheme).to eq "http"
7
- end
8
- end
9
-
10
- describe "hostname" do
11
- it "lower-cases hostname" do
12
- expect(HTTP::URI::NORMALIZER.call("http://EXAMPLE.com").host).to eq "example.com"
13
- end
14
-
15
- it "decodes percent-encoded hostname" do
16
- expect(HTTP::URI::NORMALIZER.call("http://ex%61mple.com").host).to eq "example.com"
17
- end
18
-
19
- it "removes trailing period in hostname" do
20
- expect(HTTP::URI::NORMALIZER.call("http://example.com.").host).to eq "example.com"
21
- end
22
-
23
- it "IDN-encodes non-ASCII hostname" do
24
- expect(HTTP::URI::NORMALIZER.call("http://exämple.com").host).to eq "xn--exmple-cua.com"
25
- end
26
- end
27
-
28
- describe "path" do
29
- it "ensures path is not empty" do
30
- expect(HTTP::URI::NORMALIZER.call("http://example.com").path).to eq "/"
31
- end
32
-
33
- it "preserves double slashes in path" do
34
- expect(HTTP::URI::NORMALIZER.call("http://example.com//a///b").path).to eq "//a///b"
35
- end
36
-
37
- it "resolves single-dot segments in path" do
38
- expect(HTTP::URI::NORMALIZER.call("http://example.com/a/./b").path).to eq "/a/b"
39
- end
40
-
41
- it "resolves double-dot segments in path" do
42
- expect(HTTP::URI::NORMALIZER.call("http://example.com/a/b/../c").path).to eq "/a/c"
43
- end
44
-
45
- it "resolves leading double-dot segments in path" do
46
- expect(HTTP::URI::NORMALIZER.call("http://example.com/../a/b").path).to eq "/a/b"
47
- end
48
-
49
- it "percent-encodes control characters in path" do
50
- expect(HTTP::URI::NORMALIZER.call("http://example.com/\x00\x7F\n").path).to eq "/%00%7F%0A"
51
- end
52
-
53
- it "percent-encodes space in path" do
54
- expect(HTTP::URI::NORMALIZER.call("http://example.com/a b").path).to eq "/a%20b"
55
- end
56
-
57
- it "percent-encodes non-ASCII characters in path" do
58
- expect(HTTP::URI::NORMALIZER.call("http://example.com/キョ").path).to eq "/%E3%82%AD%E3%83%A7"
59
- end
60
-
61
- it "does not percent-encode non-special characters in path" do
62
- expect(HTTP::URI::NORMALIZER.call("http://example.com/~.-_!$&()*,;=:@{}").path).to eq "/~.-_!$&()*,;=:@{}"
63
- end
64
-
65
- it "preserves escape sequences in path" do
66
- expect(HTTP::URI::NORMALIZER.call("http://example.com/%41").path).to eq "/%41"
67
- end
68
- end
69
-
70
- describe "query" do
71
- it "allows no query" do
72
- expect(HTTP::URI::NORMALIZER.call("http://example.com").query).to be_nil
73
- end
74
-
75
- it "percent-encodes control characters in query" do
76
- expect(HTTP::URI::NORMALIZER.call("http://example.com/?\x00\x7F\n").query).to eq "%00%7F%0A"
77
- end
78
-
79
- it "percent-encodes space in query" do
80
- expect(HTTP::URI::NORMALIZER.call("http://example.com/?a b").query).to eq "a%20b"
81
- end
82
-
83
- it "percent-encodes non-ASCII characters in query" do
84
- expect(HTTP::URI::NORMALIZER.call("http://example.com?キョ").query).to eq "%E3%82%AD%E3%83%A7"
85
- end
86
-
87
- it "does not percent-encode non-special characters in query" do
88
- expect(HTTP::URI::NORMALIZER.call("http://example.com/?~.-_!$&()*,;=:@{}?").query).to eq "~.-_!$&()*,;=:@{}?"
89
- end
90
-
91
- it "preserves escape sequences in query" do
92
- expect(HTTP::URI::NORMALIZER.call("http://example.com/?%41").query).to eq "%41"
93
- end
94
- end
95
- end
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe HTTP::URI do
4
- let(:example_ipv6_address) { "2606:2800:220:1:248:1893:25c8:1946" }
5
-
6
- let(:example_http_uri_string) { "http://example.com" }
7
- let(:example_https_uri_string) { "https://example.com" }
8
- let(:example_ipv6_uri_string) { "https://[#{example_ipv6_address}]" }
9
-
10
- subject(:http_uri) { described_class.parse(example_http_uri_string) }
11
- subject(:https_uri) { described_class.parse(example_https_uri_string) }
12
- subject(:ipv6_uri) { described_class.parse(example_ipv6_uri_string) }
13
-
14
- it "knows URI schemes" do
15
- expect(http_uri.scheme).to eq "http"
16
- expect(https_uri.scheme).to eq "https"
17
- end
18
-
19
- it "sets default ports for HTTP URIs" do
20
- expect(http_uri.port).to eq 80
21
- end
22
-
23
- it "sets default ports for HTTPS URIs" do
24
- expect(https_uri.port).to eq 443
25
- end
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
-
62
- describe "#dup" do
63
- it "doesn't share internal value between duplicates" do
64
- duplicated_uri = http_uri.dup
65
- duplicated_uri.host = "example.org"
66
-
67
- expect(duplicated_uri.to_s).to eq("http://example.org")
68
- expect(http_uri.to_s).to eq("http://example.com")
69
- end
70
- end
71
- end