http.rb 1.3.8 → 1.3.10

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: 5cab4dfd9757c08463389bff8595489378a59ecb3149cbdfcc465ab6a508536e
4
- data.tar.gz: 5fe112a78858fc9deee9a1b8ab29cf71325a7e0801fd6b6d33e3f48835aba2dd
3
+ metadata.gz: 873748118e3dfd0adeeccf8c1fe6db2e407eb2f6c34515bbc3fafbdf332e8b7b
4
+ data.tar.gz: 9a9df13975fdacee8e5e9933e5ed31fed099fa4d0601e722a805fa60048a7cf0
5
5
  SHA512:
6
- metadata.gz: a9678a45ae024d10874c9fdd9781e785b64f2e9818c85cc991b7af6bff8f56d38d3cad1f53d606bf36ff758581a1c2106e3b38c5f88224aa6d5272833ee97482
7
- data.tar.gz: 8f9c36f7f2496a752c55a3352eb867585e787d72d63e87c8a124576b849517e213bd997d92415d2819eaac3f21a47099bef2f3a2f8e85e473aea6d8a3c9ab560
6
+ metadata.gz: 46f719719823a8e30ec6e5690973f10ab6f8ea81037d1083079a8ae574a0ed311ebb378dbf452c5667b649bf50a333497342e751677f4f35d14f27493c6f57ab
7
+ data.tar.gz: 0cc192a342f6c171d38b6338996aac5f96369e59ced845c0171048253d1ee44b5efe5bc67ec4fa19e5f9ca4d759949785156196832ff751f597d41f1ae09a5c5
data/CHANGELOG CHANGED
@@ -1,5 +1,30 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 20261011
4
+
5
+ 1.3.10: A block is yielded to once, with the response.
6
+
7
+ With a block, a followed redirect yielded the final response to it, and then yielded again whatever the block had returned, since that is what the redirected request returned and it was taken for the response: a block which returned an Array was handed that Array. With no_redirect set, the block was yielded the redirect and the redirect was then followed regardless, the branch yielding without returning, so the block was yielded to three times and a request was made which had been asked not to be.
8
+
9
+ 1. ~ HTTP.request: a followed redirect returns what the redirected request returns, which has already been yielded where there is a block, rather than yielding it again.
10
+ 2. ~ HTTP.request: no_redirect is a condition of following rather than a branch of its own, so that the redirect is yielded or returned as any other response is, and not followed.
11
+ 3. ~ test/HTTP/REDIRECT_test.rb: + one yield with the final response when a redirect is followed, and one with the redirect when no_redirect is set. Both fail against 1.3.9.
12
+ 4. ~ HTTP::VERSION: /1.3.9/1.3.10/
13
+
14
+
15
+ ## 20261011
16
+
17
+ 1.3.9: Only a 301, 302, 303, 307, or 308 with a Location is followed.
18
+
19
+ Any 3xx was taken for a redirect. A 304 Not Modified carries no Location, so URI#merge was handed nil and raised ArgumentError, as did any 3xx without one. And a 300 Multiple Choices was followed to whatever its Location named, though it is a list of choices for the caller, the Location being only the server's preference among them. These are answers rather than redirects, and are now returned as they are.
20
+
21
+ 1. ~ lib/HTTP/REDIRECT.rb: + HTTP::REDIRECT::CODES (301, 302, 303, 307, 308); + HTTP.redirect?, which is true of a response with one of those codes and a Location.
22
+ 2. ~ HTTP.request: follows what redirect? is true of, rather than whatever begins with a 3.
23
+ 3. ~ test/HTTP/REDIRECT_test.rb: + 300 and 304 returned as they are, as is a 302 without a Location. All three fail against 1.3.8: the 300 and the 304 were followed, and the 302 raised.
24
+ 4. ~ README.md: + which responses are followed, under Redirections.
25
+ 5. ~ HTTP::VERSION: /1.3.8/1.3.9/
26
+
27
+
3
28
  ## 20261011
4
29
 
5
30
  1.3.8: Headers are carried through a 301, 302, or 303.
data/README.md CHANGED
@@ -95,6 +95,8 @@ When both are supplied, the options hash wins.
95
95
 
96
96
  ### Redirections
97
97
 
98
+ 301, 302, 303, 307, and 308 responses with a `Location` are followed. Other 3xx responses, such as 300 and 304, are returned as they are.
99
+
98
100
  Redirects are followed with the headers they were given, except that `Authorization` and `Cookie`, and the `username:` and `password:` options, go no further than the origin (scheme, host, and port) they were given to. Where a redirect makes the request a GET, `Content-Type` is left behind, there being no body for it to describe.
99
101
 
100
102
  ### Preventing redirections
data/lib/HTTP/REDIRECT.rb CHANGED
@@ -3,9 +3,17 @@
3
3
 
4
4
  module HTTP
5
5
  module REDIRECT
6
+ CODES = %w{301 302 303 307 308}.freeze
6
7
  CREDENTIAL_HEADERS = %w{authorization cookie}.freeze
7
8
  end
8
9
 
10
+ # A 300 or a 304 is an answer rather than somewhere else to go, and a 3xx without a
11
+ # Location has nowhere to send it.
12
+ def redirect?(response)
13
+ REDIRECT::CODES.include?(response.code) && !response['location'].to_s.empty?
14
+ end
15
+ module_function :redirect?
16
+
9
17
  def same_origin?(a, b)
10
18
  [a.scheme, a.host, a.port] == [b.scheme, b.host, b.port]
11
19
  end
data/lib/HTTP/VERSION.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # HTTP::VERSION
3
3
 
4
4
  module HTTP
5
- VERSION = '1.3.8'
5
+ VERSION = '1.3.10'
6
6
  end
data/lib/HTTP/request.rb CHANGED
@@ -40,19 +40,14 @@ module HTTP
40
40
  http.request(request_object)
41
41
  end
42
42
  )
43
- if response.code =~ /^3/
44
- if block_given? && no_redirect
45
- yield response
46
- elsif no_redirect
47
- return response
48
- end
43
+ if !no_redirect && redirect?(response)
49
44
  redirect_uri = uri.merge(response['location'])
50
45
  onward_options = redirect_options(given_options, uri, redirect_uri)
51
46
  if response.code =~ /^30[78]$/
52
47
  data = METHODS::WITH_BODY.include?(request_method) ? request_object.body : {}
53
- response = send(request_method, redirect_uri.to_s, data, redirect_headers(headers, uri, redirect_uri), onward_options, &block)
48
+ return send(request_method, redirect_uri.to_s, data, redirect_headers(headers, uri, redirect_uri), onward_options, &block)
54
49
  else
55
- response = get(redirect_uri.to_s, {}, redirect_headers(headers, uri, redirect_uri, drop_content_type: true), onward_options, &block)
50
+ return get(redirect_uri.to_s, {}, redirect_headers(headers, uri, redirect_uri, drop_content_type: true), onward_options, &block)
56
51
  end
57
52
  end
58
53
  if block_given?
@@ -96,4 +96,37 @@ describe "redirect behaviour" do
96
96
  assert_requested(:get, other_origin_uri){|request| !request.headers.key?('Authorization')}
97
97
  end
98
98
  end
99
+
100
+ describe "3xx responses which are not followed" do
101
+ %w{300 304}.each do |code|
102
+ it "return a #{code} as it is" do
103
+ stub_request(:get, uri).to_return(status: code.to_i, headers: {'location' => other_origin_uri})
104
+ _(HTTP.get(uri).code).must_equal(code)
105
+ assert_not_requested(:get, other_origin_uri)
106
+ end
107
+ end
108
+
109
+ it "return a redirect without a Location as it is" do
110
+ stub_request(:get, uri).to_return(status: 302)
111
+ _(HTTP.get(uri).code).must_equal('302')
112
+ end
113
+ end
114
+
115
+ describe "with a block" do
116
+ it "yields once when a redirect is followed" do
117
+ stub_request(:get, uri).to_return(status: 302, headers: {'location' => other_origin_uri})
118
+ stub_request(:get, other_origin_uri).to_return(status: 200)
119
+ yielded = []
120
+ HTTP.get(uri){|response| yielded << response.code}
121
+ _(yielded).must_equal(['200'])
122
+ end
123
+
124
+ it "yields once, with the redirect, when no_redirect is set" do
125
+ stub_request(:get, uri).to_return(status: 302, headers: {'location' => other_origin_uri})
126
+ yielded = []
127
+ HTTP.get(uri, {}, {}, {no_redirect: true}){|response| yielded << response.code}
128
+ _(yielded).must_equal(['302'])
129
+ assert_not_requested(:get, other_origin_uri)
130
+ end
131
+ end
99
132
  end
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: 1.3.8
4
+ version: 1.3.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - thoran