Class: Async::HTTP::Protocol::HTTP2
- Inherits:
-
Object
- Object
- Async::HTTP::Protocol::HTTP2
show all
- Defined in:
- lib/async/http/protocol/http2.rb
Overview
A server that supports both HTTP1.0 and HTTP1.1 semantics by detecting the version of the request.
Defined Under Namespace
Classes: Request, Response
Constant Summary
collapse
- HTTPS =
'https'.freeze
- SCHEME =
':scheme'.freeze
- METHOD =
':method'.freeze
- PATH =
':path'.freeze
- AUTHORITY =
':authority'.freeze
- REASON =
':reason'.freeze
- STATUS =
':status'.freeze
- VERSION =
'HTTP/2.0'.freeze
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(controller, stream) ⇒ HTTP2
Returns a new instance of HTTP2.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
# File 'lib/async/http/protocol/http2.rb', line 52
def initialize(controller, stream)
@controller = controller
@stream = stream
@controller.on(:frame) do |data|
@stream.write(data)
@stream.flush
end
@controller.on(:frame_sent) do |frame|
Async.logger.debug(self) {"Sent frame: #{frame.inspect}"}
end
@controller.on(:frame_received) do |frame|
Async.logger.debug(self) {"Received frame: #{frame.inspect}"}
end
@goaway = false
@controller.on(:goaway) do |payload|
Async.logger.error(self) {"goaway: #{payload.inspect}"}
@goaway = true
end
@count = 0
end
|
Instance Attribute Details
#count ⇒ Object
Returns the value of attribute count.
84
85
86
|
# File 'lib/async/http/protocol/http2.rb', line 84
def count
@count
end
|
Class Method Details
.client(stream) ⇒ Object
35
36
37
|
# File 'lib/async/http/protocol/http2.rb', line 35
def self.client(stream)
self.new(::HTTP2::Client.new, stream)
end
|
.server(stream) ⇒ Object
39
40
41
|
# File 'lib/async/http/protocol/http2.rb', line 39
def self.server(stream)
self.new(::HTTP2::Server.new, stream)
end
|
Instance Method Details
#call(request) ⇒ Object
Used by the client to send requests to the remote server.
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
|
# File 'lib/async/http/protocol/http2.rb', line 266
def call(request)
@count += 1
stream = @controller.new_stream
response = Response.new(self, stream)
body = response.body
exception = nil
finished = Async::Notification.new
waiting = true
stream.on(:close) do |error|
if waiting
if error
exception = EOFError.new(error)
end
waiting = false
finished.signal
else
if error
body.stop(EOFError.new(error))
else
body.finish
end
end
end
stream.on(:headers) do ||
response.()
waiting = false
finished.signal
end
stream.on(:data) do |chunk|
begin
body.write(chunk.to_s) unless chunk.empty?
rescue
stream.close(:internal_error)
end
end
write_request(request, stream)
Async.logger.debug(self) {"Request sent, waiting for signal."}
finished.wait
if exception
raise exception
end
Async.logger.debug(self) {"Stream finished: #{response.inspect}"}
return response
end
|
#close ⇒ Object
120
121
122
123
124
125
|
# File 'lib/async/http/protocol/http2.rb', line 120
def close
Async.logger.debug(self) {"Closing connection"}
@reader.stop if @reader
@stream.close
end
|
#good? ⇒ Boolean
Can we use this connection to make requests?
92
93
94
|
# File 'lib/async/http/protocol/http2.rb', line 92
def good?
@stream.connected?
end
|
#multiplex ⇒ Object
Multiple requests can be processed at the same time.
87
88
89
|
# File 'lib/async/http/protocol/http2.rb', line 87
def multiplex
@controller.remote_settings[:settings_max_concurrent_streams]
end
|
#peer ⇒ Object
80
81
82
|
# File 'lib/async/http/protocol/http2.rb', line 80
def peer
@stream.io
end
|
#read_in_background(task: Task.current) ⇒ Object
108
109
110
111
112
113
114
115
116
117
118
|
# File 'lib/async/http/protocol/http2.rb', line 108
def read_in_background(task: Task.current)
task.async do |nested_task|
nested_task.annotate("#{version} reading data")
while buffer = @stream.read_partial
@controller << buffer
end
Async.logger.debug(self) {"Connection reset by peer!"}
end
end
|
#receive_requests(task: Task.current, &block) ⇒ Object
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
# File 'lib/async/http/protocol/http2.rb', line 162
def receive_requests(task: Task.current, &block)
@controller.on(:stream) do |stream|
@count += 1
request = Request.new(self, stream)
body = request.body
stream.on(:headers) do ||
begin
request.()
rescue
Async.logger.error(self) {$!}
stream.({
STATUS => "400"
}, end_stream: true)
else
task.async do
generate_response(request, stream, &block)
end
end
end
stream.on(:data) do |chunk|
body.write(chunk.to_s) unless chunk.empty?
end
stream.on(:half_close) do
body.finish
end
stream.on(:close) do |error|
if error
body.stop(EOFError.new(error))
else
end
end
end
start_connection
@reader.wait
end
|
#reusable? ⇒ Boolean
96
97
98
|
# File 'lib/async/http/protocol/http2.rb', line 96
def reusable?
!@goaway || !@stream.closed?
end
|
#start_connection ⇒ Object
104
105
106
|
# File 'lib/async/http/protocol/http2.rb', line 104
def start_connection
@reader ||= read_in_background
end
|
#version ⇒ Object
100
101
102
|
# File 'lib/async/http/protocol/http2.rb', line 100
def version
VERSION
end
|