raptor 0.20.2 → 0.21.0
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 +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +28 -17
- data/docs/raptor-vs-puma.md +15 -9
- data/ext/raptor_http2/raptor_http2.c +12 -0
- data/lib/raptor/binder.rb +39 -13
- data/lib/raptor/cli.rb +10 -0
- data/lib/raptor/cluster.rb +5 -3
- data/lib/raptor/http.rb +18 -0
- data/lib/raptor/http1.rb +2 -20
- data/lib/raptor/http2.rb +406 -79
- data/lib/raptor/reactor.rb +142 -23
- data/lib/raptor/server.rb +12 -0
- data/lib/raptor/version.rb +1 -1
- data/sig/generated/raptor/binder.rbs +26 -13
- data/sig/generated/raptor/http.rbs +12 -0
- data/sig/generated/raptor/http1.rbs +0 -12
- data/sig/generated/raptor/http2.rbs +202 -15
- data/sig/generated/raptor/reactor.rbs +70 -8
- metadata +2 -2
data/lib/raptor/reactor.rb
CHANGED
|
@@ -5,10 +5,9 @@ require "nio"
|
|
|
5
5
|
require "red-black-tree"
|
|
6
6
|
|
|
7
7
|
module Raptor
|
|
8
|
-
# Multiplexes client connections
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
# completed requests back to the caller-provided handlers.
|
|
8
|
+
# Multiplexes client connections, manages connection deadlines, feeds
|
|
9
|
+
# ready bytes to the parser pipeline, and hands completed requests back
|
|
10
|
+
# to the caller-provided handlers.
|
|
12
11
|
#
|
|
13
12
|
class Reactor
|
|
14
13
|
# A client connection node ordered by absolute expiry time so the
|
|
@@ -59,6 +58,8 @@ module Raptor
|
|
|
59
58
|
# @rbs @first_data_timeout: Integer
|
|
60
59
|
# @rbs @chunk_data_timeout: Integer
|
|
61
60
|
# @rbs @persistent_data_timeout: Integer
|
|
61
|
+
# @rbs @http2_keepalive_interval: Integer
|
|
62
|
+
# @rbs @http2_keepalive_timeout: Integer
|
|
62
63
|
# @rbs @selector: NIO::Selector
|
|
63
64
|
# @rbs @queue: Queue[TCPSocket]
|
|
64
65
|
# @rbs @timeouts: RedBlackTree[TimeoutClient]
|
|
@@ -67,6 +68,9 @@ module Raptor
|
|
|
67
68
|
# @rbs @id_to_timeout: Hash[Integer, TimeoutClient]
|
|
68
69
|
# @rbs @id_to_writer: Hash[Integer, untyped]
|
|
69
70
|
# @rbs @id_to_flow_control: Hash[Integer, untyped]
|
|
71
|
+
# @rbs @id_to_http2_last_stream: Hash[Integer, Integer]
|
|
72
|
+
# @rbs @id_to_http2_drain_stream: Hash[Integer, Integer]
|
|
73
|
+
# @rbs @id_to_http2_keepalive: Hash[Integer, Hash[Symbol, untyped]]
|
|
70
74
|
|
|
71
75
|
# Creates a new Reactor instance.
|
|
72
76
|
#
|
|
@@ -78,16 +82,21 @@ module Raptor
|
|
|
78
82
|
# @option connection_options [Integer] :chunk_data_timeout timeout for subsequent chunks
|
|
79
83
|
# @param http1_options [Hash] HTTP/1.1-specific configuration
|
|
80
84
|
# @option http1_options [Integer] :persistent_data_timeout timeout for keep-alive idle connections
|
|
85
|
+
# @param http2_options [Hash] HTTP/2-specific configuration
|
|
86
|
+
# @option http2_options [Integer] :keepalive_interval idle time before sending a PING
|
|
87
|
+
# @option http2_options [Integer] :keepalive_timeout time to await a PING acknowledgement
|
|
81
88
|
# @return [void]
|
|
82
89
|
#
|
|
83
|
-
# @rbs (untyped http1_ractor_pool, untyped http2_ractor_pool, untyped thread_pool, connection_options: Hash[Symbol, untyped], http1_options: Hash[Symbol, untyped]) -> void
|
|
84
|
-
def initialize(http1_ractor_pool, http2_ractor_pool, thread_pool, connection_options:, http1_options:)
|
|
90
|
+
# @rbs (untyped http1_ractor_pool, untyped http2_ractor_pool, untyped thread_pool, connection_options: Hash[Symbol, untyped], http1_options: Hash[Symbol, untyped], http2_options: Hash[Symbol, untyped]) -> void
|
|
91
|
+
def initialize(http1_ractor_pool, http2_ractor_pool, thread_pool, connection_options:, http1_options:, http2_options:)
|
|
85
92
|
@http1_ractor_pool = http1_ractor_pool
|
|
86
93
|
@http2_ractor_pool = http2_ractor_pool
|
|
87
94
|
@thread_pool = thread_pool
|
|
88
95
|
@first_data_timeout = connection_options[:first_data_timeout]
|
|
89
96
|
@chunk_data_timeout = connection_options[:chunk_data_timeout]
|
|
90
97
|
@persistent_data_timeout = http1_options[:persistent_data_timeout]
|
|
98
|
+
@http2_keepalive_interval = http2_options[:keepalive_interval]
|
|
99
|
+
@http2_keepalive_timeout = http2_options[:keepalive_timeout]
|
|
91
100
|
|
|
92
101
|
@selector = NIO::Selector.new
|
|
93
102
|
@queue = Queue.new
|
|
@@ -98,6 +107,9 @@ module Raptor
|
|
|
98
107
|
@id_to_timeout = {}
|
|
99
108
|
@id_to_writer = {}
|
|
100
109
|
@id_to_flow_control = {}
|
|
110
|
+
@id_to_http2_last_stream = {}
|
|
111
|
+
@id_to_http2_drain_stream = {}
|
|
112
|
+
@id_to_http2_keepalive = {}
|
|
101
113
|
end
|
|
102
114
|
|
|
103
115
|
# Starts the reactor's main event loop in a new thread. Runs until
|
|
@@ -129,12 +141,7 @@ module Raptor
|
|
|
129
141
|
@timeouts.delete!(to_client)
|
|
130
142
|
id = to_client.client_data[:id]
|
|
131
143
|
@id_to_timeout.delete(id)
|
|
132
|
-
|
|
133
|
-
next unless socket
|
|
134
|
-
|
|
135
|
-
@selector.deregister(socket)
|
|
136
|
-
socket.write(TIMEOUT_RESPONSE) rescue nil
|
|
137
|
-
cleanup(socket)
|
|
144
|
+
handle_timeout(to_client, now)
|
|
138
145
|
end
|
|
139
146
|
|
|
140
147
|
until @queue.empty?
|
|
@@ -145,12 +152,16 @@ module Raptor
|
|
|
145
152
|
end
|
|
146
153
|
end
|
|
147
154
|
|
|
155
|
+
@id_to_flow_control.each_value(&:close)
|
|
148
156
|
@id_to_socket.each_value { |socket| socket.close rescue nil }
|
|
149
157
|
@id_to_socket.clear
|
|
150
158
|
@socket_to_state.clear
|
|
151
159
|
@id_to_timeout.clear
|
|
152
160
|
@id_to_writer.clear
|
|
153
161
|
@id_to_flow_control.clear
|
|
162
|
+
@id_to_http2_last_stream.clear
|
|
163
|
+
@id_to_http2_drain_stream.clear
|
|
164
|
+
@id_to_http2_keepalive.clear
|
|
154
165
|
@timeouts.clear!
|
|
155
166
|
@selector.close
|
|
156
167
|
end
|
|
@@ -270,6 +281,42 @@ module Raptor
|
|
|
270
281
|
@id_to_flow_control[id]
|
|
271
282
|
end
|
|
272
283
|
|
|
284
|
+
# Records an HTTP/2 stream before application dispatch, rejecting streams
|
|
285
|
+
# that arrived after graceful draining began.
|
|
286
|
+
#
|
|
287
|
+
# @param id [Integer] unique connection identifier
|
|
288
|
+
# @param stream_id [Integer] HTTP/2 stream identifier
|
|
289
|
+
# @return [Boolean] whether the stream may be dispatched
|
|
290
|
+
#
|
|
291
|
+
# @rbs (Integer id, Integer stream_id) -> bool
|
|
292
|
+
def dispatch_http2_stream(id, stream_id)
|
|
293
|
+
if (last_stream = @id_to_http2_drain_stream[id])
|
|
294
|
+
return stream_id <= last_stream
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
current = @id_to_http2_last_stream[id] || 0
|
|
298
|
+
@id_to_http2_last_stream[id] = stream_id if stream_id > current
|
|
299
|
+
true
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
# Sends GOAWAY on every HTTP/2 connection and fixes the last stream each
|
|
303
|
+
# connection may dispatch while existing application work drains.
|
|
304
|
+
#
|
|
305
|
+
# @yieldparam stream_id [Integer] last dispatched stream identifier
|
|
306
|
+
# @yieldreturn [String] serialized GOAWAY frame
|
|
307
|
+
# @return [void]
|
|
308
|
+
#
|
|
309
|
+
# @rbs () { (Integer stream_id) -> String } -> void
|
|
310
|
+
def drain_http2
|
|
311
|
+
@id_to_flow_control.each_key do |id|
|
|
312
|
+
last_stream = @id_to_http2_last_stream[id] || 0
|
|
313
|
+
@id_to_http2_drain_stream[id] = last_stream
|
|
314
|
+
writer = @id_to_writer[id]
|
|
315
|
+
socket = @id_to_socket[id]
|
|
316
|
+
writer.write_frames(socket, [yield(last_stream)]) if writer && socket
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
273
320
|
# Stores an HTTP/2 connection's socket, state, writer, and flow
|
|
274
321
|
# controller in the reactor's per-connection maps.
|
|
275
322
|
#
|
|
@@ -278,14 +325,34 @@ module Raptor
|
|
|
278
325
|
# @param state [Hash] initial connection state
|
|
279
326
|
# @param writer [Http2::Writer] per-connection frame writer
|
|
280
327
|
# @param flow_control [Http2::FlowControl] per-connection outbound flow controller
|
|
328
|
+
# @param ping_frame [String] serialized PING frame for keepalive probes
|
|
329
|
+
# @param ping_payload [String] payload expected in the corresponding acknowledgement
|
|
281
330
|
# @return [void]
|
|
282
331
|
#
|
|
283
|
-
# @rbs (id: Integer, socket: TCPSocket, state: Hash[Symbol, untyped], writer: untyped, flow_control: untyped) -> void
|
|
284
|
-
def attach_http2(id:, socket:, state:, writer:, flow_control:)
|
|
332
|
+
# @rbs (id: Integer, socket: TCPSocket, state: Hash[Symbol, untyped], writer: untyped, flow_control: untyped, ping_frame: String, ping_payload: String) -> void
|
|
333
|
+
def attach_http2(id:, socket:, state:, writer:, flow_control:, ping_frame:, ping_payload:)
|
|
285
334
|
@id_to_socket[id] = socket
|
|
286
335
|
@socket_to_state[socket] = state
|
|
287
336
|
@id_to_writer[id] = writer
|
|
288
337
|
@id_to_flow_control[id] = flow_control
|
|
338
|
+
@id_to_http2_last_stream[id] = 0
|
|
339
|
+
if @http2_keepalive_interval.positive?
|
|
340
|
+
@id_to_http2_keepalive[id] = {frame: ping_frame, payload: ping_payload}
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
# Records acknowledgements for server keepalive probes.
|
|
345
|
+
#
|
|
346
|
+
# @param id [Integer] unique connection identifier
|
|
347
|
+
# @param payloads [Array<String>, nil] acknowledged PING payloads
|
|
348
|
+
# @return [void]
|
|
349
|
+
#
|
|
350
|
+
# @rbs (Integer id, Array[String]? payloads) -> void
|
|
351
|
+
def acknowledge_http2_ping(id, payloads)
|
|
352
|
+
keepalive = @id_to_http2_keepalive[id]
|
|
353
|
+
return unless keepalive && payloads&.include?(keepalive[:payload])
|
|
354
|
+
|
|
355
|
+
keepalive.delete(:deadline)
|
|
289
356
|
end
|
|
290
357
|
|
|
291
358
|
# Registers an attached socket for future reactor-driven reads.
|
|
@@ -335,7 +402,10 @@ module Raptor
|
|
|
335
402
|
|
|
336
403
|
@socket_to_state.delete(socket)
|
|
337
404
|
@id_to_writer.delete(id)
|
|
338
|
-
@id_to_flow_control.delete(id)
|
|
405
|
+
@id_to_flow_control.delete(id)&.close
|
|
406
|
+
@id_to_http2_last_stream.delete(id)
|
|
407
|
+
@id_to_http2_drain_stream.delete(id)
|
|
408
|
+
@id_to_http2_keepalive.delete(id)
|
|
339
409
|
socket.close rescue nil
|
|
340
410
|
end
|
|
341
411
|
|
|
@@ -372,19 +442,65 @@ module Raptor
|
|
|
372
442
|
@selector.register(socket, :r).value = socket
|
|
373
443
|
|
|
374
444
|
state = @socket_to_state[socket]
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
445
|
+
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
446
|
+
timeout_at = if state[:protocol] == :http2
|
|
447
|
+
if state[:http2_preface_received]
|
|
448
|
+
keepalive = @id_to_http2_keepalive[state[:id]]
|
|
449
|
+
keepalive && (keepalive[:deadline] || now + @http2_keepalive_interval)
|
|
450
|
+
else
|
|
451
|
+
now + @first_data_timeout
|
|
452
|
+
end
|
|
453
|
+
elsif state[:persisted]
|
|
454
|
+
now + @persistent_data_timeout
|
|
378
455
|
elsif first_data_received?(state)
|
|
379
|
-
@chunk_data_timeout
|
|
456
|
+
now + @chunk_data_timeout
|
|
380
457
|
else
|
|
381
|
-
@first_data_timeout
|
|
458
|
+
now + @first_data_timeout
|
|
382
459
|
end
|
|
383
|
-
|
|
460
|
+
track_timeout(state, timeout_at) if timeout_at
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
# Adds a connection deadline to the timeout tree.
|
|
464
|
+
#
|
|
465
|
+
# @param state [Hash] client connection state
|
|
466
|
+
# @param timeout_at [Float] absolute monotonic expiry time
|
|
467
|
+
# @return [void]
|
|
468
|
+
#
|
|
469
|
+
# @rbs (Hash[Symbol, untyped] state, Float timeout_at) -> void
|
|
470
|
+
def track_timeout(state, timeout_at)
|
|
471
|
+
client = TimeoutClient.new(state)
|
|
472
|
+
client.timeout_at = timeout_at
|
|
384
473
|
@timeouts << client
|
|
385
474
|
@id_to_timeout[state[:id]] = client
|
|
386
475
|
end
|
|
387
476
|
|
|
477
|
+
# Handles an expired connection deadline, sending an HTTP/2 keepalive
|
|
478
|
+
# probe before closing the connection when its acknowledgement is late.
|
|
479
|
+
#
|
|
480
|
+
# @param client [TimeoutClient] expired client
|
|
481
|
+
# @param now [Float] current monotonic timestamp
|
|
482
|
+
# @return [void]
|
|
483
|
+
#
|
|
484
|
+
# @rbs (TimeoutClient client, Float now) -> void
|
|
485
|
+
def handle_timeout(client, now)
|
|
486
|
+
state = client.client_data
|
|
487
|
+
id = state[:id]
|
|
488
|
+
socket = @id_to_socket[id]
|
|
489
|
+
return unless socket
|
|
490
|
+
|
|
491
|
+
keepalive = @id_to_http2_keepalive[id] if state[:http2_preface_received]
|
|
492
|
+
if keepalive && !keepalive[:deadline]
|
|
493
|
+
keepalive[:deadline] = now + @http2_keepalive_timeout
|
|
494
|
+
@id_to_writer[id].write_frames(socket, [keepalive[:frame]])
|
|
495
|
+
track_timeout(state, keepalive[:deadline])
|
|
496
|
+
return
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
@selector.deregister(socket)
|
|
500
|
+
socket.write(TIMEOUT_RESPONSE) rescue nil unless state[:protocol] == :http2
|
|
501
|
+
cleanup(socket)
|
|
502
|
+
end
|
|
503
|
+
|
|
388
504
|
# Handles socket wakeup by deregistering and queuing for processing.
|
|
389
505
|
#
|
|
390
506
|
# @param socket [TCPSocket] the socket that became ready
|
|
@@ -395,7 +511,7 @@ module Raptor
|
|
|
395
511
|
@selector.deregister(socket)
|
|
396
512
|
state = @socket_to_state[socket]
|
|
397
513
|
to_client = @id_to_timeout.delete(state[:id])
|
|
398
|
-
@timeouts.delete!(to_client)
|
|
514
|
+
@timeouts.delete!(to_client) if to_client
|
|
399
515
|
read_and_queue_for_parse(socket, state)
|
|
400
516
|
end
|
|
401
517
|
|
|
@@ -441,7 +557,10 @@ module Raptor
|
|
|
441
557
|
state = @socket_to_state.delete(socket)
|
|
442
558
|
@id_to_socket.delete(state[:id])
|
|
443
559
|
@id_to_writer.delete(state[:id])
|
|
444
|
-
@id_to_flow_control.delete(state[:id])
|
|
560
|
+
@id_to_flow_control.delete(state[:id])&.close
|
|
561
|
+
@id_to_http2_last_stream.delete(state[:id])
|
|
562
|
+
@id_to_http2_drain_stream.delete(state[:id])
|
|
563
|
+
@id_to_http2_keepalive.delete(state[:id])
|
|
445
564
|
socket.close
|
|
446
565
|
end
|
|
447
566
|
|
data/lib/raptor/server.rb
CHANGED
|
@@ -182,6 +182,18 @@ module Raptor
|
|
|
182
182
|
return true
|
|
183
183
|
end
|
|
184
184
|
|
|
185
|
+
if listener.is_a?(Binder::H2cListener)
|
|
186
|
+
@http2.eager_accept(
|
|
187
|
+
tcp_client,
|
|
188
|
+
tcp_client.object_id,
|
|
189
|
+
@reactor,
|
|
190
|
+
@thread_pool,
|
|
191
|
+
remote_addr,
|
|
192
|
+
HTTP_SCHEME
|
|
193
|
+
)
|
|
194
|
+
return true
|
|
195
|
+
end
|
|
196
|
+
|
|
185
197
|
@http1.eager_accept(
|
|
186
198
|
tcp_client,
|
|
187
199
|
tcp_client.object_id,
|
data/lib/raptor/version.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Generated from lib/raptor/binder.rb with RBS::Inline
|
|
2
2
|
|
|
3
3
|
module Raptor
|
|
4
|
-
# Binds
|
|
5
|
-
# holds them for the server. Reconstructs listeners from inherited
|
|
6
|
-
# descriptors when provided (systemd socket activation, hot restart).
|
|
4
|
+
# Binds TCP, Unix, SSL, and cleartext HTTP/2 URIs to listening sockets
|
|
5
|
+
# and holds them for the server. Reconstructs listeners from inherited
|
|
6
|
+
# file descriptors when provided (systemd socket activation, hot restart).
|
|
7
7
|
class Binder
|
|
8
8
|
SOCKET_BACKLOG: ::Integer
|
|
9
9
|
|
|
@@ -27,9 +27,21 @@ module Raptor
|
|
|
27
27
|
def members: () -> [ :tcp_server, :ssl_context ]
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
# Marks a TCPServer as accepting cleartext HTTP/2 connections.
|
|
31
|
+
class H2cListener < Data
|
|
32
|
+
attr_reader tcp_server(): untyped
|
|
33
|
+
|
|
34
|
+
def self.new: (untyped tcp_server) -> instance
|
|
35
|
+
| (tcp_server: untyped) -> instance
|
|
36
|
+
|
|
37
|
+
def self.members: () -> [ :tcp_server ]
|
|
38
|
+
|
|
39
|
+
def members: () -> [ :tcp_server ]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
@uri_listeners: Hash[String, Array[TCPServer | UNIXServer | SslListener | H2cListener]]
|
|
31
43
|
|
|
32
|
-
@listeners: Array[TCPServer | UNIXServer | SslListener]
|
|
44
|
+
@listeners: Array[TCPServer | UNIXServer | SslListener | H2cListener]
|
|
33
45
|
|
|
34
46
|
@inherited_fds: Hash[String, Array[Integer]]
|
|
35
47
|
|
|
@@ -49,7 +61,7 @@ module Raptor
|
|
|
49
61
|
|
|
50
62
|
# Returns the array of listening sockets.
|
|
51
63
|
#
|
|
52
|
-
# @return [Array<TCPServer, UNIXServer, SslListener>]
|
|
64
|
+
# @return [Array<TCPServer, UNIXServer, SslListener, H2cListener>]
|
|
53
65
|
attr_reader listeners: untyped
|
|
54
66
|
|
|
55
67
|
# Creates a new Binder and binds each URI. `localhost` expands to both
|
|
@@ -66,7 +78,8 @@ module Raptor
|
|
|
66
78
|
def initialize: (Array[String] bind_uris, ?socket_backlog: Integer, ?inherited_fds: Hash[String, Array[Integer]]) -> void
|
|
67
79
|
|
|
68
80
|
# Returns the bound addresses as strings: TCP as `host:port`, Unix as
|
|
69
|
-
# the socket path, SSL as `ssl://host:port
|
|
81
|
+
# the socket path, SSL as `ssl://host:port`, and cleartext HTTP/2 as
|
|
82
|
+
# `h2c://host:port`.
|
|
70
83
|
#
|
|
71
84
|
# @return [Array<String>]
|
|
72
85
|
#
|
|
@@ -124,22 +137,22 @@ module Raptor
|
|
|
124
137
|
# Creates fresh listeners for the given URI.
|
|
125
138
|
#
|
|
126
139
|
# @param uri [URI] the parsed bind URI
|
|
127
|
-
# @return [Array<TCPServer, UNIXServer, SslListener>]
|
|
140
|
+
# @return [Array<TCPServer, UNIXServer, SslListener, H2cListener>]
|
|
128
141
|
# @raise [UnknownBindSchemeError] if the URI scheme is not supported
|
|
129
142
|
#
|
|
130
|
-
# @rbs (URI::Generic uri) -> Array[TCPServer | UNIXServer | SslListener]
|
|
131
|
-
def create_listeners: (URI::Generic uri) -> Array[TCPServer | UNIXServer | SslListener]
|
|
143
|
+
# @rbs (URI::Generic uri) -> Array[TCPServer | UNIXServer | SslListener | H2cListener]
|
|
144
|
+
def create_listeners: (URI::Generic uri) -> Array[TCPServer | UNIXServer | SslListener | H2cListener]
|
|
132
145
|
|
|
133
146
|
# Reconstructs listeners for the given URI from inherited file
|
|
134
147
|
# descriptors.
|
|
135
148
|
#
|
|
136
149
|
# @param uri [URI] the parsed bind URI the FDs were bound to
|
|
137
150
|
# @param filenos [Array<Integer>] file descriptors to wrap
|
|
138
|
-
# @return [Array<TCPServer, UNIXServer, SslListener>]
|
|
151
|
+
# @return [Array<TCPServer, UNIXServer, SslListener, H2cListener>]
|
|
139
152
|
# @raise [UnknownBindSchemeError] if the URI scheme is not supported
|
|
140
153
|
#
|
|
141
|
-
# @rbs (URI::Generic uri, Array[Integer] filenos) -> Array[TCPServer | UNIXServer | SslListener]
|
|
142
|
-
def restore_listeners: (URI::Generic uri, Array[Integer] filenos) -> Array[TCPServer | UNIXServer | SslListener]
|
|
154
|
+
# @rbs (URI::Generic uri, Array[Integer] filenos) -> Array[TCPServer | UNIXServer | SslListener | H2cListener]
|
|
155
|
+
def restore_listeners: (URI::Generic uri, Array[Integer] filenos) -> Array[TCPServer | UNIXServer | SslListener | H2cListener]
|
|
143
156
|
|
|
144
157
|
# Creates TCP server sockets for the given host and port.
|
|
145
158
|
#
|
|
@@ -61,6 +61,18 @@ module Raptor
|
|
|
61
61
|
# @rbs (Hash[String, untyped] env_template, Integer? max_body_size) -> ^(Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
|
|
62
62
|
def self.parser_worker: (Hash[String, untyped] env_template, Integer? max_body_size) -> ^(Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
|
|
63
63
|
|
|
64
|
+
# Calls every `rack.response_finished` callback in reverse
|
|
65
|
+
# registration order, rescuing any that raise.
|
|
66
|
+
#
|
|
67
|
+
# @param env [Hash, nil] the Rack environment
|
|
68
|
+
# @param status [Integer, nil] the response status code
|
|
69
|
+
# @param headers [Hash, nil] the response headers
|
|
70
|
+
# @param error [Exception, nil] any error raised during processing, or nil on success
|
|
71
|
+
# @return [void]
|
|
72
|
+
#
|
|
73
|
+
# @rbs (Hash[String, untyped]? env, Integer? status, Hash[String, String | Array[String]]? headers, Exception? error) -> void
|
|
74
|
+
def self.call_response_finished: (Hash[String, untyped]? env, Integer? status, Hash[String, String | Array[String]]? headers, Exception? error) -> void
|
|
75
|
+
|
|
64
76
|
# Writes a Common Log Format entry to `io`. Write failures are silently
|
|
65
77
|
# ignored.
|
|
66
78
|
#
|
|
@@ -580,18 +580,6 @@ module Raptor
|
|
|
580
580
|
# @rbs (TCPSocket socket, String response, untyped body, bool use_chunked) -> void
|
|
581
581
|
def write_enumerable_body: (TCPSocket socket, String response, untyped body, bool use_chunked) -> void
|
|
582
582
|
|
|
583
|
-
# Calls every `rack.response_finished` callback in reverse
|
|
584
|
-
# registration order, rescuing any that raise.
|
|
585
|
-
#
|
|
586
|
-
# @param env [Hash, nil] the Rack environment
|
|
587
|
-
# @param status [Integer, nil] the response status code
|
|
588
|
-
# @param headers [Hash, nil] the response headers
|
|
589
|
-
# @param error [Exception, nil] any error raised during processing, or nil on success
|
|
590
|
-
# @return [void]
|
|
591
|
-
#
|
|
592
|
-
# @rbs (Hash[String, untyped] env, Integer? status, Hash[String, String | Array[String]]? headers, Exception? error) -> void
|
|
593
|
-
def call_response_finished: (Hash[String, untyped] env, Integer? status, Hash[String, String | Array[String]]? headers, Exception? error) -> void
|
|
594
|
-
|
|
595
583
|
# Instance-level wrapper around {Http.write_access_log} that routes to
|
|
596
584
|
# the configured `@access_log_io`.
|
|
597
585
|
#
|