async-http 0.98.0 → 0.99.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/client.rb +2 -1
- data/lib/async/http/protocol/http1/connection.rb +19 -2
- data/lib/async/http/protocol/http1/server.rb +3 -2
- data/lib/async/http/protocol/http2/response.rb +15 -19
- data/lib/async/http/protocol/http2/server.rb +7 -7
- data/lib/async/http/version.rb +1 -1
- data/readme.md +8 -8
- data/releases.md +8 -0
- data.tar.gz.sig +2 -3
- metadata +5 -5
- 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: 0b6ac145066c1d834e5466282d944564e313852717edd28359de26515a85ead6
|
|
4
|
+
data.tar.gz: 1b242251b92b8885392569c591fc0581ea94eba1751f4d2cf8f0c5279c07336e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 690e9bc0fd0080b7dd98119fdf8876c3f04bd84d4045b727cbdd82735159d314c6852a56a7967949939fe5b7a2182318ef7ec405ffa2d44ce4383c814952abba
|
|
7
|
+
data.tar.gz: 2e72385b497dbb1e37bb1a9237f32c963baa886cb6efe35171f78e16a940c74f22f0305f0e5892fdf1a84ade8045194c58da722dcef40213eb2acb30157eb80e
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/lib/async/http/client.rb
CHANGED
|
@@ -9,6 +9,7 @@ require "io/endpoint"
|
|
|
9
9
|
require "async/pool/controller"
|
|
10
10
|
|
|
11
11
|
require "protocol/http/body/completable"
|
|
12
|
+
require "protocol/http/error"
|
|
12
13
|
require "protocol/http/methods"
|
|
13
14
|
|
|
14
15
|
require_relative "protocol"
|
|
@@ -126,7 +127,7 @@ module Async
|
|
|
126
127
|
else
|
|
127
128
|
raise
|
|
128
129
|
end
|
|
129
|
-
rescue SocketError, IOError, EOFError, Errno::ECONNRESET, Errno::EPIPE
|
|
130
|
+
rescue ::Protocol::HTTP::RemoteError, SocketError, IOError, EOFError, Errno::ECONNRESET, Errno::EPIPE
|
|
130
131
|
if connection
|
|
131
132
|
@pool.release(connection)
|
|
132
133
|
connection = nil
|
|
@@ -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-2026, by Samuel Williams.
|
|
5
5
|
|
|
6
6
|
require_relative "request"
|
|
7
7
|
require_relative "response"
|
|
@@ -67,7 +67,24 @@ module Async
|
|
|
67
67
|
|
|
68
68
|
# Can we use this connection to make requests?
|
|
69
69
|
def viable?
|
|
70
|
-
self.idle?
|
|
70
|
+
unless self.idle?
|
|
71
|
+
return false
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
unless @stream
|
|
75
|
+
return false
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# `nil` indicates that the connection has no data, but is still alive. An empty string means the connection is closed, while a non-empty string indicates application data on a idle HTTP/1 connection, both are failure cases.
|
|
79
|
+
if @stream.peek_partial(1)
|
|
80
|
+
return false
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
return @stream.readable?
|
|
84
|
+
rescue => error
|
|
85
|
+
Console.debug(self, "Connection viability probe failed!", exception: error)
|
|
86
|
+
|
|
87
|
+
return false
|
|
71
88
|
end
|
|
72
89
|
|
|
73
90
|
# @returns [Boolean] Whether the connection can be reused for another request.
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
require_relative "connection"
|
|
11
11
|
require_relative "finishable"
|
|
12
12
|
|
|
13
|
+
require "async/promise"
|
|
13
14
|
require "console/event/failure"
|
|
14
15
|
|
|
15
16
|
module Async
|
|
@@ -22,14 +23,14 @@ module Async
|
|
|
22
23
|
def initialize(...)
|
|
23
24
|
super
|
|
24
25
|
|
|
25
|
-
@ready = Async::
|
|
26
|
+
@ready = Async::Promise.new
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
# Called when the connection is closed, signalling any waiting tasks.
|
|
29
30
|
def closed(error = nil)
|
|
30
31
|
super
|
|
31
32
|
|
|
32
|
-
@ready.
|
|
33
|
+
@ready.resolve(nil)
|
|
33
34
|
end
|
|
34
35
|
|
|
35
36
|
# Write a failure response with the given status code.
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
require_relative "../response"
|
|
7
7
|
require_relative "stream"
|
|
8
8
|
|
|
9
|
+
require "async/promise"
|
|
10
|
+
|
|
9
11
|
module Async
|
|
10
12
|
module HTTP
|
|
11
13
|
module Protocol
|
|
@@ -20,8 +22,7 @@ module Async
|
|
|
20
22
|
|
|
21
23
|
@response = Response.new(self)
|
|
22
24
|
|
|
23
|
-
@
|
|
24
|
-
@exception = nil
|
|
25
|
+
@ready = Async::Promise.new
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
attr :response
|
|
@@ -88,7 +89,7 @@ module Async
|
|
|
88
89
|
send_reset_stream(::Protocol::HTTP2::Error::PROTOCOL_ERROR)
|
|
89
90
|
end
|
|
90
91
|
|
|
91
|
-
|
|
92
|
+
@ready.resolve(nil)
|
|
92
93
|
|
|
93
94
|
return headers
|
|
94
95
|
end
|
|
@@ -106,22 +107,15 @@ module Async
|
|
|
106
107
|
@response.request.send_interim_response(status, headers)
|
|
107
108
|
end
|
|
108
109
|
|
|
109
|
-
# Notify anyone waiting on the response headers to be received (or failure).
|
|
110
|
-
def notify!
|
|
111
|
-
if notification = @notification
|
|
112
|
-
@notification = nil
|
|
113
|
-
notification.signal
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
110
|
# Wait for the headers to be received or for stream reset.
|
|
118
111
|
def wait
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
raise @exception
|
|
112
|
+
@ready.wait
|
|
113
|
+
rescue ::Protocol::HTTP2::StreamError => error
|
|
114
|
+
if error.code == ::Protocol::HTTP2::Error::INTERNAL_ERROR
|
|
115
|
+
raise ::Protocol::HTTP::RemoteError, error.message
|
|
124
116
|
end
|
|
117
|
+
|
|
118
|
+
raise
|
|
125
119
|
end
|
|
126
120
|
|
|
127
121
|
# Called when the stream is closed.
|
|
@@ -133,9 +127,11 @@ module Async
|
|
|
133
127
|
@response = nil
|
|
134
128
|
end
|
|
135
129
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
130
|
+
if error
|
|
131
|
+
@ready.reject(error)
|
|
132
|
+
else
|
|
133
|
+
@ready.resolve(nil)
|
|
134
|
+
end
|
|
139
135
|
end
|
|
140
136
|
end
|
|
141
137
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
require_relative "connection"
|
|
7
7
|
require_relative "request"
|
|
8
8
|
|
|
9
|
+
require "async/barrier"
|
|
9
10
|
require "protocol/http2/server"
|
|
10
11
|
|
|
11
12
|
module Async
|
|
@@ -41,11 +42,7 @@ module Async
|
|
|
41
42
|
|
|
42
43
|
# Close the server connection and stop accepting requests.
|
|
43
44
|
def close(error = nil)
|
|
44
|
-
|
|
45
|
-
# Stop the request loop:
|
|
46
|
-
@requests.enqueue(nil)
|
|
47
|
-
@requests = nil
|
|
48
|
-
end
|
|
45
|
+
@requests.close
|
|
49
46
|
|
|
50
47
|
super
|
|
51
48
|
end
|
|
@@ -55,9 +52,10 @@ module Async
|
|
|
55
52
|
# @parameter request [Request] The incoming HTTP/2 request.
|
|
56
53
|
def each(task: Task.current)
|
|
57
54
|
task.annotate("Reading #{version} requests for #{self.class}.")
|
|
55
|
+
barrier = Async::Barrier.new(parent: task)
|
|
58
56
|
|
|
59
57
|
# It's possible the connection has died before we get here...
|
|
60
|
-
@requests
|
|
58
|
+
@requests.async(parent: barrier) do |task, request|
|
|
61
59
|
task.annotate("Incoming request: #{request.method} #{request.path.inspect}.")
|
|
62
60
|
|
|
63
61
|
response = nil
|
|
@@ -79,7 +77,9 @@ module Async
|
|
|
79
77
|
end
|
|
80
78
|
end
|
|
81
79
|
|
|
82
|
-
|
|
80
|
+
barrier.wait
|
|
81
|
+
ensure
|
|
82
|
+
barrier&.stop
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
end
|
data/lib/async/http/version.rb
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.99.0
|
|
20
|
+
|
|
21
|
+
- Retry safe requests when a remote HTTP/2 endpoint resets the stream with `INTERNAL_ERROR` before returning a response.
|
|
22
|
+
|
|
23
|
+
### v0.98.1
|
|
24
|
+
|
|
25
|
+
- Probe idle HTTP/1 connections before reuse, avoiding requests on connections already closed by the peer.
|
|
26
|
+
|
|
19
27
|
### v0.98.0
|
|
20
28
|
|
|
21
29
|
- Rewind request bodies before retrying requests.
|
|
@@ -51,14 +59,6 @@ Please see the [project releases](https://socketry.github.io/async-http/releases
|
|
|
51
59
|
|
|
52
60
|
- Propagate all errors from background reader to active streams so that they are closed correctly (e.g. errors are not missed).
|
|
53
61
|
|
|
54
|
-
### v0.92.2
|
|
55
|
-
|
|
56
|
-
- Better handling of trailers. If invalid trailers are received, the connection (HTTP/1) or stream (HTTP/2) is reset.
|
|
57
|
-
|
|
58
|
-
### v0.92.0
|
|
59
|
-
|
|
60
|
-
- **Breaking**: Remove `Async::HTTP::Reference`. Use `Protocol::URL::Reference` directly instead.
|
|
61
|
-
|
|
62
62
|
## See Also
|
|
63
63
|
|
|
64
64
|
- [benchmark-http](https://github.com/socketry/benchmark-http) — A benchmarking tool to report on web server concurrency.
|
data/releases.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
+
## v0.99.0
|
|
4
|
+
|
|
5
|
+
- Retry safe requests when a remote HTTP/2 endpoint resets the stream with `INTERNAL_ERROR` before returning a response.
|
|
6
|
+
|
|
7
|
+
## v0.98.1
|
|
8
|
+
|
|
9
|
+
- Probe idle HTTP/1 connections before reuse, avoiding requests on connections already closed by the peer.
|
|
10
|
+
|
|
3
11
|
## v0.98.0
|
|
4
12
|
|
|
5
13
|
- Rewind request bodies before retrying requests.
|
data.tar.gz.sig
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
��
|
|
2
|
-
|
|
3
|
-
��×�m��Ƚ���%��/-OM�!�)M�
|
|
1
|
+
��
|
|
2
|
+
�8�0X��d�wk�T��p}q��賗�NqѪ�}��2�hwӀ�%z�өT��` �L��O_�4/A�荋 ��q��x�L�s�x�NQ'<�V�����\�_t��7���d\^�Y�0rXFʤR���4��=��xÝQX���G�2݁+,����rY����ِJB����( ��0bQ�-���&��O���WrfS���l.�_��'ĺ�mL���&���%W<���?>��d��e6* ��}9JB����3��P�����-�jk�%�"���d�-/�����>`��r2]z�F�t���A@�mz���j��D��Y
|
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.99.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -110,28 +110,28 @@ dependencies:
|
|
|
110
110
|
requirements:
|
|
111
111
|
- - "~>"
|
|
112
112
|
- !ruby/object:Gem::Version
|
|
113
|
-
version: '0.
|
|
113
|
+
version: '0.14'
|
|
114
114
|
type: :runtime
|
|
115
115
|
prerelease: false
|
|
116
116
|
version_requirements: !ruby/object:Gem::Requirement
|
|
117
117
|
requirements:
|
|
118
118
|
- - "~>"
|
|
119
119
|
- !ruby/object:Gem::Version
|
|
120
|
-
version: '0.
|
|
120
|
+
version: '0.14'
|
|
121
121
|
- !ruby/object:Gem::Dependency
|
|
122
122
|
name: protocol-http
|
|
123
123
|
requirement: !ruby/object:Gem::Requirement
|
|
124
124
|
requirements:
|
|
125
125
|
- - "~>"
|
|
126
126
|
- !ruby/object:Gem::Version
|
|
127
|
-
version: '0.
|
|
127
|
+
version: '0.66'
|
|
128
128
|
type: :runtime
|
|
129
129
|
prerelease: false
|
|
130
130
|
version_requirements: !ruby/object:Gem::Requirement
|
|
131
131
|
requirements:
|
|
132
132
|
- - "~>"
|
|
133
133
|
- !ruby/object:Gem::Version
|
|
134
|
-
version: '0.
|
|
134
|
+
version: '0.66'
|
|
135
135
|
- !ruby/object:Gem::Dependency
|
|
136
136
|
name: protocol-http1
|
|
137
137
|
requirement: !ruby/object:Gem::Requirement
|
metadata.gz.sig
CHANGED
|
Binary file
|