async-http 0.74.0 → 0.75.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/async/http/protocol/http1/client.rb +4 -10
- data/lib/async/http/protocol/http1/server.rb +28 -19
- data/lib/async/http/protocol/http2/connection.rb +4 -2
- data/lib/async/http/protocol/http2/request.rb +1 -1
- data/lib/async/http/protocol/http2/response.rb +7 -2
- data/lib/async/http/protocol/request.rb +1 -1
- data/lib/async/http/version.rb +1 -1
- data/readme.md +4 -0
- data/releases.md +4 -0
- 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: 946e45fa80db4dc1a3416f91a6533d58e7e4c5b8e7db9a687b922e9161f84dcf
|
4
|
+
data.tar.gz: 7810dfb04b6c120e91660c4cabec884ef531bb4b4078c149558a6190314f88cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 456325793d94251a8b8b117000361e512c23aad9ce03dd2df6c387a35405ac83a7cae1b0de270bf0264485ab98ff5fff3778d720845fe26753950bedd1066b38
|
7
|
+
data.tar.gz: de2cb3749808740c03bd0d0d6cfe5facb3282d26f8465ddeb734158389cfdd70b2bf5610a01bf1d4f0af44fdc1d6c15249f912942038778e9f38217e96ad9c84
|
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-2024, by Samuel Williams.
|
5
5
|
|
6
6
|
require_relative 'connection'
|
7
7
|
|
@@ -33,22 +33,16 @@ module Async
|
|
33
33
|
|
34
34
|
if protocol = request.protocol
|
35
35
|
# This is a very tricky apect of handling HTTP/1 upgrade connections. In theory, this approach is a bit inefficient, because we spin up a task just to handle writing to the underlying stream when we could be writing to the stream directly. But we need to maintain some level of compatibility with HTTP/2. Additionally, we don't know if the upgrade request will be accepted, so starting to write the body at this point needs to be handled with care.
|
36
|
-
task.async do
|
37
|
-
subtask.annotate("Upgrading request.")
|
38
|
-
|
36
|
+
task.async(annotation: "Upgrading request...") do
|
39
37
|
# If this fails, this connection will be closed.
|
40
38
|
write_upgrade_body(protocol, body)
|
41
39
|
end
|
42
40
|
elsif request.connect?
|
43
|
-
task.async do
|
44
|
-
subtask.annotate("Tunnelling body.")
|
45
|
-
|
41
|
+
task.async(annotation: "Tunnneling request...") do
|
46
42
|
write_tunnel_body(@version, body)
|
47
43
|
end
|
48
44
|
else
|
49
|
-
task.async do
|
50
|
-
subtask.annotate("Streaming body.")
|
51
|
-
|
45
|
+
task.async(annotation: "Streaming request...") do
|
52
46
|
# Once we start writing the body, we can't recover if the request fails. That's because the body might be generated dynamically, streaming, etc.
|
53
47
|
write_body(@version, body, false, trailer)
|
54
48
|
end
|
@@ -59,33 +59,42 @@ module Async
|
|
59
59
|
if response
|
60
60
|
trailer = response.headers.trailer!
|
61
61
|
|
62
|
-
write_response(@version, response.status, response.headers)
|
63
|
-
|
64
62
|
# Some operations in this method are long running, that is, it's expected that `body.call(stream)` could literally run indefinitely. In order to facilitate garbage collection, we want to nullify as many local variables before calling the streaming body. This ensures that the garbage collection can clean up as much state as possible during the long running operation, so we don't retain objects that are no longer needed.
|
65
|
-
|
63
|
+
|
66
64
|
if body and protocol = response.protocol
|
65
|
+
# We force a 101 response if the protocol is upgraded - HTTP/2 CONNECT will return 200 for success, but this won't be understood by HTTP/1 clients:
|
66
|
+
write_response(@version, 101, response.headers)
|
67
|
+
|
67
68
|
stream = write_upgrade_body(protocol)
|
68
69
|
|
69
70
|
# At this point, the request body is hijacked, so we don't want to call #finish below.
|
70
|
-
request = response = nil
|
71
|
-
|
72
|
-
body.call(stream)
|
73
|
-
elsif request.connect? and response.success?
|
74
|
-
stream = write_tunnel_body(request.version)
|
75
|
-
|
76
|
-
# Same as above:
|
77
|
-
request = response = nil
|
78
|
-
|
79
|
-
body.call(stream)
|
80
|
-
else
|
81
|
-
head = request.head?
|
82
|
-
version = request.version
|
83
|
-
|
84
|
-
# Same as above:
|
85
71
|
request = nil unless request.body
|
86
72
|
response = nil
|
87
73
|
|
88
|
-
|
74
|
+
# We must return here as no further request processing can be done:
|
75
|
+
return body.call(stream)
|
76
|
+
else
|
77
|
+
write_response(@version, response.status, response.headers)
|
78
|
+
|
79
|
+
if request.connect? and response.success?
|
80
|
+
stream = write_tunnel_body(request.version)
|
81
|
+
|
82
|
+
# Same as above:
|
83
|
+
request = nil unless request.body
|
84
|
+
response = nil
|
85
|
+
|
86
|
+
# We must return here as no further request processing can be done:
|
87
|
+
return body.call(stream)
|
88
|
+
else
|
89
|
+
head = request.head?
|
90
|
+
version = request.version
|
91
|
+
|
92
|
+
# Same as above:
|
93
|
+
request = nil unless request.body
|
94
|
+
response = nil
|
95
|
+
|
96
|
+
write_body(version, body, head, trailer)
|
97
|
+
end
|
89
98
|
end
|
90
99
|
|
91
100
|
# We are done with the body, you shouldn't need to call close on it:
|
@@ -66,14 +66,14 @@ module Async
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def close(error = nil)
|
69
|
-
super
|
70
|
-
|
71
69
|
# Ensure the reader task is stopped.
|
72
70
|
if @reader
|
73
71
|
reader = @reader
|
74
72
|
@reader = nil
|
75
73
|
reader.stop
|
76
74
|
end
|
75
|
+
|
76
|
+
super
|
77
77
|
end
|
78
78
|
|
79
79
|
def read_in_background(parent: Task.current)
|
@@ -101,6 +101,8 @@ module Async
|
|
101
101
|
ensure
|
102
102
|
# Don't call #close twice.
|
103
103
|
if @reader
|
104
|
+
@reader = nil
|
105
|
+
|
104
106
|
self.close(error)
|
105
107
|
end
|
106
108
|
end
|
@@ -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-2024, by Samuel Williams.
|
5
5
|
|
6
6
|
require_relative '../response'
|
7
7
|
require_relative 'stream'
|
@@ -54,6 +54,11 @@ module Async
|
|
54
54
|
@response.status = status
|
55
55
|
@headers = ::Protocol::HTTP::Headers.new
|
56
56
|
|
57
|
+
# If the protocol request was successful, ensure the response protocol matches:
|
58
|
+
if status == 200 and protocol = @response.request.protocol
|
59
|
+
@response.protocol = Array(protocol).first
|
60
|
+
end
|
61
|
+
|
57
62
|
headers.each do |key, value|
|
58
63
|
# It's guaranteed that this should be the first header:
|
59
64
|
if key == CONTENT_LENGTH
|
@@ -118,7 +123,7 @@ module Async
|
|
118
123
|
|
119
124
|
@exception = error
|
120
125
|
|
121
|
-
notify!
|
126
|
+
self.notify!
|
122
127
|
end
|
123
128
|
end
|
124
129
|
|
data/lib/async/http/version.rb
CHANGED
data/readme.md
CHANGED
@@ -16,6 +16,10 @@ 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.75.0
|
20
|
+
|
21
|
+
- Better handling of HTTP/1 \<-\> HTTP/2 proxying, specifically upgrade/CONNECT requests.
|
22
|
+
|
19
23
|
### v0.74.0
|
20
24
|
|
21
25
|
- [`Async::HTTP::Internet` accepts keyword arguments](https://socketry.github.io/async-http/releases/index#async::http::internet-accepts-keyword-arguments)
|
data/releases.md
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.
|
4
|
+
version: 0.75.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -58,7 +58,7 @@ cert_chain:
|
|
58
58
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
59
59
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
60
60
|
-----END CERTIFICATE-----
|
61
|
-
date: 2024-
|
61
|
+
date: 2024-09-04 00:00:00.000000000 Z
|
62
62
|
dependencies:
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
64
|
name: async
|
metadata.gz.sig
CHANGED
Binary file
|