async-http 0.98.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32a7056790328efb71a89aa3c721672b18640bef1ac9c6ba67ce934f085f3c64
4
- data.tar.gz: df9f6b4843347757a887d9ab64e49af66e2e88cfc6dcc8659d77dc875f0d02b5
3
+ metadata.gz: 0b6ac145066c1d834e5466282d944564e313852717edd28359de26515a85ead6
4
+ data.tar.gz: 1b242251b92b8885392569c591fc0581ea94eba1751f4d2cf8f0c5279c07336e
5
5
  SHA512:
6
- metadata.gz: 040b5ef80794ddda14b86cdfcb118fd63de4ee72c21c8923e740b2ad3cfb7138370edf87c0db5249b6e177009ba4c7683cc6ab8515e3f94720ab74462839e669
7
- data.tar.gz: 2f5f60d796f3fd4d1dcad6f8dfd9acd11ed40c82a3092f65cdf22093e9c2019a558cb91085978a76a78be78596207bebfa7a2554fd8eac0c2503f268829cd999
6
+ metadata.gz: 690e9bc0fd0080b7dd98119fdf8876c3f04bd84d4045b727cbdd82735159d314c6852a56a7967949939fe5b7a2182318ef7ec405ffa2d44ce4383c814952abba
7
+ data.tar.gz: 2e72385b497dbb1e37bb1a9237f32c963baa886cb6efe35171f78e16a940c74f22f0305f0e5892fdf1a84ade8045194c58da722dcef40213eb2acb30157eb80e
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
@@ -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.99.0"
11
11
  end
12
12
  end
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.99.0
20
+
21
+ - Retry safe requests when a remote HTTP/2 endpoint resets the stream with `INTERNAL_ERROR` before returning a response.
22
+
19
23
  ### v0.98.1
20
24
 
21
25
  - Probe idle HTTP/1 connections before reuse, avoiding requests on connections already closed by the peer.
@@ -55,10 +59,6 @@ Please see the [project releases](https://socketry.github.io/async-http/releases
55
59
 
56
60
  - Propagate all errors from background reader to active streams so that they are closed correctly (e.g. errors are not missed).
57
61
 
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,9 @@
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
+
3
7
  ## v0.98.1
4
8
 
5
9
  - 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.99.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -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