async-http 0.59.3 → 0.59.4
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
- checksums.yaml.gz.sig +0 -0
- data/lib/async/http/relative_location.rb +60 -7
- data/lib/async/http/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdec9955ffb3564757b70e1745e2cea19a63961da0431e38eca773c22b2c6008
|
4
|
+
data.tar.gz: 2d005a43f0e8b43f25834566cbed86fbccc7cfebd6e27a64fdc69c65d0fec700
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23a2d571edf0bb0fb73277057c84f7469648dba7f0afccf24ac2e3c15f0d1d11658e831fe3ef8a11b4dd4f28469be0c94a330bbd009aeb6a3e661f5323a2cb09
|
7
|
+
data.tar.gz: da57464924efd79a5dba6b7c5366ac883d012a1aed10492a11911137cd55b809e24a757ec4481e83a45092f2bd7286aca6852376075e5b07564fdca2ae56ed99
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -23,6 +23,7 @@ require_relative 'endpoint'
|
|
23
23
|
require_relative 'reference'
|
24
24
|
|
25
25
|
require 'protocol/http/middleware'
|
26
|
+
require 'protocol/http/body/rewindable'
|
26
27
|
|
27
28
|
module Async
|
28
29
|
module HTTP
|
@@ -30,8 +31,28 @@ module Async
|
|
30
31
|
end
|
31
32
|
|
32
33
|
# A client wrapper which transparently handles both relative and absolute redirects to a given maximum number of hops.
|
34
|
+
#
|
35
|
+
# The best reference for these semantics is defined by the [Fetch specification](https://fetch.spec.whatwg.org/#http-redirect-fetch).
|
36
|
+
#
|
37
|
+
# | Redirect using GET | Permanent | Temporary |
|
38
|
+
# |:-----------------------------------------:|:---------:|:---------:|
|
39
|
+
# | Allowed | 301 | 302 |
|
40
|
+
# | Preserve original method | 308 | 307 |
|
41
|
+
#
|
42
|
+
# For the specific details of the redirect handling, see:
|
43
|
+
# - <https://datatracker.ietf.org/doc/html/rfc7231#section-6-4-2> 301 Moved Permanently.
|
44
|
+
# - <https://datatracker.ietf.org/doc/html/rfc7231#section-6-4-3> 302 Found.
|
45
|
+
# - <https://datatracker.ietf.org/doc/html/rfc7538 308 Permanent Redirect.
|
46
|
+
# - <https://datatracker.ietf.org/doc/html/rfc7231#section-6-4-7> 307 Temporary Redirect.
|
47
|
+
#
|
33
48
|
class RelativeLocation < ::Protocol::HTTP::Middleware
|
34
|
-
|
49
|
+
# Header keys which should be deleted when changing a request from a POST to a GET as defined by <https://fetch.spec.whatwg.org/#request-body-header-name>.
|
50
|
+
PROHIBITED_GET_HEADERS = [
|
51
|
+
'content-encoding',
|
52
|
+
'content-language',
|
53
|
+
'content-location',
|
54
|
+
'content-type',
|
55
|
+
]
|
35
56
|
|
36
57
|
# maximum_hops is the max number of redirects. Set to 0 to allow 1 request with no redirects.
|
37
58
|
def initialize(app, maximum_hops = 3)
|
@@ -43,20 +64,39 @@ module Async
|
|
43
64
|
# The maximum number of hops which will limit the number of redirects until an error is thrown.
|
44
65
|
attr :maximum_hops
|
45
66
|
|
67
|
+
def redirect_with_get?(request, response)
|
68
|
+
# We only want to switch to GET if the request method is something other than get, e.g. POST.
|
69
|
+
if request.method != GET
|
70
|
+
# According to the RFC, we should only switch to GET if the response is a 301 or 302:
|
71
|
+
return response.status == 301 || response.status == 302
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
46
75
|
def call(request)
|
47
|
-
|
76
|
+
# We don't want to follow redirects for HEAD requests:
|
77
|
+
return super if request.head?
|
78
|
+
|
79
|
+
if body = request.body
|
80
|
+
# We need to cache the body as it might be submitted multiple times if we get a response status of 307 or 308:
|
81
|
+
body = ::Protocol::HTTP::Body::Rewindable.new(body)
|
82
|
+
request.body = body
|
83
|
+
end
|
48
84
|
|
49
|
-
|
50
|
-
request.finish
|
85
|
+
hops = 0
|
51
86
|
|
52
87
|
while hops <= @maximum_hops
|
53
88
|
response = super(request)
|
54
89
|
|
55
90
|
if response.redirection?
|
56
91
|
hops += 1
|
92
|
+
|
93
|
+
# Get the redirect location:
|
94
|
+
unless location = response.headers['location']
|
95
|
+
return response
|
96
|
+
end
|
97
|
+
|
57
98
|
response.finish
|
58
99
|
|
59
|
-
location = response.headers['location']
|
60
100
|
uri = URI.parse(location)
|
61
101
|
|
62
102
|
if uri.absolute?
|
@@ -65,8 +105,21 @@ module Async
|
|
65
105
|
request.path = Reference[request.path] + location
|
66
106
|
end
|
67
107
|
|
68
|
-
|
69
|
-
|
108
|
+
if request.method == GET or response.preserve_method?
|
109
|
+
# We (might) need to rewind the body so that it can be submitted again:
|
110
|
+
body&.rewind
|
111
|
+
else
|
112
|
+
# We are changing the method to GET:
|
113
|
+
request.method = GET
|
114
|
+
|
115
|
+
# Clear the request body:
|
116
|
+
request.finish
|
117
|
+
body = nil
|
118
|
+
|
119
|
+
# Remove any headers which are not allowed in a GET request:
|
120
|
+
PROHIBITED_GET_HEADERS.each do |header|
|
121
|
+
request.headers.delete(header)
|
122
|
+
end
|
70
123
|
end
|
71
124
|
else
|
72
125
|
return response
|
data/lib/async/http/version.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-http
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.59.
|
4
|
+
version: 0.59.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -52,7 +52,7 @@ cert_chain:
|
|
52
52
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
53
53
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
54
54
|
-----END CERTIFICATE-----
|
55
|
-
date: 2022-
|
55
|
+
date: 2022-12-13 00:00:00.000000000 Z
|
56
56
|
dependencies:
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: async
|
metadata.gz.sig
CHANGED
Binary file
|