async-http 0.98.1 → 0.100.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32a7056790328efb71a89aa3c721672b18640bef1ac9c6ba67ce934f085f3c64
4
- data.tar.gz: df9f6b4843347757a887d9ab64e49af66e2e88cfc6dcc8659d77dc875f0d02b5
3
+ metadata.gz: ee704ca93c1b809cfcd2ea2db7961066a10d433143f1144658a52c7674179110
4
+ data.tar.gz: 268a538e9a234f51495990e39d8f5c9f7bb8d1a73db57da285e6cf180f3638e7
5
5
  SHA512:
6
- metadata.gz: 040b5ef80794ddda14b86cdfcb118fd63de4ee72c21c8923e740b2ad3cfb7138370edf87c0db5249b6e177009ba4c7683cc6ab8515e3f94720ab74462839e669
7
- data.tar.gz: 2f5f60d796f3fd4d1dcad6f8dfd9acd11ed40c82a3092f65cdf22093e9c2019a558cb91085978a76a78be78596207bebfa7a2554fd8eac0c2503f268829cd999
6
+ metadata.gz: 9393381596b9b8f1c14cea1383577cb4037e60f74d4e0aa9f84862f38f906988645fc9153dc68cb933fe3932ea3b3e5abc92cae9429200d4ee1a17a90706b476
7
+ data.tar.gz: 9bae0d3084ce01b65c9eeb208b97a525b176063c20473f554a1b18016b486e6a0813b974864c7bbdadaca22e1605932e1239e10c402bf38a9cfd16fb59744c2e
checksums.yaml.gz.sig CHANGED
Binary file
@@ -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
@@ -70,6 +70,7 @@ module Async
70
70
  # @option hostname [String] the hostname to connect to (or bind to), overrides the URL hostname (used for SNI).
71
71
  # @option port [Integer] the port to bind to, overrides the URL port.
72
72
  # @option ssl_context [OpenSSL::SSL::SSLContext] the context to use for TLS.
73
+ # @option tls_configuration [IO::Endpoint::TLS::Configuration] the transport-neutral TLS configuration.
73
74
  # @option alpn_protocols [Array(String)] the alpn protocols to negotiate.
74
75
  def initialize(url, endpoint = nil, **options)
75
76
  super(**options)
@@ -206,6 +207,11 @@ module Async
206
207
  end
207
208
  end
208
209
 
210
+ # @returns [IO::Endpoint::TLS::Configuration | Nil] The transport-neutral TLS configuration.
211
+ def tls_configuration
212
+ @options[:tls_configuration]
213
+ end
214
+
209
215
  # Build a suitable endpoint, optionally wrapping in TLS for secure connections.
210
216
  # @parameter endpoint [IO::Endpoint::Generic | Nil] An optional underlying endpoint to wrap.
211
217
  # @returns [IO::Endpoint::Generic] The constructed endpoint.
@@ -216,6 +222,7 @@ module Async
216
222
  # Wrap it in SSL:
217
223
  return ::IO::Endpoint::SSLEndpoint.new(endpoint,
218
224
  ssl_context: self.ssl_context,
225
+ tls_configuration: self.tls_configuration,
219
226
  hostname: @url.hostname,
220
227
  timeout: self.timeout,
221
228
  )
@@ -280,6 +287,7 @@ module Async
280
287
  options.delete(:port)
281
288
  options.delete(:hostname)
282
289
  options.delete(:ssl_context)
290
+ options.delete(:tls_configuration)
283
291
  options.delete(:alpn_protocols)
284
292
  options.delete(:protocol)
285
293
 
@@ -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::Notification.new
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.signal
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
- @notification = Async::Notification.new
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
- self.notify!
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
- # If you call wait after the headers were already received, it should return immediately:
120
- @notification&.wait
121
-
122
- if @exception
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
- @exception = error
137
-
138
- self.notify!
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
- if @requests
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&.async do |task, request|
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
- # Maybe we should add some synchronisation here - i.e. only exit once all requests are finished.
80
+ barrier.wait
81
+ ensure
82
+ barrier&.stop
83
83
  end
84
84
  end
85
85
  end
@@ -7,6 +7,6 @@
7
7
  module Async
8
8
  # @namespace
9
9
  module HTTP
10
- VERSION = "0.98.1"
10
+ VERSION = "0.100.0"
11
11
  end
12
12
  end
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.100.0
20
+
21
+ - Added transport-neutral TLS configuration support to `Async::HTTP::Endpoint`.
22
+
23
+ ### v0.99.0
24
+
25
+ - Retry safe requests when a remote HTTP/2 endpoint resets the stream with `INTERNAL_ERROR` before returning a response.
26
+
19
27
  ### v0.98.1
20
28
 
21
29
  - Probe idle HTTP/1 connections before reuse, avoiding requests on connections already closed by the peer.
@@ -51,14 +59,6 @@ Please see the [project releases](https://socketry.github.io/async-http/releases
51
59
 
52
60
  - Fix `defer_stop` usage in `HTTP1::Server`, improving server graceful shutdown behavior.
53
61
 
54
- ### v0.94.0
55
-
56
- - Propagate all errors from background reader to active streams so that they are closed correctly (e.g. errors are not missed).
57
-
58
- ### v0.92.2
59
-
60
- - Better handling of trailers. If invalid trailers are received, the connection (HTTP/1) or stream (HTTP/2) is reset.
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.100.0
4
+
5
+ - Added transport-neutral TLS configuration support to `Async::HTTP::Endpoint`.
6
+
7
+ ## v0.99.0
8
+
9
+ - Retry safe requests when a remote HTTP/2 endpoint resets the stream with `INTERNAL_ERROR` before returning a response.
10
+
3
11
  ## v0.98.1
4
12
 
5
13
  - Probe idle HTTP/1 connections before reuse, avoiding requests on connections already closed by the peer.
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.98.1
4
+ version: 0.100.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -96,14 +96,14 @@ dependencies:
96
96
  requirements:
97
97
  - - "~>"
98
98
  - !ruby/object:Gem::Version
99
- version: '0.14'
99
+ version: '0.18'
100
100
  type: :runtime
101
101
  prerelease: false
102
102
  version_requirements: !ruby/object:Gem::Requirement
103
103
  requirements:
104
104
  - - "~>"
105
105
  - !ruby/object:Gem::Version
106
- version: '0.14'
106
+ version: '0.18'
107
107
  - !ruby/object:Gem::Dependency
108
108
  name: io-stream
109
109
  requirement: !ruby/object:Gem::Requirement
@@ -124,14 +124,14 @@ dependencies:
124
124
  requirements:
125
125
  - - "~>"
126
126
  - !ruby/object:Gem::Version
127
- version: '0.64'
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.64'
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