async-http 0.54.1 → 0.56.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82df1313e46a49ebe4ba6c345c911dcf0c899e59361f09abaedc5f7c7979e61f
4
- data.tar.gz: 838d76ab9e99d661ac7be82169d6931325e64d22fab02ca93089d5da2ed13b31
3
+ metadata.gz: efbee0417c7ab944ad2ec6b6bd2c29735924d821b2396b02e78a6826874aa644
4
+ data.tar.gz: '08abaadc604cba6bb2ade84fd1387f962bab03c915f613c69cd5a1588666b431'
5
5
  SHA512:
6
- metadata.gz: 0d78d6636a59967ab8de9c76eddad387d6a607c04224563bf6599ab4b637d5fccceffa462d700c7f4d19c4ce1bee6b6f72562dd91cc6f9532802dbe1769f4315
7
- data.tar.gz: bcdc8bc22dfeb30ed425ad4117c682aca370acfab125a478cba7af03ec83b29eafabd5f8b0194adaf060dbdf03d7c926f348658cd9b89d4b5b12b583e33a9dc6
6
+ metadata.gz: 60cf32dd530b64e7919047f662ba3a94a81a05328a404c5e51e9d45f0f8a379f59462b7d04e52aa2a8e83d42df44605866aec128b87a8528d233ec1ecc8d44fc
7
+ data.tar.gz: 3c62522dbe7bb6915cf2d6613d356515911ebb63e5036c643073632b0571f62be2d254177fbf6565eb0044c31d3c21b5195cc98d6a43b5cf687851cdd531eebd
data/bake/async/http.rb CHANGED
@@ -68,8 +68,8 @@ def fetch(url, method:)
68
68
 
69
69
  response.finish
70
70
 
71
- if trailers = response.headers.trailers
72
- trailers.each do |key, value|
71
+ if trailer = response.headers.trailer
72
+ trailer.each do |key, value|
73
73
  terminal.print_line(
74
74
  :key, key.rjust(align), :reset, ": ", :value, value.inspect
75
75
  )
@@ -26,7 +26,7 @@ def server
26
26
 
27
27
  container = Async::Container.new
28
28
 
29
- Async.logger.info(self){"Starting server..."}
29
+ Console.logger.info(self){"Starting server..."}
30
30
 
31
31
  container.run(count: 1) do
32
32
  server = Async::HTTP::Server.for(endpoint, protocol: Async::HTTP::Protocol::HTTP2, scheme: "https") do |request|
@@ -32,13 +32,13 @@ module Async
32
32
  ::Protocol::HTTP::Response[status, headers, self.wrap(request, &block)]
33
33
  end
34
34
 
35
- def self.wrap(request, &block)
36
- self.new(request.body, &block)
35
+ def self.wrap(request = nil, &block)
36
+ self.new(block, request&.body)
37
37
  end
38
38
 
39
- def initialize(input = nil, &block)
40
- @input = input
39
+ def initialize(block, input = nil)
41
40
  @block = block
41
+ @input = input
42
42
 
43
43
  @task = nil
44
44
  @stream = nil
@@ -83,7 +83,7 @@ module Async
83
83
 
84
84
  def close
85
85
  while @pool.busy?
86
- Async.logger.warn(self) {"Waiting for #{@protocol} pool to drain: #{@pool}"}
86
+ Console.logger.warn(self) {"Waiting for #{@protocol} pool to drain: #{@pool}"}
87
87
  @pool.wait
88
88
  end
89
89
 
@@ -152,7 +152,7 @@ module Async
152
152
 
153
153
  def make_pool(connection_limit)
154
154
  Async::Pool::Controller.wrap(limit: connection_limit) do
155
- Async.logger.debug(self) {"Making connection to #{@endpoint.inspect}"}
155
+ Console.logger.debug(self) {"Making connection to #{@endpoint.inspect}"}
156
156
 
157
157
  @protocol.client(@endpoint.connect)
158
158
  end
@@ -22,8 +22,10 @@
22
22
 
23
23
  require_relative 'client'
24
24
  require_relative 'endpoint'
25
+
25
26
  require 'protocol/http/middleware'
26
27
  require 'protocol/http/body/buffered'
28
+ require 'protocol/http/accept_encoding'
27
29
 
28
30
  module Async
29
31
  module HTTP
@@ -48,13 +50,15 @@ module Async
48
50
  body = Body::Buffered.wrap(body)
49
51
  headers = ::Protocol::HTTP::Headers[headers]
50
52
 
51
- request = ::Protocol::HTTP::Request.new(client.scheme, endpoint.authority, method, endpoint.path, nil, headers, body)
53
+ request = ::Protocol::HTTP::Request.new(endpoint.scheme, endpoint.authority, method, endpoint.path, nil, headers, body)
52
54
 
53
55
  return client.call(request)
54
56
  end
55
57
 
56
58
  def client_for(endpoint)
57
- Client.new(endpoint, **@options)
59
+ ::Protocol::HTTP::AcceptEncoding.new(
60
+ Client.new(endpoint, **@options)
61
+ )
58
62
  end
59
63
 
60
64
  def close
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative '../internet'
24
+ require 'thread/local'
25
+
26
+ module Async
27
+ module HTTP
28
+ class Internet
29
+ # Provide access to a shared thread-local instance.
30
+ extend ::Thread::Local
31
+ end
32
+ end
33
+ end
@@ -33,7 +33,7 @@ module Async
33
33
  true
34
34
  end
35
35
 
36
- def self.trailers?
36
+ def self.trailer?
37
37
  true
38
38
  end
39
39
 
@@ -29,9 +29,12 @@ module Async
29
29
  class Client < Connection
30
30
  # Used by the client to send requests to the remote server.
31
31
  def call(request, task: Task.current)
32
- Async.logger.debug(self) {"#{request.method} #{request.path} #{request.headers.inspect}"}
32
+ # We need to keep track of connections which are not in the initial "ready" state.
33
+ @ready = false
33
34
 
34
- trailers = request.headers.trailers!
35
+ Console.logger.debug(self) {"#{request.method} #{request.path} #{request.headers.inspect}"}
36
+
37
+ trailer = request.headers.trailer!
35
38
 
36
39
  # We carefully interpret https://tools.ietf.org/html/rfc7230#section-6.3.1 to implement this correctly.
37
40
  begin
@@ -63,16 +66,19 @@ module Async
63
66
  subtask.annotate("Streaming body.")
64
67
 
65
68
  # Once we start writing the body, we can't recover if the request fails. That's because the body might be generated dynamically, streaming, etc.
66
- write_body(@version, body, false, trailers)
69
+ write_body(@version, body, false, trailer)
67
70
  end
68
71
  end
69
72
  elsif protocol = request.protocol
70
73
  write_upgrade_body(protocol)
71
74
  else
72
- write_body(@version, body, false, trailers)
75
+ write_body(@version, body, false, trailer)
73
76
  end
74
77
 
75
- return Response.read(self, request)
78
+ response = Response.read(self, request)
79
+ @ready = true
80
+
81
+ return response
76
82
  rescue
77
83
  # This will ensure that #reusable? returns false.
78
84
  @stream.close
@@ -33,6 +33,7 @@ module Async
33
33
  def initialize(stream, version)
34
34
  super(stream)
35
35
 
36
+ @ready = true
36
37
  @version = version
37
38
  end
38
39
 
@@ -48,8 +49,6 @@ module Async
48
49
 
49
50
  def read_line?
50
51
  @stream.read_until(CRLF)
51
- rescue Errno::ECONNRESET
52
- return nil
53
52
  end
54
53
 
55
54
  def read_line
@@ -68,11 +67,11 @@ module Async
68
67
 
69
68
  # Can we use this connection to make requests?
70
69
  def viable?
71
- @stream&.connected?
70
+ @ready && @stream&.connected?
72
71
  end
73
72
 
74
73
  def reusable?
75
- @persistent && @stream && !@stream.closed?
74
+ @ready && @persistent && @stream && !@stream.closed?
76
75
  end
77
76
  end
78
77
  end
@@ -64,7 +64,7 @@ module Async
64
64
  return if @stream.nil? or @stream.closed?
65
65
 
66
66
  if response
67
- trailers = response.headers.trailers!
67
+ trailer = response.headers.trailer!
68
68
 
69
69
  write_response(@version, response.status, response.headers)
70
70
 
@@ -95,7 +95,7 @@ module Async
95
95
  request = nil unless body
96
96
  response = nil
97
97
 
98
- write_body(version, body, head, trailers)
98
+ write_body(version, body, head, trailer)
99
99
  end
100
100
  else
101
101
  # If the request failed to generate a response, it was an internal server error:
@@ -32,7 +32,7 @@ module Async
32
32
  false
33
33
  end
34
34
 
35
- def self.trailers?
35
+ def self.trailer?
36
36
  false
37
37
  end
38
38
 
@@ -32,7 +32,7 @@ module Async
32
32
  true
33
33
  end
34
34
 
35
- def self.trailers?
35
+ def self.trailer?
36
36
  true
37
37
  end
38
38
 
@@ -33,7 +33,7 @@ module Async
33
33
  true
34
34
  end
35
35
 
36
- def self.trailers?
36
+ def self.trailer?
37
37
  true
38
38
  end
39
39
 
@@ -38,7 +38,7 @@ module Async
38
38
 
39
39
  CONTENT_LENGTH = 'content-length'.freeze
40
40
  CONNECTION = 'connection'.freeze
41
- TRAILERS = 'trailers'.freeze
41
+ TRAILER = 'trailer'.freeze
42
42
 
43
43
  module Connection
44
44
  def initialize(*)
@@ -27,17 +27,17 @@ module Async
27
27
  module Protocol
28
28
  module HTTP2
29
29
  class Output
30
- def initialize(stream, body, trailers = nil)
30
+ def initialize(stream, body, trailer = nil)
31
31
  @stream = stream
32
32
  @body = body
33
- @trailers = trailers
33
+ @trailer = trailer
34
34
 
35
35
  @task = nil
36
36
 
37
37
  @window_updated = Async::Condition.new
38
38
  end
39
39
 
40
- attr :trailers
40
+ attr :trailer
41
41
 
42
42
  def start(parent: Task.current)
43
43
  raise "Task already started!" if @task
@@ -145,12 +145,12 @@ module Async
145
145
  headers = ::Protocol::HTTP::Headers::Merged.new(protocol_headers, response.headers)
146
146
 
147
147
  if body = response.body and !self.head?
148
- # 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.
149
- trailers = response.headers.trailers!
148
+ # 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.
149
+ trailer = response.headers.trailer!
150
150
 
151
151
  @stream.send_headers(nil, headers)
152
152
 
153
- @stream.send_body(body, trailers)
153
+ @stream.send_body(body, trailer)
154
154
  else
155
155
  # Ensure the response body is closed if we are ending the stream:
156
156
  response.close
@@ -208,8 +208,8 @@ module Async
208
208
  pseudo_headers << [CONTENT_LENGTH, length]
209
209
  end
210
210
 
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.
212
- trailers = request.headers.trailers!
211
+ # 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.
212
+ trailer = request.headers.trailer!
213
213
 
214
214
  begin
215
215
  @stream.send_headers(nil, headers)
@@ -217,7 +217,7 @@ module Async
217
217
  raise RequestFailed
218
218
  end
219
219
 
220
- @stream.send_body(request.body, trailers)
220
+ @stream.send_body(request.body, trailer)
221
221
  end
222
222
  end
223
223
  end
@@ -34,7 +34,7 @@ module Async
34
34
  super
35
35
 
36
36
  @headers = nil
37
- @trailers = nil
37
+ @trailer = nil
38
38
 
39
39
  # Input buffer, reading request body, or response body (receive_data):
40
40
  @length = nil
@@ -62,7 +62,7 @@ module Async
62
62
 
63
63
  def receive_trailing_headers(headers, end_stream)
64
64
  headers.each do |key, value|
65
- if @trailers.include?(key)
65
+ if @trailer.include?(key)
66
66
  add_header(key, value)
67
67
  else
68
68
  raise ::Protocol::HTTP2::HeaderError, "Cannot add trailer #{key} as it was not specified as a trailer!"
@@ -75,8 +75,8 @@ module Async
75
75
  @headers = ::Protocol::HTTP::Headers.new
76
76
  self.receive_initial_headers(super, frame.end_stream?)
77
77
 
78
- @trailers = @headers[TRAILERS]
79
- elsif @trailers and frame.end_stream?
78
+ @trailer = @headers[TRAILER]
79
+ elsif @trailer and frame.end_stream?
80
80
  self.receive_trailing_headers(super, frame.end_stream?)
81
81
  else
82
82
  raise ::Protocol::HTTP2::HeaderError, "Unable to process headers!"
@@ -88,7 +88,7 @@ module Async
88
88
  @input = nil
89
89
  end
90
90
  rescue ::Protocol::HTTP2::HeaderError => error
91
- Async.logger.error(self, error)
91
+ Console.logger.error(self, error)
92
92
 
93
93
  send_reset_stream(error.code)
94
94
  end
@@ -136,24 +136,24 @@ module Async
136
136
  end
137
137
 
138
138
  # Set the body and begin sending it.
139
- def send_body(body, trailers = nil)
140
- @output = Output.new(self, body, trailers)
139
+ def send_body(body, trailer = nil)
140
+ @output = Output.new(self, body, trailer)
141
141
 
142
142
  @output.start
143
143
  end
144
144
 
145
145
  # Called when the output terminates normally.
146
146
  def finish_output(error = nil)
147
- trailers = @output&.trailers
147
+ trailer = @output&.trailer
148
148
 
149
149
  @output = nil
150
150
 
151
151
  if error
152
152
  send_reset_stream(::Protocol::HTTP2::Error::INTERNAL_ERROR)
153
153
  else
154
- # Write trailers?
155
- if trailers
156
- send_headers(nil, trailers, ::Protocol::HTTP2::END_STREAM)
154
+ # Write trailer?
155
+ if trailer
156
+ send_headers(nil, trailer, ::Protocol::HTTP2::END_STREAM)
157
157
  else
158
158
  send_data(nil, ::Protocol::HTTP2::END_STREAM)
159
159
  end
@@ -59,7 +59,7 @@ module Async
59
59
  # alpn_protocol is only available if openssl v1.0.2+
60
60
  name = peer.alpn_protocol
61
61
 
62
- Async.logger.debug(self) {"Negotiating protocol #{name.inspect}..."}
62
+ Console.logger.debug(self) {"Negotiating protocol #{name.inspect}..."}
63
63
 
64
64
  if protocol = HANDLERS[name]
65
65
  return protocol
@@ -48,7 +48,7 @@ module Async
48
48
  def accept(peer, address, task: Task.current)
49
49
  connection = @protocol.server(peer)
50
50
 
51
- Async.logger.debug(self) {"Incoming connnection from #{address.inspect} to #{@protocol}"}
51
+ Console.logger.debug(self) {"Incoming connnection from #{address.inspect} to #{@protocol}"}
52
52
 
53
53
  connection.each do |request|
54
54
  # We set the default scheme unless it was otherwise specified.
@@ -58,7 +58,7 @@ module Async
58
58
  # This is a slight optimization to avoid having to get the address from the socket.
59
59
  request.remote_address = address
60
60
 
61
- # Async.logger.debug(self) {"Incoming request from #{address.inspect}: #{request.method} #{request.path}"}
61
+ # Console.logger.debug(self) {"Incoming request from #{address.inspect}: #{request.method} #{request.path}"}
62
62
 
63
63
  # If this returns nil, we assume that the connection has been hijacked.
64
64
  self.call(request)
@@ -22,6 +22,6 @@
22
22
 
23
23
  module Async
24
24
  module HTTP
25
- VERSION = "0.54.1"
25
+ VERSION = "0.56.3"
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.54.1
4
+ version: 0.56.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-06 00:00:00.000000000 Z
11
+ date: 2021-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -58,28 +58,28 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.21.0
61
+ version: 0.22.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.21.0
68
+ version: 0.22.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: protocol-http1
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.13.0
75
+ version: 0.14.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.13.0
82
+ version: 0.14.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: protocol-http2
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -197,6 +197,7 @@ files:
197
197
  - lib/async/http/client.rb
198
198
  - lib/async/http/endpoint.rb
199
199
  - lib/async/http/internet.rb
200
+ - lib/async/http/internet/instance.rb
200
201
  - lib/async/http/protocol.rb
201
202
  - lib/async/http/protocol/http1.rb
202
203
  - lib/async/http/protocol/http1/client.rb
@@ -243,7 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
244
  - !ruby/object:Gem::Version
244
245
  version: '0'
245
246
  requirements: []
246
- rubygems_version: 3.1.2
247
+ rubygems_version: 3.3.0.dev
247
248
  signing_key:
248
249
  specification_version: 4
249
250
  summary: A HTTP client and server library.