async-http 0.52.3 → 0.54.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/bake/async/http/h2spec.rb +1 -1
  3. data/lib/async/http/body/delayed.rb +2 -2
  4. data/lib/async/http/body/hijack.rb +5 -0
  5. data/lib/async/http/body/pipe.rb +15 -7
  6. data/lib/async/http/body/slowloris.rb +2 -2
  7. data/lib/async/http/body/stream.rb +1 -1
  8. data/lib/async/http/client.rb +3 -3
  9. data/lib/async/http/endpoint.rb +2 -2
  10. data/lib/async/http/internet.rb +4 -0
  11. data/lib/async/http/protocol/http1/connection.rb +0 -5
  12. data/lib/async/http/protocol/http1/server.rb +4 -3
  13. data/lib/async/http/protocol/http2.rb +0 -18
  14. data/lib/async/http/protocol/http2/output.rb +1 -1
  15. data/lib/async/http/protocol/http2/request.rb +0 -38
  16. data/lib/async/http/protocol/http2/response.rb +6 -13
  17. data/lib/async/http/protocol/request.rb +0 -4
  18. data/lib/async/http/proxy.rb +24 -8
  19. data/lib/async/http/server.rb +3 -3
  20. data/lib/async/http/version.rb +1 -1
  21. metadata +23 -65
  22. data/.editorconfig +0 -6
  23. data/.github/workflows/development.yml +0 -52
  24. data/.gitignore +0 -15
  25. data/.rspec +0 -3
  26. data/.travis.yml +0 -35
  27. data/README.md +0 -365
  28. data/async-http.gemspec +0 -39
  29. data/bake.rb +0 -0
  30. data/examples/compare/Gemfile +0 -9
  31. data/examples/compare/benchmark.rb +0 -78
  32. data/examples/download/chunked.rb +0 -86
  33. data/examples/fetch/Gemfile +0 -3
  34. data/examples/fetch/Gemfile.lock +0 -74
  35. data/examples/fetch/README.md +0 -3
  36. data/examples/fetch/config.ru +0 -28
  37. data/examples/fetch/public/index.html +0 -23
  38. data/examples/fetch/public/stream.js +0 -56
  39. data/examples/google/search.rb +0 -47
  40. data/examples/request.rb +0 -38
  41. data/examples/stream/stop.rb +0 -28
  42. data/examples/trenni/Gemfile +0 -5
  43. data/examples/trenni/streaming.rb +0 -35
  44. data/examples/upload/client.rb +0 -39
  45. data/examples/upload/data.txt +0 -41
  46. data/examples/upload/server.rb +0 -19
  47. data/examples/upload/upload.rb +0 -26
  48. data/gems.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b5f422d50d91e0a55cf4a231bab122661198bf277ef483c5d342feb96f5e5d0
4
- data.tar.gz: acf9ea6b2d1c332b73ead3f4203725cc3a750418ceb945a8ca1f431c71e8cfba
3
+ metadata.gz: 58036943b2703b5583d7213ee79593b6d9edd2f5e84e431b78fc1bc960fdf591
4
+ data.tar.gz: 014dbfce1a65d60894b9a1d474fa3f53e810e3a2f37c0493acac0abe83585ff5
5
5
  SHA512:
6
- metadata.gz: 9744602130e3f4587f9e56e26cff4db9656b36685ae4ca6d15275e858c27bc239bec304e7146620231a0bb1619f11dea6153ccb41573caa80f94a4904f1a5edc
7
- data.tar.gz: 4907eba09d6899a0bb97b59c3f75e35bed686b3b103107d69b96298f0358a7bb188f1358f4a799fe97c8837a34044af74ea5ba7728b9eb86592f208d1091b505
6
+ metadata.gz: 446d57893e12466988963eb0becae11b8328bad7615317119f93c0c3a0fd696a457f7928ed2b1cbb3e3ce43436c8bf15e9675ae57fe6c7fa73a9f685d5a0646e
7
+ data.tar.gz: d75d5eb8e013c213c0a5e9fe8570965a59f1e042238daa72696a9b20e021bac4b4775ee2e6f23b389f9dff52f34b6c8c24938d4ce49eb7248149587ea04988e1
@@ -29,7 +29,7 @@ def server
29
29
  Async.logger.info(self){"Starting server..."}
30
30
 
31
31
  container.run(count: 1) do
32
- server = Async::HTTP::Server.for(endpoint, Async::HTTP::Protocol::HTTP2, "https") do |request|
32
+ server = Async::HTTP::Server.for(endpoint, protocol: Async::HTTP::Protocol::HTTP2, scheme: "https") do |request|
33
33
  Protocol::HTTP::Response[200, {'content-type' => 'text/plain'}, ["Hello World"]]
34
34
  end
35
35
 
@@ -20,12 +20,12 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
  # THE SOFTWARE.
22
22
 
23
- require_relative 'wrapper'
23
+ require 'protocol/http/body/wrapper'
24
24
 
25
25
  module Async
26
26
  module HTTP
27
27
  module Body
28
- class Delayed < Async::HTTP::Body::Wrapper
28
+ class Delayed < Protocol::HTTP::Body::Wrapper
29
29
  def initialize(body, delay = 0.01)
30
30
  super(body)
31
31
 
@@ -44,6 +44,11 @@ module Async
44
44
  @stream = nil
45
45
  end
46
46
 
47
+ # We prefer streaming directly as it's the lowest overhead.
48
+ def stream?
49
+ true
50
+ end
51
+
47
52
  def call(stream)
48
53
  return @block.call(stream)
49
54
  end
@@ -20,6 +20,9 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
21
  # THE SOFTWARE.
22
22
 
23
+ require 'async/io/socket'
24
+ require 'async/io/stream'
25
+
23
26
  require_relative 'writable'
24
27
 
25
28
  module Async
@@ -39,8 +42,8 @@ module Async
39
42
  @reader = nil
40
43
  @writer = nil
41
44
 
42
- task.async(&self.method(:reader))
43
- task.async(&self.method(:writer))
45
+ task.async(transient: true, &self.method(:reader))
46
+ task.async(transient: true, &self.method(:writer))
44
47
  end
45
48
 
46
49
  def to_io
@@ -69,10 +72,9 @@ module Async
69
72
 
70
73
  @head.close_write
71
74
  ensure
72
- @reader = nil
73
75
  @input.close($!)
74
76
 
75
- @head.close if @writer.nil?
77
+ close_head if @writer&.finished?
76
78
  end
77
79
 
78
80
  # Read from the head of the pipe and write to the @output stream.
@@ -86,11 +88,17 @@ module Async
86
88
  @output.write(chunk)
87
89
  end
88
90
  ensure
89
- @writer = nil
90
-
91
91
  @output.close($!)
92
92
 
93
- @head.close if @reader.nil?
93
+ close_head if @reader&.finished?
94
+ end
95
+
96
+ def close_head
97
+ @head.close
98
+
99
+ # Both tasks are done, don't keep references:
100
+ @reader = nil
101
+ @writer = nil
94
102
  end
95
103
  end
96
104
  end
@@ -37,8 +37,8 @@ module Async
37
37
 
38
38
  # In order for this implementation to work correctly, you need to use a LimitedQueue.
39
39
  # @param minimum_throughput [Integer] the minimum bytes per second otherwise this body will be forcefully closed.
40
- def initialize(*args, minimum_throughput: 1024, **options)
41
- super(*args, **options)
40
+ def initialize(*arguments, minimum_throughput: 1024, **options)
41
+ super(*arguments, **options)
42
42
 
43
43
  @minimum_throughput = minimum_throughput
44
44
 
@@ -139,7 +139,7 @@ module Async
139
139
  end
140
140
 
141
141
  # Close the input and output bodies.
142
- def close
142
+ def close(error = nil)
143
143
  self.close_read
144
144
  self.close_write
145
145
  ensure
@@ -25,7 +25,7 @@ require 'async/io/stream'
25
25
 
26
26
  require 'async/pool/controller'
27
27
 
28
- require 'protocol/http/body/streamable'
28
+ require 'protocol/http/body/completable'
29
29
  require 'protocol/http/methods'
30
30
 
31
31
  require_relative 'protocol'
@@ -45,7 +45,7 @@ module Async
45
45
  # @param protocol [Protocol::HTTP1 | Protocol::HTTP2 | Protocol::HTTPS] the protocol to use.
46
46
  # @param scheme [String] The default scheme to set to requests.
47
47
  # @param authority [String] The default authority to set to requests.
48
- def initialize(endpoint, protocol = endpoint.protocol, scheme = endpoint.scheme, authority = endpoint.authority, retries: DEFAULT_RETRIES, connection_limit: DEFAULT_CONNECTION_LIMIT)
48
+ def initialize(endpoint, protocol: endpoint.protocol, scheme: endpoint.scheme, authority: endpoint.authority, retries: DEFAULT_RETRIES, connection_limit: DEFAULT_CONNECTION_LIMIT)
49
49
  @endpoint = endpoint
50
50
  @protocol = protocol
51
51
 
@@ -143,7 +143,7 @@ module Async
143
143
  response = request.call(connection)
144
144
 
145
145
  # The connection won't be released until the body is completely read/released.
146
- ::Protocol::HTTP::Body::Streamable.wrap(response) do
146
+ ::Protocol::HTTP::Body::Completable.wrap(response) do
147
147
  @pool.release(connection)
148
148
  end
149
149
 
@@ -193,8 +193,8 @@ module Async
193
193
  @endpoint ||= build_endpoint
194
194
  end
195
195
 
196
- def bind(*args, &block)
197
- endpoint.bind(*args, &block)
196
+ def bind(*arguments, &block)
197
+ endpoint.bind(*arguments, &block)
198
198
  end
199
199
 
200
200
  def connect(&block)
@@ -33,6 +33,10 @@ module Async
33
33
  @options = options
34
34
  end
35
35
 
36
+ # A cache of clients.
37
+ # @attribute [Hash(URI, Client)]
38
+ attr :clients
39
+
36
40
  def call(method, url, headers = nil, body = nil)
37
41
  endpoint = Endpoint.parse(url)
38
42
  key = host_key(endpoint)
@@ -74,11 +74,6 @@ module Async
74
74
  def reusable?
75
75
  @persistent && @stream && !@stream.closed?
76
76
  end
77
-
78
- def close
79
- Async.logger.debug(self) {"Closing connection"}
80
- super
81
- end
82
77
  end
83
78
  end
84
79
  end
@@ -56,7 +56,7 @@ module Async
56
56
 
57
57
  # Server loop.
58
58
  def each(task: Task.current)
59
- task.annotate("Reading #{version} requests for #{self.class}.")
59
+ task.annotate("Reading #{self.version} requests for #{self.class}.")
60
60
 
61
61
  while request = next_request
62
62
  response = yield(request, self)
@@ -80,7 +80,7 @@ module Async
80
80
  response = nil
81
81
 
82
82
  body.call(stream)
83
- elsif body and request.connect?
83
+ elsif request.connect? and response.success?
84
84
  stream = write_tunnel_body(request.version)
85
85
 
86
86
  # Same as above:
@@ -90,11 +90,12 @@ module Async
90
90
  body.call(stream)
91
91
  else
92
92
  head = request.head?
93
+ version = request.version
93
94
 
94
95
  request = nil unless body
95
96
  response = nil
96
97
 
97
- write_body(request.version, body, head, trailers)
98
+ write_body(version, body, head, trailers)
98
99
  end
99
100
  else
100
101
  # If the request failed to generate a response, it was an internal server error:
@@ -76,24 +76,6 @@ module Async
76
76
  def self.names
77
77
  ["h2"]
78
78
  end
79
-
80
- module WithPush
81
- CLIENT_SETTINGS = HTTP2::CLIENT_SETTINGS.merge(
82
- ::Protocol::HTTP2::Settings::ENABLE_PUSH => 1,
83
- )
84
-
85
- def self.client(peer, settings = CLIENT_SETTINGS)
86
- HTTP2.client(peer, settings)
87
- end
88
-
89
- def self.server(peer, settings = SERVER_SETTINGS)
90
- HTTP2.server(peer, settings)
91
- end
92
-
93
- def self.names
94
- HTTP2.names
95
- end
96
- end
97
79
  end
98
80
  end
99
81
  end
@@ -42,7 +42,7 @@ module Async
42
42
  def start(parent: Task.current)
43
43
  raise "Task already started!" if @task
44
44
 
45
- if @body.respond_to?(:call)
45
+ if @body.stream?
46
46
  @task = parent.async(&self.method(:stream))
47
47
  else
48
48
  @task = parent.async(&self.method(:passthrough))
@@ -39,18 +39,6 @@ module Async
39
39
 
40
40
  attr :request
41
41
 
42
- # Create a fake request on the server, with the given headers.
43
- def create_push_promise_stream(headers)
44
- stream = @connection.create_push_promise_stream(&Stream.method(:create))
45
-
46
- stream.headers = ::Protocol::HTTP::Headers.new
47
-
48
- # This will ultimately enqueue the request to be processed by the server:
49
- stream.receive_initial_headers(headers, false)
50
-
51
- return stream
52
- end
53
-
54
42
  def receive_initial_headers(headers, end_stream)
55
43
  headers.each do |key, value|
56
44
  if key == SCHEME
@@ -133,32 +121,6 @@ module Async
133
121
  false
134
122
  end
135
123
 
136
- def push?
137
- @stream.connection.enable_push?
138
- end
139
-
140
- # @return [Stream] the promised stream, on which to send data.
141
- def push(path, headers = nil, scheme = @scheme, authority = @authority)
142
- raise ArgumentError, "Missing scheme!" unless scheme
143
- raise ArgumentError, "Missing authority!" unless authority
144
-
145
- push_headers = [
146
- [SCHEME, scheme],
147
- [METHOD, ::Protocol::HTTP::Methods::GET],
148
- [PATH, path],
149
- [AUTHORITY, authority]
150
- ]
151
-
152
- if headers
153
- push_headers = Headers::Merged.new(
154
- push_headers,
155
- headers
156
- )
157
- end
158
-
159
- @stream.send_push_promise(push_headers)
160
- end
161
-
162
124
  NO_RESPONSE = [
163
125
  [STATUS, '500'],
164
126
  ]
@@ -50,13 +50,7 @@ module Async
50
50
  end
51
51
 
52
52
  def accept_push_promise_stream(promised_stream_id, headers)
53
- stream = @connection.accept_push_promise_stream(promised_stream_id, &Stream.method(:create))
54
-
55
- stream.response.build_request(headers)
56
-
57
- @response.promises.enqueue(stream.response)
58
-
59
- return stream
53
+ raise ProtocolError, "Cannot accept push promise stream!"
60
54
  end
61
55
 
62
56
  # This should be invoked from the background reader, and notifies the task waiting for the headers that we are done.
@@ -113,7 +107,6 @@ module Async
113
107
  super
114
108
 
115
109
  if @response
116
- @response.promises.enqueue nil
117
110
  @response = nil
118
111
  end
119
112
 
@@ -128,7 +121,6 @@ module Async
128
121
 
129
122
  @stream = stream
130
123
  @request = nil
131
- @promises = nil
132
124
  end
133
125
 
134
126
  attr :stream
@@ -150,10 +142,6 @@ module Async
150
142
  !!@status
151
143
  end
152
144
 
153
- def promises
154
- @promises ||= Async::Queue.new
155
- end
156
-
157
145
  def build_request(headers)
158
146
  request = ::Protocol::HTTP::Request.new
159
147
  request.headers = ::Protocol::HTTP::Headers.new
@@ -215,6 +203,11 @@ module Async
215
203
  if request.body.nil?
216
204
  @stream.send_headers(nil, headers, ::Protocol::HTTP2::END_STREAM)
217
205
  else
206
+ if length = request.body.length
207
+ # This puts it at the end of the pseudo-headers:
208
+ pseudo_headers << [CONTENT_LENGTH, length]
209
+ end
210
+
218
211
  # This function informs the headers object that any subsequent headers are going to be trailers. Therefore, it must be called *before* sending the headers, to avoid any race conditions.
219
212
  trailers = request.headers.trailers!
220
213
 
@@ -42,10 +42,6 @@ module Async
42
42
  false
43
43
  end
44
44
 
45
- def push?
46
- false
47
- end
48
-
49
45
  def peer
50
46
  if connection = self.connection
51
47
  connection.peer
@@ -30,6 +30,15 @@ module Async
30
30
  # Wraps a client, address and headers required to initiate a connectio to a remote host using the CONNECT verb.
31
31
  # Behaves like a TCP endpoint for the purposes of connecting to a remote host.
32
32
  class Proxy
33
+ class ConnectFailure < StandardError
34
+ def initialize(response)
35
+ super "Failed to connect: #{response.status}"
36
+ @response = response
37
+ end
38
+
39
+ attr :response
40
+ end
41
+
33
42
  module Client
34
43
  def proxy(endpoint, headers = nil)
35
44
  Proxy.new(self, endpoint.authority(false), headers)
@@ -92,14 +101,21 @@ module Async
92
101
 
93
102
  response = @client.connect(@address.to_s, @headers, input)
94
103
 
95
- pipe = Body::Pipe.new(response.body, input)
96
-
97
- return pipe.to_io unless block_given?
98
-
99
- begin
100
- yield pipe.to_io
101
- ensure
102
- pipe.close
104
+ if response.success?
105
+ pipe = Body::Pipe.new(response.body, input)
106
+
107
+ return pipe.to_io unless block_given?
108
+
109
+ begin
110
+ yield pipe.to_io
111
+ ensure
112
+ pipe.close
113
+ end
114
+ else
115
+ # This ensures we don't leave a response dangling:
116
+ response.close
117
+
118
+ raise ConnectFailure, response
103
119
  end
104
120
  end
105
121
 
@@ -29,11 +29,11 @@ require 'protocol/http/middleware'
29
29
  module Async
30
30
  module HTTP
31
31
  class Server < ::Protocol::HTTP::Middleware
32
- def self.for(*arguments, &block)
33
- self.new(block, *arguments)
32
+ def self.for(*arguments, **options, &block)
33
+ self.new(block, *arguments, **options)
34
34
  end
35
35
 
36
- def initialize(app, endpoint, protocol = endpoint.protocol, scheme = endpoint.scheme)
36
+ def initialize(app, endpoint, protocol: endpoint.protocol, scheme: endpoint.scheme)
37
37
  super(app)
38
38
 
39
39
  @endpoint = endpoint
@@ -22,6 +22,6 @@
22
22
 
23
23
  module Async
24
24
  module HTTP
25
- VERSION = "0.52.3"
25
+ VERSION = "0.54.0"
26
26
  end
27
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.52.3
4
+ version: 0.54.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-08 00:00:00.000000000 Z
11
+ date: 2020-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.20.0
61
+ version: 0.21.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.20.0
68
+ version: 0.21.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: protocol-http1
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -95,35 +95,35 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: 0.14.0
97
97
  - !ruby/object:Gem::Dependency
98
- name: async-rspec
98
+ name: async-container
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '1.10'
103
+ version: '0.14'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '1.10'
110
+ version: '0.14'
111
111
  - !ruby/object:Gem::Dependency
112
- name: async-container
112
+ name: async-rspec
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.14.0
117
+ version: '1.10'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.14.0
124
+ version: '1.10'
125
125
  - !ruby/object:Gem::Dependency
126
- name: rack-test
126
+ name: covered
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
@@ -137,7 +137,7 @@ dependencies:
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
- name: covered
140
+ name: rack-test
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - ">="
@@ -151,21 +151,21 @@ dependencies:
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
- name: bundler
154
+ name: rspec
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - ">="
157
+ - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: '0'
159
+ version: '3.6'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - ">="
164
+ - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: '0'
166
+ version: '3.6'
167
167
  - !ruby/object:Gem::Dependency
168
- name: bake-bundler
168
+ name: localhost
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - ">="
@@ -178,56 +178,14 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
- - !ruby/object:Gem::Dependency
182
- name: rspec
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - "~>"
186
- - !ruby/object:Gem::Version
187
- version: '3.6'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - "~>"
193
- - !ruby/object:Gem::Version
194
- version: '3.6'
195
- description:
181
+ description:
196
182
  email:
197
- - samuel.williams@oriontransfer.co.nz
198
183
  executables: []
199
184
  extensions: []
200
185
  extra_rdoc_files: []
201
186
  files:
202
- - ".editorconfig"
203
- - ".github/workflows/development.yml"
204
- - ".gitignore"
205
- - ".rspec"
206
- - ".travis.yml"
207
- - README.md
208
- - async-http.gemspec
209
- - bake.rb
210
187
  - bake/async/http.rb
211
188
  - bake/async/http/h2spec.rb
212
- - examples/compare/Gemfile
213
- - examples/compare/benchmark.rb
214
- - examples/download/chunked.rb
215
- - examples/fetch/Gemfile
216
- - examples/fetch/Gemfile.lock
217
- - examples/fetch/README.md
218
- - examples/fetch/config.ru
219
- - examples/fetch/public/index.html
220
- - examples/fetch/public/stream.js
221
- - examples/google/search.rb
222
- - examples/request.rb
223
- - examples/stream/stop.rb
224
- - examples/trenni/Gemfile
225
- - examples/trenni/streaming.rb
226
- - examples/upload/client.rb
227
- - examples/upload/data.txt
228
- - examples/upload/server.rb
229
- - examples/upload/upload.rb
230
- - gems.rb
231
189
  - lib/async/http.rb
232
190
  - lib/async/http/body.rb
233
191
  - lib/async/http/body/delayed.rb
@@ -270,7 +228,7 @@ homepage: https://github.com/socketry/async-http
270
228
  licenses:
271
229
  - MIT
272
230
  metadata: {}
273
- post_install_message:
231
+ post_install_message:
274
232
  rdoc_options: []
275
233
  require_paths:
276
234
  - lib
@@ -285,8 +243,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
285
243
  - !ruby/object:Gem::Version
286
244
  version: '0'
287
245
  requirements: []
288
- rubygems_version: 3.1.2
289
- signing_key:
246
+ rubygems_version: 3.2.3
247
+ signing_key:
290
248
  specification_version: 4
291
249
  summary: A HTTP client and server library.
292
250
  test_files: []