async-http 0.92.1 → 0.92.2

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: d2eec64b9787b5fbad7b8d4b7d45566efcb701b1dcfb9aa7774bf3e2bc3f79f1
4
- data.tar.gz: 2105c3c5bb32cb5d69359bb077e4bba77bdcad644cc8186149b34c425749ccc3
3
+ metadata.gz: 2ee1dcf16e21d1cdbd3c4ebeac7d519d1693bb18d94c11d4831ab23d4dbd31cb
4
+ data.tar.gz: edcceae84648691978106b49f9766550f2af3aa37f0ea488719dfe7a3c20ecf5
5
5
  SHA512:
6
- metadata.gz: b797e853dec72a6f115c73aa3199ae135d28f5dbaf6f2eb21ceb19bb5a747c4b3c6aadc2212a9352c86f2ea64c17a4864a829a9aea0de80fabfdef0205782df9
7
- data.tar.gz: a39431a5f5ddeedaf208121a64b232b318b73716c018de26dad6bcb1ff98cb12a3ad68e4ba11ea8b27291ee25eae1604af3f9c53152fda81cbcdab6132c709f7
6
+ metadata.gz: 5afe2ec6bbe24cd6954be3e2d7358505b7ac063a2ae7cab7217de09d4f4cb1ed06496a2a69bca1338add2f3e08036f4536eb5f0cb2366061856f08991b7dfe50
7
+ data.tar.gz: 071b23544be29451741c8ec09686cc251349ff2b2d40fc4abdb375c55e4d5208b86bc49ca0c98e5f24666d4744a195d96144c7625c1efabc1941ec73dd51ef39
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, 2017-2025, by Samuel Williams.
4
+ # Copyright, 2017-2026, by Samuel Williams.
5
5
  # Copyright, 2022, by Ian Ker-Seymer.
6
6
 
7
7
  require "io/endpoint"
@@ -79,7 +79,7 @@ module Async
79
79
 
80
80
  def close
81
81
  @pool.wait_until_free do
82
- Console.warn(self) {"Waiting for #{@protocol} pool to drain: #{@pool}"}
82
+ Console.warn(self){"Waiting for #{@protocol} pool to drain: #{@pool}"}
83
83
  end
84
84
 
85
85
  @pool.close
@@ -161,7 +161,7 @@ module Async
161
161
  self.assign_default_tags(options[:tags] ||= {})
162
162
 
163
163
  Async::Pool::Controller.wrap(**options) do
164
- Console.debug(self) {"Making connection to #{@endpoint.inspect}"}
164
+ Console.debug(self){"Making connection to #{@endpoint.inspect}"}
165
165
 
166
166
  @protocol.client(@endpoint.connect)
167
167
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2025, by Samuel Williams.
4
+ # Copyright, 2019-2026, by Samuel Williams.
5
5
  # Copyright, 2021-2022, by Adam Daniels.
6
6
  # Copyright, 2024, by Thomas Morgan.
7
7
  # Copyright, 2024, by Igor Sidorov.
@@ -159,7 +159,7 @@ module Async
159
159
  end
160
160
 
161
161
  def alpn_protocols
162
- @options.fetch(:alpn_protocols) {self.protocol.names}
162
+ @options.fetch(:alpn_protocols){self.protocol.names}
163
163
  end
164
164
 
165
165
  def localhost?
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2025, by Samuel Williams.
4
+ # Copyright, 2018-2026, by Samuel Williams.
5
5
 
6
6
  require_relative "connection"
7
7
 
@@ -32,6 +32,7 @@ module Async
32
32
  def call(request, task: Task.current)
33
33
  # Mark the start of the trailers:
34
34
  trailer = request.headers.trailer!
35
+ headers = request.headers.header
35
36
 
36
37
  # We carefully interpret https://tools.ietf.org/html/rfc7230#section-6.3.1 to implement this correctly.
37
38
  begin
@@ -44,7 +45,7 @@ module Async
44
45
  authority = nil
45
46
  end
46
47
 
47
- write_request(authority, request.method, target, @version, request.headers)
48
+ write_request(authority, request.method, target, @version, headers)
48
49
  rescue
49
50
  # If we fail to fully write the request and body, we can retry this request.
50
51
  raise RequestFailed
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2025, by Samuel Williams.
4
+ # Copyright, 2018-2026, by Samuel Williams.
5
5
  # Copyright, 2020, by Igor Sidorov.
6
6
  # Copyright, 2023, by Thomas Morgan.
7
7
  # Copyright, 2024, by Anton Zhuravsky.
@@ -82,12 +82,13 @@ module Async
82
82
  # If a response was generated, send it:
83
83
  if response
84
84
  trailer = response.headers.trailer!
85
+ headers = response.headers.header
85
86
 
86
87
  # 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.
87
88
 
88
89
  if body and protocol = response.protocol
89
90
  # 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:
90
- write_response(@version, 101, response.headers)
91
+ write_response(@version, 101, headers)
91
92
 
92
93
  # At this point, the request body is hijacked, so we don't want to call #finish below.
93
94
  request = nil
@@ -100,7 +101,7 @@ module Async
100
101
  end
101
102
  elsif response.status == 101
102
103
  # This code path is to support legacy behavior where the response status is set to 101, but the protocol is not upgraded. This may not be a valid use case, but it is supported for compatibility. We expect the response headers to contain the `upgrade` header.
103
- write_response(@version, response.status, response.headers)
104
+ write_response(@version, response.status, headers)
104
105
 
105
106
  # Same as above:
106
107
  request = nil
@@ -112,7 +113,7 @@ module Async
112
113
  write_tunnel_body(version, body)
113
114
  end
114
115
  else
115
- write_response(@version, response.status, response.headers)
116
+ write_response(@version, response.status, headers)
116
117
 
117
118
  if request.connect? and response.success?
118
119
  # Same as above:
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2025, by Samuel Williams.
4
+ # Copyright, 2018-2026, by Samuel Williams.
5
5
 
6
6
  require_relative "../request"
7
7
  require_relative "stream"
@@ -123,7 +123,10 @@ module Async
123
123
  protocol_headers << [CONTENT_LENGTH, length]
124
124
  end
125
125
 
126
- headers = ::Protocol::HTTP::Headers::Merged.new(protocol_headers, response.headers)
126
+ headers = ::Protocol::HTTP::Headers::Merged.new(
127
+ protocol_headers,
128
+ response.headers.header
129
+ )
127
130
 
128
131
  if body = response.body and !self.head?
129
132
  # This function informs the headers object that any subsequent headers are going to be trailer. Therefore, it must be called *before* sending the headers, to avoid any race conditions.
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2025, by Samuel Williams.
4
+ # Copyright, 2018-2026, by Samuel Williams.
5
5
 
6
6
  require_relative "../response"
7
7
  require_relative "stream"
@@ -221,7 +221,7 @@ module Async
221
221
 
222
222
  headers = ::Protocol::HTTP::Headers::Merged.new(
223
223
  pseudo_headers,
224
- request.headers
224
+ request.headers.header
225
225
  )
226
226
 
227
227
  if request.body.nil?
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2025, by Samuel Williams.
4
+ # Copyright, 2018-2026, by Samuel Williams.
5
5
  # Copyright, 2022, by Marco Concetto Rudilosso.
6
6
  # Copyright, 2023, by Thomas Morgan.
7
7
 
@@ -36,7 +36,7 @@ module Async
36
36
 
37
37
  attr :input
38
38
 
39
- def add_header(key, value)
39
+ def add_header(key, value, trailer: false)
40
40
  if key == CONNECTION
41
41
  raise ::Protocol::HTTP2::HeaderError, "Connection header is not allowed!"
42
42
  elsif key.start_with? ":"
@@ -44,13 +44,13 @@ module Async
44
44
  elsif key =~ /[A-Z]/
45
45
  raise ::Protocol::HTTP2::HeaderError, "Invalid upper-case characters in header #{key}!"
46
46
  else
47
- @headers.add(key, value)
47
+ @headers.add(key, value, trailer: trailer)
48
48
  end
49
49
  end
50
50
 
51
51
  def receive_trailing_headers(headers, end_stream)
52
52
  headers.each do |key, value|
53
- add_header(key, value)
53
+ add_header(key, value, trailer: true)
54
54
  end
55
55
  end
56
56
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2025, by Samuel Williams.
4
+ # Copyright, 2018-2026, by Samuel Williams.
5
5
  # Copyright, 2019, by Brian Morearty.
6
6
 
7
7
  require_relative "defaulton"
@@ -43,7 +43,7 @@ module Async
43
43
  # alpn_protocol is only available if openssl v1.0.2+
44
44
  name = peer.alpn_protocol
45
45
 
46
- Console.debug(self) {"Negotiating protocol #{name.inspect}..."}
46
+ Console.debug(self){"Negotiating protocol #{name.inspect}..."}
47
47
 
48
48
  if protocol = HANDLERS[name]
49
49
  return protocol
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2017-2025, by Samuel Williams.
4
+ # Copyright, 2017-2026, by Samuel Williams.
5
5
  # Copyright, 2019, by Brian Morearty.
6
6
 
7
7
  require "async"
@@ -44,7 +44,7 @@ module Async
44
44
  def accept(peer, address, task: Task.current)
45
45
  connection = @protocol.server(peer)
46
46
 
47
- Console.debug(self) {"Incoming connnection from #{address.inspect} to #{@protocol}"}
47
+ Console.debug(self){"Incoming connnection from #{address.inspect} to #{@protocol}"}
48
48
 
49
49
  connection.each do |request|
50
50
  # We set the default scheme unless it was otherwise specified.
@@ -67,6 +67,9 @@ module Async
67
67
 
68
68
  # Wait for all children to finish:
69
69
  task.children.each(&:wait)
70
+ ensure
71
+ # Stop all children (accept loops) on exit:
72
+ task.children.each(&:stop)
70
73
  end
71
74
  end
72
75
  end
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Async
7
7
  module HTTP
8
- VERSION = "0.92.1"
8
+ VERSION = "0.92.2"
9
9
  end
10
10
  end
data/license.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
 
3
- Copyright, 2017-2025, by Samuel Williams.
3
+ Copyright, 2017-2026, by Samuel Williams.
4
4
  Copyright, 2018, by Viacheslav Koval.
5
5
  Copyright, 2018, by Janko Marohnić.
6
6
  Copyright, 2019, by Denis Talakevich.
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.92.2
20
+
21
+ - Better handling of trailers.
22
+
19
23
  ### v0.92.0
20
24
 
21
25
  - **Breaking**: Remove `Async::HTTP::Reference`. Use `Protocol::URL::Reference` directly instead.
@@ -52,11 +56,6 @@ Please see the [project releases](https://socketry.github.io/async-http/releases
52
56
 
53
57
  - Expose `protocol` and `endpoint` as tags to `async-pool` for improved instrumentation.
54
58
 
55
- ### v0.77.0
56
-
57
- - Improved HTTP/1 connection handling.
58
- - The input stream is no longer closed when the output stream is closed.
59
-
60
59
  ## See Also
61
60
 
62
61
  - [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.92.2
4
+
5
+ - Better handling of trailers.
6
+
3
7
  ## v0.92.0
4
8
 
5
9
  - **Breaking**: Remove `Async::HTTP::Reference`. Use `Protocol::URL::Reference` directly instead.
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.92.1
4
+ version: 0.92.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -138,28 +138,28 @@ dependencies:
138
138
  requirements:
139
139
  - - "~>"
140
140
  - !ruby/object:Gem::Version
141
- version: '0.49'
141
+ version: '0.58'
142
142
  type: :runtime
143
143
  prerelease: false
144
144
  version_requirements: !ruby/object:Gem::Requirement
145
145
  requirements:
146
146
  - - "~>"
147
147
  - !ruby/object:Gem::Version
148
- version: '0.49'
148
+ version: '0.58'
149
149
  - !ruby/object:Gem::Dependency
150
150
  name: protocol-http1
151
151
  requirement: !ruby/object:Gem::Requirement
152
152
  requirements:
153
153
  - - "~>"
154
154
  - !ruby/object:Gem::Version
155
- version: '0.30'
155
+ version: '0.36'
156
156
  type: :runtime
157
157
  prerelease: false
158
158
  version_requirements: !ruby/object:Gem::Requirement
159
159
  requirements:
160
160
  - - "~>"
161
161
  - !ruby/object:Gem::Version
162
- version: '0.30'
162
+ version: '0.36'
163
163
  - !ruby/object:Gem::Dependency
164
164
  name: protocol-http2
165
165
  requirement: !ruby/object:Gem::Requirement
@@ -284,7 +284,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
284
284
  - !ruby/object:Gem::Version
285
285
  version: '0'
286
286
  requirements: []
287
- rubygems_version: 3.7.2
287
+ rubygems_version: 4.0.3
288
288
  specification_version: 4
289
289
  summary: A HTTP client and server library.
290
290
  test_files: []
metadata.gz.sig CHANGED
Binary file