async-http 0.85.0 → 0.87.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/async/http/protocol/http1/client.rb +11 -2
- data/lib/async/http/protocol/http1/request.rb +29 -5
- data/lib/async/http/protocol/http2/request.rb +2 -2
- data/lib/async/http/protocol/http2/response.rb +5 -2
- data/lib/async/http/protocol/http2.rb +2 -0
- data/lib/async/http/proxy.rb +2 -2
- data/lib/async/http/version.rb +1 -1
- data/license.md +1 -1
- data/readme.md +8 -0
- data/releases.md +28 -0
- data.tar.gz.sig +0 -0
- metadata +20 -25
- metadata.gz.sig +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fb9ca49f85d321261c3a3ee9cccf0459841fc09e5df5981289c6d4a6dc6a973
|
4
|
+
data.tar.gz: 2a8310e595b65f51001f0b871de5992476153cd0de3eb175d1060e7743ffe6d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b2c843acae23369e6fcffffea81ee443bac6caa2bb21acd80a72af00a831326700e0b0c6e57128f300b11bcbaf435f03e59a84c3de17c59b170241a0dce0cfb
|
7
|
+
data.tar.gz: b851a56d637736f82cc48b68c00ca4562daa9756548792d4f41c21771150e6b1bd1385eb429cfa43937936454d4719e3535f9273254dc81e26880ce30aa3eeb6
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2018-
|
4
|
+
# Copyright, 2018-2025, by Samuel Williams.
|
5
5
|
|
6
6
|
require_relative "connection"
|
7
7
|
|
@@ -39,7 +39,16 @@ module Async
|
|
39
39
|
|
40
40
|
# We carefully interpret https://tools.ietf.org/html/rfc7230#section-6.3.1 to implement this correctly.
|
41
41
|
begin
|
42
|
-
|
42
|
+
target = request.path
|
43
|
+
authority = request.authority
|
44
|
+
|
45
|
+
# If we are using a CONNECT request, we need to use the authority as the target:
|
46
|
+
if request.connect?
|
47
|
+
target = authority
|
48
|
+
authority = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
write_request(authority, request.method, target, @version, request.headers)
|
43
52
|
rescue
|
44
53
|
# If we fail to fully write the request and body, we can retry this request.
|
45
54
|
raise RequestFailed
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2018-
|
4
|
+
# Copyright, 2018-2025, by Samuel Williams.
|
5
5
|
|
6
6
|
require_relative "../request"
|
7
7
|
|
@@ -10,21 +10,45 @@ module Async
|
|
10
10
|
module Protocol
|
11
11
|
module HTTP1
|
12
12
|
class Request < Protocol::Request
|
13
|
+
def self.valid_path?(target)
|
14
|
+
if target.start_with?("/")
|
15
|
+
return true
|
16
|
+
elsif target == "*"
|
17
|
+
return true
|
18
|
+
else
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
URI_PATTERN = %r{\A(?<scheme>[^:/]+)://(?<authority>[^/]+)(?<path>.*)\z}
|
24
|
+
|
13
25
|
def self.read(connection)
|
14
|
-
|
15
|
-
|
26
|
+
connection.read_request do |authority, method, target, version, headers, body|
|
27
|
+
if method == ::Protocol::HTTP::Methods::CONNECT
|
28
|
+
# We put the target into the authority field for CONNECT requests, as per HTTP/2 semantics.
|
29
|
+
self.new(connection, nil, target, method, nil, version, headers, body)
|
30
|
+
elsif valid_path?(target)
|
31
|
+
# This is a valid request.
|
32
|
+
self.new(connection, nil, authority, method, target, version, headers, body)
|
33
|
+
elsif match = target.match(URI_PATTERN)
|
34
|
+
# We map the incoming absolute URI target to the scheme, authority, and path fields of the request.
|
35
|
+
self.new(connection, match[:scheme], match[:authority], method, match[:path], version, headers, body)
|
36
|
+
else
|
37
|
+
# This is an invalid request.
|
38
|
+
raise ::Protocol::HTTP1::BadRequest.new("Invalid request target: #{target}")
|
39
|
+
end
|
16
40
|
end
|
17
41
|
end
|
18
42
|
|
19
43
|
UPGRADE = "upgrade"
|
20
44
|
|
21
|
-
def initialize(connection, authority, method, path, version, headers, body)
|
45
|
+
def initialize(connection, scheme, authority, method, path, version, headers, body)
|
22
46
|
@connection = connection
|
23
47
|
|
24
48
|
# HTTP/1 requests with an upgrade header (which can contain zero or more values) are extracted into the protocol field of the request, and we expect a response to select one of those protocols with a status code of 101 Switching Protocols.
|
25
49
|
protocol = headers.delete("upgrade")
|
26
50
|
|
27
|
-
super(
|
51
|
+
super(scheme, authority, method, path, version, headers, body, protocol, self.public_method(:write_interim_response))
|
28
52
|
end
|
29
53
|
|
30
54
|
def connection
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2018-
|
4
|
+
# Copyright, 2018-2025, by Samuel Williams.
|
5
5
|
|
6
6
|
require_relative "../request"
|
7
7
|
require_relative "stream"
|
@@ -99,7 +99,7 @@ module Async
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def valid?
|
102
|
-
@scheme and @method and @path
|
102
|
+
@scheme and @method and (@path or @method == ::Protocol::HTTP::Methods::CONNECT)
|
103
103
|
end
|
104
104
|
|
105
105
|
def hijack?
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2018-
|
4
|
+
# Copyright, 2018-2025, by Samuel Williams.
|
5
5
|
|
6
6
|
require_relative "../response"
|
7
7
|
require_relative "stream"
|
@@ -204,9 +204,12 @@ module Async
|
|
204
204
|
pseudo_headers = [
|
205
205
|
[SCHEME, request.scheme],
|
206
206
|
[METHOD, request.method],
|
207
|
-
[PATH, request.path],
|
208
207
|
]
|
209
208
|
|
209
|
+
if path = request.path
|
210
|
+
pseudo_headers << [PATH, path]
|
211
|
+
end
|
212
|
+
|
210
213
|
# To ensure that the HTTP/1.1 request line can be reproduced accurately, this pseudo-header field MUST be omitted when translating from an HTTP/1.1 request that has a request target in origin or asterisk form (see [RFC7230], Section 5.3). Clients that generate HTTP/2 requests directly SHOULD use the :authority pseudo-header field instead of the Host header field.
|
211
214
|
if authority = request.authority
|
212
215
|
pseudo_headers << [AUTHORITY, authority]
|
@@ -27,6 +27,7 @@ module Async
|
|
27
27
|
::Protocol::HTTP2::Settings::ENABLE_PUSH => 0,
|
28
28
|
::Protocol::HTTP2::Settings::MAXIMUM_FRAME_SIZE => 0x100000,
|
29
29
|
::Protocol::HTTP2::Settings::INITIAL_WINDOW_SIZE => 0x800000,
|
30
|
+
::Protocol::HTTP2::Settings::NO_RFC7540_PRIORITIES => 1,
|
30
31
|
}
|
31
32
|
|
32
33
|
SERVER_SETTINGS = {
|
@@ -35,6 +36,7 @@ module Async
|
|
35
36
|
::Protocol::HTTP2::Settings::MAXIMUM_FRAME_SIZE => 0x100000,
|
36
37
|
::Protocol::HTTP2::Settings::INITIAL_WINDOW_SIZE => 0x800000,
|
37
38
|
::Protocol::HTTP2::Settings::ENABLE_CONNECT_PROTOCOL => 1,
|
39
|
+
::Protocol::HTTP2::Settings::NO_RFC7540_PRIORITIES => 1,
|
38
40
|
}
|
39
41
|
|
40
42
|
def self.client(peer, settings = CLIENT_SETTINGS)
|
data/lib/async/http/proxy.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-
|
4
|
+
# Copyright, 2019-2025, by Samuel Williams.
|
5
5
|
|
6
6
|
require_relative "client"
|
7
7
|
require_relative "endpoint"
|
@@ -82,7 +82,7 @@ module Async
|
|
82
82
|
def connect(&block)
|
83
83
|
input = Body::Writable.new
|
84
84
|
|
85
|
-
response = @client.connect(@address
|
85
|
+
response = @client.connect(authority: @address, headers: @headers, body: input)
|
86
86
|
|
87
87
|
if response.success?
|
88
88
|
pipe = Body::Pipe.new(response.body, input)
|
data/lib/async/http/version.rb
CHANGED
data/license.md
CHANGED
data/readme.md
CHANGED
@@ -16,6 +16,14 @@ Please see the [project documentation](https://socketry.github.io/async-http/) f
|
|
16
16
|
|
17
17
|
Please see the [project releases](https://socketry.github.io/async-http/releases/index) for all releases.
|
18
18
|
|
19
|
+
### v0.87.0
|
20
|
+
|
21
|
+
- [Unify HTTP/1 and HTTP/2 `CONNECT` semantics](https://socketry.github.io/async-http/releases/index#unify-http/1-and-http/2-connect-semantics)
|
22
|
+
|
23
|
+
### v0.86.0
|
24
|
+
|
25
|
+
- Add support for HTTP/2 `NO_RFC7540_PRIORITIES`. See <https://www.rfc-editor.org/rfc/rfc9218.html> for more details.
|
26
|
+
|
19
27
|
### v0.84.0
|
20
28
|
|
21
29
|
- Minor consistency fixes to `Async::HTTP::Internet` singleton methods.
|
data/releases.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# Releases
|
2
2
|
|
3
|
+
## v0.87.0
|
4
|
+
|
5
|
+
### Unify HTTP/1 and HTTP/2 `CONNECT` semantics
|
6
|
+
|
7
|
+
HTTP/1 has a request line "target" which takes different forms depending on the kind of request. For `CONNECT` requests, the target is the authority (host and port) of the target server, e.g.
|
8
|
+
|
9
|
+
CONNECT example.com:443 HTTP/1.1
|
10
|
+
|
11
|
+
In HTTP/2, the `CONNECT` method uses the `:authority` pseudo-header to specify the target, e.g.
|
12
|
+
|
13
|
+
``` http
|
14
|
+
[HEADERS FRAME]
|
15
|
+
:method: connect
|
16
|
+
:authority: example.com:443
|
17
|
+
```
|
18
|
+
|
19
|
+
In HTTP/1, the `Request#path` attribute was previously used to store the target, and this was incorrectly mapped to the `:path` pseudo-header in HTTP/2. This has been corrected, and the `Request#authority` attribute is now used to store the target for both HTTP/1 and HTTP/2, and mapped accordingly. Thus, to make a `CONNECT` request, you should set the `Request#authority` attribute, e.g.
|
20
|
+
|
21
|
+
``` ruby
|
22
|
+
response = client.connect(authority: "example.com:443")
|
23
|
+
```
|
24
|
+
|
25
|
+
For HTTP/1, the authority is mapped back to the request line target, and for HTTP/2, it is mapped to the `:authority` pseudo-header.
|
26
|
+
|
27
|
+
## v0.86.0
|
28
|
+
|
29
|
+
- Add support for HTTP/2 `NO_RFC7540_PRIORITIES`. See <https://www.rfc-editor.org/rfc/rfc9218.html> for more details.
|
30
|
+
|
3
31
|
## v0.84.0
|
4
32
|
|
5
33
|
- Minor consistency fixes to `Async::HTTP::Internet` singleton methods.
|
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.
|
4
|
+
version: 0.87.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -26,7 +26,6 @@ authors:
|
|
26
26
|
- Trevor Turk
|
27
27
|
- Viacheslav Koval
|
28
28
|
- dependabot[bot]
|
29
|
-
autorequire:
|
30
29
|
bindir: bin
|
31
30
|
cert_chain:
|
32
31
|
- |
|
@@ -58,7 +57,7 @@ cert_chain:
|
|
58
57
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
59
58
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
60
59
|
-----END CERTIFICATE-----
|
61
|
-
date:
|
60
|
+
date: 2025-01-29 00:00:00.000000000 Z
|
62
61
|
dependencies:
|
63
62
|
- !ruby/object:Gem::Dependency
|
64
63
|
name: async
|
@@ -117,77 +116,75 @@ dependencies:
|
|
117
116
|
- !ruby/object:Gem::Version
|
118
117
|
version: '0.6'
|
119
118
|
- !ruby/object:Gem::Dependency
|
120
|
-
name:
|
119
|
+
name: metrics
|
121
120
|
requirement: !ruby/object:Gem::Requirement
|
122
121
|
requirements:
|
123
122
|
- - "~>"
|
124
123
|
- !ruby/object:Gem::Version
|
125
|
-
version: '0.
|
124
|
+
version: '0.12'
|
126
125
|
type: :runtime
|
127
126
|
prerelease: false
|
128
127
|
version_requirements: !ruby/object:Gem::Requirement
|
129
128
|
requirements:
|
130
129
|
- - "~>"
|
131
130
|
- !ruby/object:Gem::Version
|
132
|
-
version: '0.
|
131
|
+
version: '0.12'
|
133
132
|
- !ruby/object:Gem::Dependency
|
134
|
-
name: protocol-
|
133
|
+
name: protocol-http
|
135
134
|
requirement: !ruby/object:Gem::Requirement
|
136
135
|
requirements:
|
137
|
-
- - "
|
136
|
+
- - "~>"
|
138
137
|
- !ruby/object:Gem::Version
|
139
|
-
version: 0.
|
138
|
+
version: '0.49'
|
140
139
|
type: :runtime
|
141
140
|
prerelease: false
|
142
141
|
version_requirements: !ruby/object:Gem::Requirement
|
143
142
|
requirements:
|
144
|
-
- - "
|
143
|
+
- - "~>"
|
145
144
|
- !ruby/object:Gem::Version
|
146
|
-
version: 0.
|
145
|
+
version: '0.49'
|
147
146
|
- !ruby/object:Gem::Dependency
|
148
|
-
name: protocol-
|
147
|
+
name: protocol-http1
|
149
148
|
requirement: !ruby/object:Gem::Requirement
|
150
149
|
requirements:
|
151
150
|
- - "~>"
|
152
151
|
- !ruby/object:Gem::Version
|
153
|
-
version: '0.
|
152
|
+
version: '0.30'
|
154
153
|
type: :runtime
|
155
154
|
prerelease: false
|
156
155
|
version_requirements: !ruby/object:Gem::Requirement
|
157
156
|
requirements:
|
158
157
|
- - "~>"
|
159
158
|
- !ruby/object:Gem::Version
|
160
|
-
version: '0.
|
159
|
+
version: '0.30'
|
161
160
|
- !ruby/object:Gem::Dependency
|
162
|
-
name:
|
161
|
+
name: protocol-http2
|
163
162
|
requirement: !ruby/object:Gem::Requirement
|
164
163
|
requirements:
|
165
164
|
- - "~>"
|
166
165
|
- !ruby/object:Gem::Version
|
167
|
-
version: '0.
|
166
|
+
version: '0.22'
|
168
167
|
type: :runtime
|
169
168
|
prerelease: false
|
170
169
|
version_requirements: !ruby/object:Gem::Requirement
|
171
170
|
requirements:
|
172
171
|
- - "~>"
|
173
172
|
- !ruby/object:Gem::Version
|
174
|
-
version: '0.
|
173
|
+
version: '0.22'
|
175
174
|
- !ruby/object:Gem::Dependency
|
176
|
-
name:
|
175
|
+
name: traces
|
177
176
|
requirement: !ruby/object:Gem::Requirement
|
178
177
|
requirements:
|
179
178
|
- - "~>"
|
180
179
|
- !ruby/object:Gem::Version
|
181
|
-
version: '0.
|
180
|
+
version: '0.10'
|
182
181
|
type: :runtime
|
183
182
|
prerelease: false
|
184
183
|
version_requirements: !ruby/object:Gem::Requirement
|
185
184
|
requirements:
|
186
185
|
- - "~>"
|
187
186
|
- !ruby/object:Gem::Version
|
188
|
-
version: '0.
|
189
|
-
description:
|
190
|
-
email:
|
187
|
+
version: '0.10'
|
191
188
|
executables: []
|
192
189
|
extensions: []
|
193
190
|
extra_rdoc_files: []
|
@@ -244,7 +241,6 @@ licenses:
|
|
244
241
|
metadata:
|
245
242
|
documentation_uri: https://socketry.github.io/async-http/
|
246
243
|
source_code_uri: https://github.com/socketry/async-http.git
|
247
|
-
post_install_message:
|
248
244
|
rdoc_options: []
|
249
245
|
require_paths:
|
250
246
|
- lib
|
@@ -259,8 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
259
255
|
- !ruby/object:Gem::Version
|
260
256
|
version: '0'
|
261
257
|
requirements: []
|
262
|
-
rubygems_version: 3.
|
263
|
-
signing_key:
|
258
|
+
rubygems_version: 3.6.2
|
264
259
|
specification_version: 4
|
265
260
|
summary: A HTTP client and server library.
|
266
261
|
test_files: []
|
metadata.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
��H��;�w1$O��i�\�q>�������ؕ���5����ʪe��5��P4ǭ;�JmVO��������bC����W��:��W..4ګb��UDw��Kx����&��VYt
|
2
|
+
�1�{��g��\u�w��e����-q�Ɓƃ=B�<i)�Ԝ��0=-Y2Q��x]��s�o[^b��*��`ܼV���yM��-�7�bg{{[�{D ����z�_� �K>0���Og��ץ��9x�)�n�Y]��ow��f 'yD��G3B��ba��TQ���t+`X��'ٔ���`��
|