async-http 0.59.3 → 0.59.5

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: ccef95a0cce84077c1782720ea14a582822ef0431d60fa98303b88437d072636
4
- data.tar.gz: 397a5e8ed0cb1d4ed5ca58190e1c7ab344cabfff040d90df57fe1c49c1ca5360
3
+ metadata.gz: 173740367554634a3d29a3624b5750bad44e8f5f6e03bab869713c13757c3aa0
4
+ data.tar.gz: 331c000cd4e00ff460ad48b168781cf072e4bbde278da3c9af22f42ff0ff979d
5
5
  SHA512:
6
- metadata.gz: 8e0194004b779c0107157cae272fbd9f3c75a050736b2c682d82507a26a88c7dd15e74dc1f3ca1e513ba8f2c1d0697103acf5a5edf172e617c5833cb11094dde
7
- data.tar.gz: 3c19cffb3030cf3b6b88091ef6818cf0339f01f5f52e6e35c704d9228d2b961af47f51d74995a7f83c19f1aa8405979d93cd612f8cd67d70492c71b02207c945
6
+ metadata.gz: a809094366e9758ff1a2c7325f5d0b3038521a17533b46a6c8715de8ba70c961a9d221a44d35a3d9ab7acf48f49cef2bed5c0b1337c024830490cd8e35d02604
7
+ data.tar.gz: c869fa3bac9c39a8d17ed4df89fe360cddf649d86135667ffce59d1402278e3e56eb14db2febf1f6e56899ce23c8d88e9339f4d10753e778a5df2036397a3145
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
- DEFAULT_METHOD = GET
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
- hops = 0
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
- # We need to cache the body as it might be submitted multiple times.
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
- unless response.preserve_method?
69
- request.method = DEFAULT_METHOD
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
@@ -22,6 +22,6 @@
22
22
 
23
23
  module Async
24
24
  module HTTP
25
- VERSION = "0.59.3"
25
+ VERSION = "0.59.5"
26
26
  end
27
27
  end
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.3
4
+ version: 0.59.5
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-11-10 00:00:00.000000000 Z
55
+ date: 2023-01-28 00:00:00.000000000 Z
56
56
  dependencies:
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: async
@@ -102,14 +102,14 @@ dependencies:
102
102
  requirements:
103
103
  - - "~>"
104
104
  - !ruby/object:Gem::Version
105
- version: 0.23.1
105
+ version: '0.23'
106
106
  type: :runtime
107
107
  prerelease: false
108
108
  version_requirements: !ruby/object:Gem::Requirement
109
109
  requirements:
110
110
  - - "~>"
111
111
  - !ruby/object:Gem::Version
112
- version: 0.23.1
112
+ version: '0.23'
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: protocol-http1
115
115
  requirement: !ruby/object:Gem::Requirement
@@ -301,7 +301,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
301
301
  - !ruby/object:Gem::Version
302
302
  version: '0'
303
303
  requirements: []
304
- rubygems_version: 3.3.7
304
+ rubygems_version: 3.4.1
305
305
  signing_key:
306
306
  specification_version: 4
307
307
  summary: A HTTP client and server library.
metadata.gz.sig CHANGED
Binary file