http.rb 0.18.1 → 0.18.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3cf46d2fcd2e4e18c1bd5fb1245da1156b14d694871970fb6d827d5a79f2a533
4
- data.tar.gz: 786e1c2b4fc5314e2626f466bfd249d7a24ea80b607ed0f3c67333c6220147e2
3
+ metadata.gz: 4bfdcd1317baede9f978ecc2090b816da19fd76531ab759ff685ffc42e237297
4
+ data.tar.gz: a4ea5421285e8a5b1b702b33be58de8be2e8984963b238b81679fdbca118eeec
5
5
  SHA512:
6
- metadata.gz: 86963812021231537e441627cbe6e617920409c465010296e4f513f838c40df51005edfc25083ad03348566de02c94a80ae9a3ccfa26c956abe00274425857aa
7
- data.tar.gz: d5b6e217124fffa5ee8a23e78c316e9d8bbce7cfe8523613923ac18b34bfa74e003a21294b793ddca56785261ea8f765e158adae3b83663d732aa19c12c38fcc
6
+ metadata.gz: 5dbf7b38407e2bcc6932efdee8b36ee4994cdfc420edcb6d2c7f39d9a7c407af2c2b786424d0b33123e4538b7aa094e7ed0ea5597d1afbe392aad913b29e890c
7
+ data.tar.gz: ad271ead133a0f244d4f1538ee78aa2f6595c0a0c7be47bbf5d965f8768136f579354a1d4015754e0d60e922e64ade6cbc9043213d63d006c50e140e3c196553
data/CHANGELOG CHANGED
@@ -1,5 +1,25 @@
1
1
  # CHANGELOG
2
2
 
3
+ # 20260521
4
+ # 0.18.3: Fix verb preservation on 307/308 redirects.
5
+ 1. ~ HTTP.request: Use original verb when following 307 or 308 redirects, per RFC 7231 §6.4.7 and RFC 7538. 301/302/303 keep legacy GET-on-redirect behaviour.
6
+ 2. ~ spec/HTTP/post_spec.rb: + specs for 307/308 verb preservation and 307 body preservation.
7
+ 3. ~ spec/HTTP/put_spec.rb: + spec for 307 verb preservation.
8
+ 4. ~ spec/HTTP/delete_spec.rb: + spec for 307 verb preservation.
9
+ 5. ~ spec/spec_helper.rb: Skip webmock's http_rb adapter, which collides with this gem's HTTP module on case-insensitive filesystems.
10
+ 6. ~ HTTP::VERSION: /0.18.2/0.18.3/
11
+ 7. ~ CHANGELOG: + 0.18.3 entry
12
+
13
+ # 20260520
14
+ # 0.18.2: Fix relative redirect URL construction.
15
+ 1. ~ HTTP.request: Use URI#merge for redirect URL construction. Preserves original scheme, elides default ports, and resolves relative paths per RFC 3986.
16
+ 2. ~ spec/HTTP/get_spec.rb: Update relative-redirect stubs to elide default port; + context for HTTPS relative redirect.
17
+ 3. ~ spec/HTTP/post_spec.rb: Update relative-redirect stubs to elide default port.
18
+ 4. ~ spec/HTTP/put_spec.rb: Update relative-redirect stubs to elide default port.
19
+ 5. ~ spec/HTTP/delete_spec.rb: Update relative-redirect stubs to elide default port.
20
+ 6. ~ HTTP::VERSION: /0.18.1/0.18.2/
21
+ 7. ~ CHANGELOG: + 0.18.2 entry
22
+
3
23
  # 20260508
4
24
  # 0.18.1: Remove incorrectly added WebDAV verbs.
5
25
  1. - lib/Net/HTTP/Report.rb
data/lib/HTTP/VERSION.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # HTTP::VERSION
3
3
 
4
4
  module HTTP
5
- VERSION = '0.18.1'
5
+ VERSION = '0.18.3'
6
6
  end
data/lib/HTTP/request.rb CHANGED
@@ -27,12 +27,13 @@ module HTTP
27
27
  elsif no_redirect
28
28
  return response
29
29
  end
30
- redirect_uri = URI.parse(response.header['location'])
31
- if redirect_uri.scheme
32
- response = get(response.header['location'], {}, {}, options, &block)
30
+ redirect_uri = uri.merge(response.header['location'])
31
+ if response.code =~ /^30[78]$/
32
+ verb = request_object.method.downcase.to_sym
33
+ data = VERBS::WITH_BODY.include?(verb) ? request_object.body : {}
34
+ response = send(verb, redirect_uri.to_s, data, headers, options, &block)
33
35
  else
34
- new_location = "http://#{uri.host}:#{uri.port}#{response.header['location']}"
35
- response = get(new_location, {}, {}, options, &block)
36
+ response = get(redirect_uri.to_s, {}, {}, options, &block)
36
37
  end
37
38
  end
38
39
  if block_given?
@@ -173,7 +173,7 @@ describe ".delete" do
173
173
  context "with path only redirection" do
174
174
  let(:request_uri){'http://example.com/path'}
175
175
  let(:redirect_path){'/new_path'}
176
- let(:redirect_uri){"http://example.com:80#{redirect_path}"}
176
+ let(:redirect_uri){"http://example.com#{redirect_path}"}
177
177
 
178
178
  before do
179
179
  stub_request(:get, redirect_uri).
@@ -212,6 +212,27 @@ describe ".delete" do
212
212
  end
213
213
  end
214
214
 
215
+ context "with verb-preserving redirection via 307" do
216
+ let(:request_uri){'http://example.com/path'}
217
+ let(:redirect_uri){'http://redirected.com'}
218
+
219
+ before do
220
+ stub_request(:delete, request_uri).
221
+ with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
222
+ to_return(status: 307, body: '', headers: {'location' => redirect_uri})
223
+ stub_request(:delete, redirect_uri).
224
+ with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
225
+ to_return(status: 200, body: '', headers: {})
226
+ end
227
+
228
+ it "preserves the verb" do
229
+ expect(HTTP).to receive(:delete).with(request_uri).and_call_original.ordered
230
+ expect(HTTP).to receive(:delete).with(redirect_uri, {}, {}, {use_ssl: false, verify_mode: 0}).and_call_original.ordered
231
+ response = HTTP.delete(request_uri)
232
+ expect(response.success?).to eq(true)
233
+ end
234
+ end
235
+
215
236
  context "no_redirect true" do
216
237
  let(:request_uri){'http://example.com/path'}
217
238
  let(:redirect_uri){'http://redirected.com'}
@@ -173,7 +173,7 @@ describe ".get" do
173
173
  context "with path only redirection" do
174
174
  let(:request_uri){'http://example.com/path'}
175
175
  let(:redirect_path){'/new_path'}
176
- let(:redirect_uri){"http://example.com:80#{redirect_path}"}
176
+ let(:redirect_uri){"http://example.com#{redirect_path}"}
177
177
 
178
178
  before do
179
179
  stub_request(:get, redirect_uri).
@@ -212,6 +212,28 @@ describe ".get" do
212
212
  end
213
213
  end
214
214
 
215
+ context "with path only redirection from HTTPS" do
216
+ let(:request_uri){'https://example.com/path'}
217
+ let(:redirect_path){'/new_path'}
218
+ let(:redirect_uri){"https://example.com#{redirect_path}"}
219
+
220
+ before do
221
+ stub_request(:get, redirect_uri).
222
+ with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
223
+ to_return(status: 200, body: '', headers: {})
224
+ stub_request(:get, request_uri).
225
+ with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
226
+ to_return(status: 301, body: '', headers: {'location' => redirect_path})
227
+ end
228
+
229
+ it "preserves the HTTPS scheme on a relative redirect" do
230
+ expect(HTTP).to receive(:get).once.with(request_uri).and_call_original
231
+ expect(HTTP).to receive(:get).once.with(redirect_uri, {}, {}, {use_ssl: true, verify_mode: 0}).and_call_original
232
+ response = HTTP.get(request_uri)
233
+ expect(response.success?).to eq(true)
234
+ end
235
+ end
236
+
215
237
  context "no_redirect true" do
216
238
  let(:request_uri){'http://example.com/path'}
217
239
  let(:redirect_uri){'http://redirected.com'}
@@ -311,7 +311,7 @@ describe ".post" do
311
311
  context "with path only redirection" do
312
312
  let(:request_uri){'http://example.com/path'}
313
313
  let(:redirect_path){'/new_path'}
314
- let(:redirect_uri){"http://example.com:80#{redirect_path}"}
314
+ let(:redirect_uri){"http://example.com#{redirect_path}"}
315
315
 
316
316
  before do
317
317
  stub_request(:get, redirect_uri).
@@ -350,6 +350,68 @@ describe ".post" do
350
350
  end
351
351
  end
352
352
 
353
+ context "with verb-preserving redirection" do
354
+ let(:request_uri){'http://example.com/path'}
355
+ let(:redirect_uri){'http://redirected.com'}
356
+
357
+ before do
358
+ stub_request(:post, redirect_uri).
359
+ with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
360
+ to_return(status: 200, body: '', headers: {})
361
+ end
362
+
363
+ context "via 307" do
364
+ before do
365
+ stub_request(:post, request_uri).
366
+ with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
367
+ to_return(status: 307, body: '', headers: {'location' => redirect_uri})
368
+ end
369
+
370
+ it "preserves the verb" do
371
+ expect(HTTP).to receive(:post).with(request_uri).and_call_original.ordered
372
+ expect(HTTP).to receive(:post).with(redirect_uri, '', {}, {use_ssl: false, verify_mode: 0}).and_call_original.ordered
373
+ response = HTTP.post(request_uri)
374
+ expect(response.success?).to eq(true)
375
+ end
376
+ end
377
+
378
+ context "via 308" do
379
+ before do
380
+ stub_request(:post, request_uri).
381
+ with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
382
+ to_return(status: 308, body: '', headers: {'location' => redirect_uri})
383
+ end
384
+
385
+ it "preserves the verb" do
386
+ expect(HTTP).to receive(:post).with(request_uri).and_call_original.ordered
387
+ expect(HTTP).to receive(:post).with(redirect_uri, '', {}, {use_ssl: false, verify_mode: 0}).and_call_original.ordered
388
+ response = HTTP.post(request_uri)
389
+ expect(response.success?).to eq(true)
390
+ end
391
+ end
392
+ end
393
+
394
+ context "with body-preserving redirection via 307" do
395
+ let(:request_uri){'http://example.com/path'}
396
+ let(:redirect_uri){'http://redirected.com'}
397
+ let(:args) do; {a: 1, b: 2}; end
398
+ let(:encoded_form_data){args.x_www_form_urlencode}
399
+
400
+ before do
401
+ stub_request(:post, request_uri).
402
+ with(body: encoded_form_data).
403
+ to_return(status: 307, body: '', headers: {'location' => redirect_uri})
404
+ stub_request(:post, redirect_uri).
405
+ with(body: encoded_form_data).
406
+ to_return(status: 200, body: '', headers: {})
407
+ end
408
+
409
+ it "preserves the body" do
410
+ response = HTTP.post(request_uri, args)
411
+ expect(response.success?).to eq(true)
412
+ end
413
+ end
414
+
353
415
  context "no_redirect true" do
354
416
  let(:request_uri){'http://example.com/path'}
355
417
  let(:redirect_uri){'http://redirected.com'}
@@ -311,7 +311,7 @@ describe ".put" do
311
311
  context "with path only redirection" do
312
312
  let(:request_uri){'http://example.com/path'}
313
313
  let(:redirect_path){'/new_path'}
314
- let(:redirect_uri){"http://example.com:80#{redirect_path}"}
314
+ let(:redirect_uri){"http://example.com#{redirect_path}"}
315
315
 
316
316
  before do
317
317
  stub_request(:get, redirect_uri).
@@ -350,6 +350,27 @@ describe ".put" do
350
350
  end
351
351
  end
352
352
 
353
+ context "with verb-preserving redirection via 307" do
354
+ let(:request_uri){'http://example.com/path'}
355
+ let(:redirect_uri){'http://redirected.com'}
356
+
357
+ before do
358
+ stub_request(:put, request_uri).
359
+ with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
360
+ to_return(status: 307, body: '', headers: {'location' => redirect_uri})
361
+ stub_request(:put, redirect_uri).
362
+ with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
363
+ to_return(status: 200, body: '', headers: {})
364
+ end
365
+
366
+ it "preserves the verb" do
367
+ expect(HTTP).to receive(:put).with(request_uri).and_call_original.ordered
368
+ expect(HTTP).to receive(:put).with(redirect_uri, '', {}, {use_ssl: false, verify_mode: 0}).and_call_original.ordered
369
+ response = HTTP.put(request_uri)
370
+ expect(response.success?).to eq(true)
371
+ end
372
+ end
373
+
353
374
  context "no_redirect true" do
354
375
  let(:request_uri){'http://example.com/path'}
355
376
  let(:redirect_uri){'http://redirected.com'}
data/spec/spec_helper.rb CHANGED
@@ -3,4 +3,13 @@
3
3
  lib_dir = File.expand_path(File.join(__FILE__, '..', '..', 'lib'))
4
4
  $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
5
5
 
6
+ # Skip webmock's http_rb adapter: it auto-requires 'http', which collides
7
+ # with this gem's lib/HTTP.rb on case-insensitive filesystems and crashes
8
+ # while trying to monkey-patch the wrong HTTP module.
9
+ gem 'webmock'
10
+ $LOADED_FEATURES << File.join(
11
+ Gem.loaded_specs['webmock'].full_gem_path,
12
+ 'lib/webmock/http_lib_adapters/http_rb_adapter.rb'
13
+ )
14
+
6
15
  require 'webmock/rspec'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.1
4
+ version: 0.18.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - thoran
@@ -79,6 +79,7 @@ files:
79
79
  - README.md
80
80
  - Rakefile
81
81
  - http.rb.gemspec
82
+ - lib/HTTP.rb
82
83
  - lib/HTTP/VERSION.rb
83
84
  - lib/HTTP/request.rb
84
85
  - lib/HTTP/verbs.rb
@@ -92,7 +93,6 @@ files:
92
93
  - lib/Thoran/Array/FirstX/firstX.rb
93
94
  - lib/Thoran/String/ToConst/to_const.rb
94
95
  - lib/URI/Generic/use_sslQ.rb
95
- - lib/http.rb
96
96
  - spec/HTTP/delete_spec.rb
97
97
  - spec/HTTP/get_spec.rb
98
98
  - spec/HTTP/head_spec.rb
@@ -117,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
117
  - !ruby/object:Gem::Version
118
118
  version: '0'
119
119
  requirements: []
120
- rubygems_version: 4.0.11
120
+ rubygems_version: 4.0.12
121
121
  specification_version: 4
122
122
  summary: HTTP made easy.
123
123
  test_files: []
File without changes