async-http 0.54.0 → 0.56.2

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: 58036943b2703b5583d7213ee79593b6d9edd2f5e84e431b78fc1bc960fdf591
4
- data.tar.gz: 014dbfce1a65d60894b9a1d474fa3f53e810e3a2f37c0493acac0abe83585ff5
3
+ metadata.gz: 550188f639092d3fc62fe8bc1e2120d01a6b316897ea9f43f9a2a4983735969a
4
+ data.tar.gz: e31110770c986aa3eb756332998b446c1a4d18faeac9cf86886f3c40841f4e24
5
5
  SHA512:
6
- metadata.gz: 446d57893e12466988963eb0becae11b8328bad7615317119f93c0c3a0fd696a457f7928ed2b1cbb3e3ce43436c8bf15e9675ae57fe6c7fa73a9f685d5a0646e
7
- data.tar.gz: d75d5eb8e013c213c0a5e9fe8570965a59f1e042238daa72696a9b20e021bac4b4775ee2e6f23b389f9dff52f34b6c8c24938d4ce49eb7248149587ea04988e1
6
+ metadata.gz: c944bbbe72788fb06cb49bd68aaf3e17be61df0ad90d330d32e7ac2e3cf6967e190a9923ab3ceb03313fbfea661e5ae963c6ce58f2f02b24b660bc8d6ffd1213
7
+ data.tar.gz: c71a81cf8c1011a0bb988bf3a809efb354741fb372db561b2331bc973eb4a6e80608d6b689e0d288147a03d965accc2e36aba63edac121cec746149d6acdccbd
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,18 +33,18 @@ 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
 
40
40
  def self.client(peer)
41
- stream = IO::Stream.new(peer, sync: false)
41
+ stream = IO::Stream.new(peer, sync: true)
42
42
 
43
43
  return HTTP1::Client.new(stream, VERSION)
44
44
  end
45
45
 
46
46
  def self.server(peer)
47
- stream = IO::Stream.new(peer, sync: false)
47
+ stream = IO::Stream.new(peer, sync: true)
48
48
 
49
49
  return HTTP1::Server.new(stream, VERSION)
50
50
  end
@@ -29,9 +29,9 @@ 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
+ Console.logger.debug(self) {"#{request.method} #{request.path} #{request.headers.inspect}"}
33
33
 
34
- trailers = request.headers.trailers!
34
+ trailer = request.headers.trailer!
35
35
 
36
36
  # We carefully interpret https://tools.ietf.org/html/rfc7230#section-6.3.1 to implement this correctly.
37
37
  begin
@@ -63,13 +63,13 @@ module Async
63
63
  subtask.annotate("Streaming body.")
64
64
 
65
65
  # 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)
66
+ write_body(@version, body, false, trailer)
67
67
  end
68
68
  end
69
69
  elsif protocol = request.protocol
70
70
  write_upgrade_body(protocol)
71
71
  else
72
- write_body(@version, body, false, trailers)
72
+ write_body(@version, body, false, trailer)
73
73
  end
74
74
 
75
75
  return Response.read(self, request)
@@ -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,18 +32,18 @@ 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
 
39
39
  def self.client(peer)
40
- stream = IO::Stream.new(peer, sync: false)
40
+ stream = IO::Stream.new(peer, sync: true)
41
41
 
42
42
  return HTTP1::Client.new(stream, VERSION)
43
43
  end
44
44
 
45
45
  def self.server(peer)
46
- stream = IO::Stream.new(peer, sync: false)
46
+ stream = IO::Stream.new(peer, sync: true)
47
47
 
48
48
  return HTTP1::Server.new(stream, VERSION)
49
49
  end
@@ -32,18 +32,18 @@ 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
 
39
39
  def self.client(peer)
40
- stream = IO::Stream.new(peer, sync: false)
40
+ stream = IO::Stream.new(peer, sync: true)
41
41
 
42
42
  return HTTP1::Client.new(stream, VERSION)
43
43
  end
44
44
 
45
45
  def self.server(peer)
46
- stream = IO::Stream.new(peer, sync: false)
46
+ stream = IO::Stream.new(peer, sync: true)
47
47
 
48
48
  return HTTP1::Server.new(stream, VERSION)
49
49
  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
 
@@ -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(*)
@@ -107,6 +107,13 @@ module Async
107
107
  end
108
108
  rescue SocketError, IOError, EOFError, Errno::ECONNRESET, Errno::EPIPE, Async::Wrapper::Cancelled
109
109
  # Ignore.
110
+ rescue ::Protocol::HTTP2::GoawayError => error
111
+ # Error is raised if a response is actively reading from the
112
+ # connection. The connection is silently closed if GOAWAY is
113
+ # received outside the request/response cycle.
114
+ if @reader
115
+ self.close(error)
116
+ end
110
117
  ensure
111
118
  # Don't call #close twice.
112
119
  if @reader
@@ -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.0"
25
+ VERSION = "0.56.2"
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.0
4
+ version: 0.56.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-26 00:00:00.000000000 Z
11
+ date: 2021-05-08 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