raptor 0.22.3 → 0.24.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 +46 -0
- data/Dockerfile +10 -2
- data/README.md +183 -61
- data/docs/assets/profile_picture.png +0 -0
- data/docs/assets/startup_output.svg +37 -0
- data/docs/raptor-vs-puma.md +104 -424
- data/docs/talk.md +1388 -0
- data/ext/raptor_bpf/reuseport_select.bpf.c +18 -9
- data/ext/raptor_http/extconf.rb +2 -0
- data/ext/raptor_http/raptor_http.c +165 -234
- data/ext/raptor_http2/raptor_http2.c +272 -223
- data/ext/raptor_native/raptor_native.c +38 -20
- data/lib/rackup/handler/raptor.rb +14 -12
- data/lib/raptor/binder.rb +12 -12
- data/lib/raptor/cli.rb +19 -18
- data/lib/raptor/cluster.rb +120 -74
- data/lib/raptor/control_server.rb +5 -2
- data/lib/raptor/detached_body.rb +6 -2
- data/lib/raptor/http.rb +7 -6
- data/lib/raptor/http1.rb +281 -234
- data/lib/raptor/http2.rb +356 -276
- data/lib/raptor/plugin.rb +98 -0
- data/lib/raptor/reactor.rb +138 -148
- data/lib/raptor/reuseport_bpf.rb +62 -38
- data/lib/raptor/server.rb +45 -34
- data/lib/raptor/stats.rb +15 -3
- data/lib/raptor/thread_locals.rb +4 -3
- data/lib/raptor/version.rb +1 -1
- data/sig/generated/rackup/handler/raptor.rbs +2 -1
- data/sig/generated/raptor/binder.rbs +9 -9
- data/sig/generated/raptor/cli.rbs +6 -6
- data/sig/generated/raptor/cluster.rbs +18 -5
- data/sig/generated/raptor/control_server.rbs +2 -1
- data/sig/generated/raptor/detached_body.rbs +5 -1
- data/sig/generated/raptor/http.rbs +3 -5
- data/sig/generated/raptor/http1.rbs +119 -102
- data/sig/generated/raptor/http2.rbs +204 -190
- data/sig/generated/raptor/plugin.rbs +52 -0
- data/sig/generated/raptor/reactor.rbs +107 -118
- data/sig/generated/raptor/reuseport_bpf.rbs +54 -17
- data/sig/generated/raptor/server.rbs +26 -26
- data/sig/generated/raptor/stats.rbs +3 -2
- data/sig/generated/raptor/thread_locals.rbs +4 -3
- metadata +6 -2
- data/docs/brisrails-talk.md +0 -2398
|
@@ -11,8 +11,6 @@ module Raptor
|
|
|
11
11
|
|
|
12
12
|
CONTENT_TYPE: ::String
|
|
13
13
|
|
|
14
|
-
HTTP_VERSION: ::String
|
|
15
|
-
|
|
16
14
|
REMOTE_ADDR: ::String
|
|
17
15
|
|
|
18
16
|
REQUEST_URI: ::String
|
|
@@ -73,13 +71,13 @@ module Raptor
|
|
|
73
71
|
# registration order, rescuing any that raise.
|
|
74
72
|
#
|
|
75
73
|
# @param env [Hash, nil] the Rack environment
|
|
76
|
-
# @param status [
|
|
74
|
+
# @param status [Object, nil] the status returned by the app, if any
|
|
77
75
|
# @param headers [Hash, nil] the response headers
|
|
78
76
|
# @param error [Exception, nil] any error raised during processing, or nil on success
|
|
79
77
|
# @return [void]
|
|
80
78
|
#
|
|
81
|
-
# @rbs (Hash[String, untyped]? env,
|
|
82
|
-
def self.call_response_finished: (Hash[String, untyped]? env,
|
|
79
|
+
# @rbs (Hash[String, untyped]? env, untyped status, Hash[String, String | Array[String]]? headers, Exception? error) -> void
|
|
80
|
+
def self.call_response_finished: (Hash[String, untyped]? env, untyped status, Hash[String, String | Array[String]]? headers, Exception? error) -> void
|
|
83
81
|
|
|
84
82
|
# Writes a Common Log Format entry to `io`. Write failures are silently
|
|
85
83
|
# ignored.
|
|
@@ -34,6 +34,10 @@ module Raptor
|
|
|
34
34
|
|
|
35
35
|
INTERNAL_SERVER_ERROR_RESPONSE: ::String
|
|
36
36
|
|
|
37
|
+
NOT_IMPLEMENTED_RESPONSE: ::String
|
|
38
|
+
|
|
39
|
+
CHUNKED_TERMINATOR: ::String
|
|
40
|
+
|
|
37
41
|
CONNECTION_CLOSE: ::String
|
|
38
42
|
|
|
39
43
|
CONNECTION_KEEPALIVE: ::String
|
|
@@ -42,14 +46,18 @@ module Raptor
|
|
|
42
46
|
|
|
43
47
|
TRANSFER_ENCODING_CHUNKED: ::String
|
|
44
48
|
|
|
45
|
-
CHUNKED_TERMINATOR: ::String
|
|
46
|
-
|
|
47
49
|
HTTP_CONNECTION: ::String
|
|
48
50
|
|
|
49
51
|
HTTP_EXPECT: ::String
|
|
50
52
|
|
|
51
53
|
HTTP_TRANSFER_ENCODING: ::String
|
|
52
54
|
|
|
55
|
+
HTTP_X_FORWARDED_PROTO: ::String
|
|
56
|
+
|
|
57
|
+
HTTP_X_FORWARDED_SCHEME: ::String
|
|
58
|
+
|
|
59
|
+
HTTP_X_FORWARDED_SSL: ::String
|
|
60
|
+
|
|
53
61
|
RACK_HEADER_PREFIX: ::String
|
|
54
62
|
|
|
55
63
|
RACK_HIJACKED: ::String
|
|
@@ -66,17 +74,23 @@ module Raptor
|
|
|
66
74
|
# @rbs (Hash[String, untyped] env) -> bool
|
|
67
75
|
def self.invalid_host?: (Hash[String, untyped] env) -> bool
|
|
68
76
|
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
# missing, not the final encoding, or duplicated; a `Transfer-Encoding`
|
|
72
|
-
# paired with a `Content-Length`; or a `Content-Length` containing any
|
|
73
|
-
# non-digit character.
|
|
77
|
+
# Rejects ambiguous message framing per RFC 9112 section 6.3 and
|
|
78
|
+
# transfer codings other than a single `chunked`.
|
|
74
79
|
#
|
|
75
80
|
# @param env [Hash] the Rack environment after header parsing
|
|
76
|
-
# @return [
|
|
81
|
+
# @return [Symbol, nil] `:malformed`, `:unsupported_encoding`, or nil
|
|
77
82
|
#
|
|
78
|
-
# @rbs (Hash[String, untyped] env) ->
|
|
79
|
-
def self.
|
|
83
|
+
# @rbs (Hash[String, untyped] env) -> Symbol?
|
|
84
|
+
def self.framing_error: (Hash[String, untyped] env) -> Symbol?
|
|
85
|
+
|
|
86
|
+
# Returns any pipelined bytes following the request, or nil if none remain.
|
|
87
|
+
#
|
|
88
|
+
# @param buffer [String] the raw request bytes
|
|
89
|
+
# @param offset [Integer] the byte offset where the request ends
|
|
90
|
+
# @return [String, nil]
|
|
91
|
+
#
|
|
92
|
+
# @rbs (String buffer, Integer offset) -> String?
|
|
93
|
+
def self.pipelined_bytes: (String buffer, Integer offset) -> String?
|
|
80
94
|
|
|
81
95
|
# Encodes one HTTP/1.1 response chunk.
|
|
82
96
|
#
|
|
@@ -96,9 +110,10 @@ module Raptor
|
|
|
96
110
|
|
|
97
111
|
# Advances an HTTP/1.x request parse from the state hash's buffered
|
|
98
112
|
# bytes. A complete well-formed request returns with `:complete` set
|
|
99
|
-
# plus populated `:env` and `:body
|
|
100
|
-
#
|
|
101
|
-
#
|
|
113
|
+
# plus populated `:env` and `:body`, and records any bytes after it in
|
|
114
|
+
# the parse data's `:pipelined`. Rejected input sets `:malformed`,
|
|
115
|
+
# `:too_large`, or `:unsupported_encoding`; incomplete input returns
|
|
116
|
+
# the state so the reactor can wait for more.
|
|
102
117
|
#
|
|
103
118
|
# @param data [Hash] the current parse state
|
|
104
119
|
# @param env_template [Hash] the Rack env template to seed the request with
|
|
@@ -110,8 +125,6 @@ module Raptor
|
|
|
110
125
|
|
|
111
126
|
@app: ^(Hash[String, untyped]) -> [ Integer, Hash[String, String | Array[String]], untyped ]
|
|
112
127
|
|
|
113
|
-
@server_port: Integer
|
|
114
|
-
|
|
115
128
|
@server_port_string: String
|
|
116
129
|
|
|
117
130
|
@write_timeout: Integer
|
|
@@ -128,7 +141,7 @@ module Raptor
|
|
|
128
141
|
|
|
129
142
|
@clean_fiber_locals: bool
|
|
130
143
|
|
|
131
|
-
@on_error: ^(Hash[String, untyped]?, Exception) -> void
|
|
144
|
+
@on_error: (^(Hash[String, untyped]?, Exception) -> void)?
|
|
132
145
|
|
|
133
146
|
@running: AtomicBoolean
|
|
134
147
|
|
|
@@ -150,39 +163,16 @@ module Raptor
|
|
|
150
163
|
# @param on_error [#call, nil] callback invoked with (env, exception) when the Rack app raises
|
|
151
164
|
# @return [void]
|
|
152
165
|
#
|
|
153
|
-
# @rbs (^(Hash[String, untyped]) -> [Integer, Hash[String, String | Array[String]], untyped] app, Integer server_port, ?connection_options: Hash[Symbol, untyped], ?http1_options: Hash[Symbol, untyped], ?access_log_io: IO?, ?clean_thread_locals: bool, ?clean_fiber_locals: bool, ?on_error: ^(Hash[String, untyped]?, Exception) -> void
|
|
154
|
-
def initialize: (^(Hash[String, untyped]) -> [ Integer, Hash[String, String | Array[String]], untyped ] app, Integer server_port, ?connection_options: Hash[Symbol, untyped], ?http1_options: Hash[Symbol, untyped], ?access_log_io: IO?, ?clean_thread_locals: bool, ?clean_fiber_locals: bool, ?on_error: ^(Hash[String, untyped]?, Exception) -> void
|
|
166
|
+
# @rbs (^(Hash[String, untyped]) -> [Integer, Hash[String, String | Array[String]], untyped] app, Integer server_port, ?connection_options: Hash[Symbol, untyped], ?http1_options: Hash[Symbol, untyped], ?access_log_io: IO?, ?clean_thread_locals: bool, ?clean_fiber_locals: bool, ?on_error: (^(Hash[String, untyped]?, Exception) -> void)?) -> void
|
|
167
|
+
def initialize: (^(Hash[String, untyped]) -> [ Integer, Hash[String, String | Array[String]], untyped ] app, Integer server_port, ?connection_options: Hash[Symbol, untyped], ?http1_options: Hash[Symbol, untyped], ?access_log_io: IO?, ?clean_thread_locals: bool, ?clean_fiber_locals: bool, ?on_error: (^(Hash[String, untyped]?, Exception) -> void)?) -> void
|
|
155
168
|
|
|
156
|
-
#
|
|
157
|
-
# handler's env template and body-size limit into the worker proc.
|
|
169
|
+
# Returns a Ractor-safe proc that parses HTTP/1.x requests.
|
|
158
170
|
#
|
|
159
171
|
# @return [Proc]
|
|
160
172
|
#
|
|
161
173
|
# @rbs () -> ^(Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
|
|
162
174
|
def parser_worker: () -> ^(Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
|
|
163
175
|
|
|
164
|
-
# Instance-level wrapper around {Http.socket_write} that applies the
|
|
165
|
-
# configured `write_timeout`.
|
|
166
|
-
#
|
|
167
|
-
# @param socket [TCPSocket] the socket to write to
|
|
168
|
-
# @param string [String] the data to write
|
|
169
|
-
# @return [void]
|
|
170
|
-
# @raise [Http::WriteError] if the socket is not writable within the timeout or raises IOError
|
|
171
|
-
#
|
|
172
|
-
# @rbs (TCPSocket socket, String string) -> void
|
|
173
|
-
def socket_write: (TCPSocket socket, String string) -> void
|
|
174
|
-
|
|
175
|
-
# Instance-level wrapper around {Http.socket_writev} that applies the
|
|
176
|
-
# configured `write_timeout`.
|
|
177
|
-
#
|
|
178
|
-
# @param socket [TCPSocket] the socket to write to
|
|
179
|
-
# @param strings [Array<String>] the buffers to write in order
|
|
180
|
-
# @return [void]
|
|
181
|
-
# @raise [Http::WriteError] if the socket is not writable within the timeout or raises IOError
|
|
182
|
-
#
|
|
183
|
-
# @rbs (TCPSocket socket, Array[String] strings) -> void
|
|
184
|
-
def socket_writev: (TCPSocket socket, Array[String] strings) -> void
|
|
185
|
-
|
|
186
176
|
# Signals eager keep-alive loops to stop processing further requests on
|
|
187
177
|
# their connections. In-flight requests complete normally.
|
|
188
178
|
#
|
|
@@ -196,10 +186,10 @@ module Raptor
|
|
|
196
186
|
# when complete. Falls back to the reactor when more data is needed.
|
|
197
187
|
#
|
|
198
188
|
# @param socket [TCPSocket] the freshly accepted client socket
|
|
199
|
-
# @param id [Integer] unique
|
|
189
|
+
# @param id [Integer] unique connection identifier
|
|
200
190
|
# @param reactor [Reactor] the reactor for fallback registration
|
|
201
191
|
# @param thread_pool [AtomicThreadPool] thread pool for application processing
|
|
202
|
-
# @param remote_addr [String] client IP address
|
|
192
|
+
# @param remote_addr [String] the client IP address
|
|
203
193
|
# @param url_scheme [String] "http" or "https"
|
|
204
194
|
# @return [void]
|
|
205
195
|
#
|
|
@@ -217,46 +207,61 @@ module Raptor
|
|
|
217
207
|
# @rbs (Hash[Symbol, untyped] parsed_request, Reactor reactor, AtomicThreadPool thread_pool) -> void
|
|
218
208
|
def handle_parsed_request: (Hash[Symbol, untyped] parsed_request, Reactor reactor, AtomicThreadPool thread_pool) -> void
|
|
219
209
|
|
|
210
|
+
# Processes kept-alive requests on application threads, yielding to queued
|
|
211
|
+
# work and returning idle or incomplete connections to the reactor.
|
|
212
|
+
#
|
|
213
|
+
# @param socket [TCPSocket] the client socket
|
|
214
|
+
# @param id [Integer] unique connection identifier
|
|
215
|
+
# @param reactor [Reactor] the reactor for fallback registration
|
|
216
|
+
# @param thread_pool [AtomicThreadPool] thread pool for application processing
|
|
217
|
+
# @param request_count [Integer] number of requests handled on this connection
|
|
218
|
+
# @param remote_addr [String] the client IP address
|
|
219
|
+
# @param url_scheme [String] "http" or "https"
|
|
220
|
+
# @param resumed [Boolean] whether the reactor queued the connection once its next request became readable
|
|
221
|
+
# @param pipelined [String, nil] bytes the client sent after the previous request
|
|
222
|
+
# @return [void]
|
|
223
|
+
#
|
|
224
|
+
# @rbs (TCPSocket socket, Integer id, Reactor reactor, AtomicThreadPool thread_pool, Integer request_count, String remote_addr, String url_scheme, ?resumed: bool, ?pipelined: String?) -> void
|
|
225
|
+
def eager_keepalive: (TCPSocket socket, Integer id, Reactor reactor, AtomicThreadPool thread_pool, Integer request_count, String remote_addr, String url_scheme, ?resumed: bool, ?pipelined: String?) -> void
|
|
226
|
+
|
|
220
227
|
private
|
|
221
228
|
|
|
222
229
|
# Reads pending bytes off `socket` into the thread-local read buffer,
|
|
223
230
|
# draining any additional SSL-buffered bytes so `pending` is empty on
|
|
224
|
-
# return.
|
|
225
|
-
# underlying `read_nonblock` does.
|
|
231
|
+
# return.
|
|
226
232
|
#
|
|
227
233
|
# @param socket [TCPSocket] the socket to read from
|
|
228
234
|
# @return [String] the thread-local buffer, freshly populated
|
|
235
|
+
# @raise [IO::WaitReadable] if no bytes are ready to read
|
|
236
|
+
# @raise [EOFError, IOError, SystemCallError] if the connection is closed or fails
|
|
229
237
|
#
|
|
230
238
|
# @rbs (TCPSocket socket) -> String
|
|
231
239
|
def read_into_thread_buffer: (TCPSocket socket) -> String
|
|
232
240
|
|
|
233
|
-
# Runs a fresh HTTP/1.x parse against `buffer
|
|
234
|
-
# `[env, parse_data, nread, parser]`. Raises `HttpParserError` on
|
|
235
|
-
# malformed input.
|
|
241
|
+
# Runs a fresh HTTP/1.x parse against `buffer`.
|
|
236
242
|
#
|
|
237
243
|
# @param buffer [String] the raw request bytes
|
|
238
|
-
# @return [Array(Hash, Hash, Integer, HttpParser)]
|
|
244
|
+
# @return [Array(Hash, Hash, Integer, HttpParser)] the env, parse data, bytes read, and parser
|
|
245
|
+
# @raise [HttpParserError] if the request is malformed
|
|
239
246
|
#
|
|
240
247
|
# @rbs (String buffer) -> [Hash[String, untyped], Hash[Symbol, untyped], Integer, HttpParser]
|
|
241
248
|
def parse_next_request: (String buffer) -> [ Hash[String, untyped], Hash[Symbol, untyped], Integer, HttpParser ]
|
|
242
249
|
|
|
243
|
-
#
|
|
244
|
-
# `String` (or `nil` when the request has no body), or one of
|
|
245
|
-
# `:incomplete`, `:too_large`, `:malformed` when the caller must
|
|
246
|
-
# fall back or reject.
|
|
250
|
+
# Validates request framing and extracts the body, preserving pipelined bytes.
|
|
247
251
|
#
|
|
248
252
|
# @param buffer [String] the raw request bytes
|
|
249
253
|
# @param env [Hash] the Rack environment being built
|
|
254
|
+
# @param parse_data [Hash] metadata from the parsing pass
|
|
250
255
|
# @param parser [HttpParser] the parser holding the finished parse state
|
|
251
256
|
# @param nread [Integer] the byte offset where the body begins in `buffer`
|
|
252
|
-
# @
|
|
253
|
-
#
|
|
257
|
+
# @return [String, nil, Symbol] body, nil when absent, or `:incomplete`,
|
|
258
|
+
# `:too_large`, `:malformed`, or `:unsupported_encoding`
|
|
254
259
|
#
|
|
255
|
-
# @rbs (String buffer, Hash[String, untyped] env, HttpParser parser, Integer nread
|
|
256
|
-
def extract_body: (String buffer, Hash[String, untyped] env, HttpParser parser, Integer nread
|
|
260
|
+
# @rbs (String buffer, Hash[String, untyped] env, Hash[Symbol, untyped] parse_data, HttpParser parser, Integer nread) -> (String | Symbol)?
|
|
261
|
+
def extract_body: (String buffer, Hash[String, untyped] env, Hash[Symbol, untyped] parse_data, HttpParser parser, Integer nread) -> (String | Symbol)?
|
|
257
262
|
|
|
258
|
-
# Returns true
|
|
259
|
-
# RFC
|
|
263
|
+
# Returns true when the request expects a 100 Continue response per
|
|
264
|
+
# RFC 9110 section 10.1.1.
|
|
260
265
|
#
|
|
261
266
|
# @param env [Hash] the parsed Rack environment (possibly incomplete)
|
|
262
267
|
# @return [Boolean]
|
|
@@ -279,32 +284,32 @@ module Raptor
|
|
|
279
284
|
# if keep-alive, eagerly reading subsequent requests inline.
|
|
280
285
|
#
|
|
281
286
|
# @param socket [TCPSocket] the client socket
|
|
282
|
-
# @param id [Integer] unique
|
|
287
|
+
# @param id [Integer] unique connection identifier
|
|
283
288
|
# @param env [Hash] partial env hash from the HTTP parser
|
|
284
289
|
# @param parse_data [Hash] metadata from the parsing pass
|
|
285
290
|
# @param body [String, nil] decoded request body
|
|
286
291
|
# @param reactor [Reactor] the reactor managing the client connection
|
|
287
292
|
# @param thread_pool [AtomicThreadPool] thread pool for application processing
|
|
288
293
|
# @param request_count [Integer] number of requests handled on this connection
|
|
289
|
-
# @param remote_addr [String] client IP address
|
|
294
|
+
# @param remote_addr [String] the client IP address
|
|
290
295
|
# @param url_scheme [String] "http" or "https"
|
|
291
296
|
# @return [void]
|
|
292
297
|
#
|
|
293
298
|
# @rbs (TCPSocket socket, Integer id, Hash[String, untyped] env, Hash[Symbol, untyped] parse_data, String? body, Reactor reactor, AtomicThreadPool thread_pool, Integer request_count, String remote_addr, String url_scheme) -> void
|
|
294
299
|
def process_client: (TCPSocket socket, Integer id, Hash[String, untyped] env, Hash[Symbol, untyped] parse_data, String? body, Reactor reactor, AtomicThreadPool thread_pool, Integer request_count, String remote_addr, String url_scheme) -> void
|
|
295
300
|
|
|
296
|
-
# Processes a single request
|
|
297
|
-
#
|
|
298
|
-
#
|
|
301
|
+
# Processes a single request, isolating fiber and thread locals as
|
|
302
|
+
# configured, and returns whether the connection stays open for another
|
|
303
|
+
# request.
|
|
299
304
|
#
|
|
300
305
|
# @param socket [TCPSocket] the client socket
|
|
301
|
-
# @param id [Integer] unique
|
|
306
|
+
# @param id [Integer] unique connection identifier
|
|
302
307
|
# @param env [Hash] partial env hash from the HTTP parser
|
|
303
308
|
# @param parse_data [Hash] metadata from the parsing pass
|
|
304
309
|
# @param body [String, nil] decoded request body
|
|
305
310
|
# @param reactor [Reactor] the reactor managing the client connection
|
|
306
311
|
# @param request_count [Integer] number of requests handled on this connection
|
|
307
|
-
# @param remote_addr [String] client IP address
|
|
312
|
+
# @param remote_addr [String] the client IP address
|
|
308
313
|
# @param url_scheme [String] "http" or "https"
|
|
309
314
|
# @return [Boolean] true if the connection should be kept alive
|
|
310
315
|
#
|
|
@@ -314,13 +319,13 @@ module Raptor
|
|
|
314
319
|
# Calls the Rack app and writes its response for one request.
|
|
315
320
|
#
|
|
316
321
|
# @param socket [TCPSocket] the client socket
|
|
317
|
-
# @param id [Integer] unique
|
|
322
|
+
# @param id [Integer] unique connection identifier
|
|
318
323
|
# @param env [Hash] partial env hash from the HTTP parser
|
|
319
324
|
# @param parse_data [Hash] metadata from the parsing pass
|
|
320
325
|
# @param body [String, nil] decoded request body
|
|
321
326
|
# @param reactor [Reactor] the reactor managing the client connection
|
|
322
327
|
# @param request_count [Integer] number of requests handled on this connection
|
|
323
|
-
# @param remote_addr [String] client IP address
|
|
328
|
+
# @param remote_addr [String] the client IP address
|
|
324
329
|
# @param url_scheme [String] "http" or "https"
|
|
325
330
|
# @return [Boolean] true if the connection should be kept alive
|
|
326
331
|
#
|
|
@@ -334,50 +339,33 @@ module Raptor
|
|
|
334
339
|
#
|
|
335
340
|
# @param socket [TCPSocket] the client socket
|
|
336
341
|
# @param rack_env [Hash, nil] the Rack environment, if it was built
|
|
337
|
-
# @param status [
|
|
342
|
+
# @param status [Object, nil] the status returned by the app, if any
|
|
338
343
|
# @param headers [Hash, nil] the headers returned by the app, if any
|
|
339
344
|
# @param error [Exception] the exception raised
|
|
340
345
|
# @param response_started [Boolean] whether any response bytes have been written
|
|
341
346
|
# @param hijacked [Boolean] whether the app took over the socket
|
|
342
347
|
# @return [void]
|
|
343
348
|
#
|
|
344
|
-
# @rbs (TCPSocket socket, Hash[String, untyped]? rack_env,
|
|
345
|
-
def handle_app_error: (TCPSocket socket, Hash[String, untyped]? rack_env,
|
|
346
|
-
|
|
347
|
-
# Reads and processes subsequent requests inline on a kept-alive
|
|
348
|
-
# connection. Returns the connection to the reactor when no data is ready
|
|
349
|
-
# or a request is incomplete, and queues complete requests behind work
|
|
350
|
-
# that is already waiting.
|
|
351
|
-
#
|
|
352
|
-
# @param socket [TCPSocket] the client socket
|
|
353
|
-
# @param id [Integer] unique client identifier
|
|
354
|
-
# @param reactor [Reactor] the reactor for fallback registration
|
|
355
|
-
# @param thread_pool [AtomicThreadPool] thread pool for deprioritization
|
|
356
|
-
# @param request_count [Integer] number of requests handled on this connection
|
|
357
|
-
# @param remote_addr [String] client IP address
|
|
358
|
-
# @param url_scheme [String] "http" or "https"
|
|
359
|
-
# @return [void]
|
|
360
|
-
#
|
|
361
|
-
# @rbs (TCPSocket socket, Integer id, Reactor reactor, AtomicThreadPool thread_pool, Integer request_count, String remote_addr, String url_scheme) -> void
|
|
362
|
-
def eager_keepalive: (TCPSocket socket, Integer id, Reactor reactor, AtomicThreadPool thread_pool, Integer request_count, String remote_addr, String url_scheme) -> void
|
|
349
|
+
# @rbs (TCPSocket socket, Hash[String, untyped]? rack_env, untyped status, Hash[String, String | Array[String]]? headers, Exception error, response_started: bool, hijacked: bool) -> void
|
|
350
|
+
def handle_app_error: (TCPSocket socket, Hash[String, untyped]? rack_env, untyped status, Hash[String, String | Array[String]]? headers, Exception error, response_started: bool, hijacked: bool) -> void
|
|
363
351
|
|
|
364
352
|
# Re-registers a socket with the reactor for further processing when
|
|
365
353
|
# an incomplete request is received on the fast path.
|
|
366
354
|
#
|
|
367
355
|
# @param socket [TCPSocket] the client socket
|
|
368
|
-
# @param id [Integer] unique
|
|
356
|
+
# @param id [Integer] unique connection identifier
|
|
369
357
|
# @param buffer [String] the partial request data already read
|
|
370
358
|
# @param env [Hash] partial env hash from the HTTP parser
|
|
371
359
|
# @param parse_data [Hash] metadata from the parsing pass
|
|
372
360
|
# @param reactor [Reactor] the reactor to re-register with
|
|
373
361
|
# @param request_count [Integer] number of requests handled on this connection
|
|
374
|
-
# @param remote_addr [String] client IP address
|
|
362
|
+
# @param remote_addr [String] the client IP address
|
|
375
363
|
# @param url_scheme [String] "http" or "https"
|
|
376
364
|
# @param persisted [Boolean] whether the connection has already completed at least one request
|
|
377
365
|
# @return [void]
|
|
378
366
|
#
|
|
379
|
-
# @rbs (TCPSocket socket, Integer id, String buffer, Hash[String, untyped] env, Hash[Symbol, untyped] parse_data, Reactor reactor, Integer request_count, String remote_addr, String url_scheme, persisted: bool) -> void
|
|
380
|
-
def fallback_to_reactor: (TCPSocket socket, Integer id, String buffer, Hash[String, untyped] env, Hash[Symbol, untyped] parse_data, Reactor reactor, Integer request_count, String remote_addr, String url_scheme, persisted: bool) -> void
|
|
367
|
+
# @rbs (TCPSocket socket, Integer id, String buffer, Hash[String, untyped] env, Hash[Symbol, untyped] parse_data, Reactor reactor, Integer request_count, String remote_addr, String url_scheme, ?persisted: bool) -> void
|
|
368
|
+
def fallback_to_reactor: (TCPSocket socket, Integer id, String buffer, Hash[String, untyped] env, Hash[Symbol, untyped] parse_data, Reactor reactor, Integer request_count, String remote_addr, String url_scheme, ?persisted: bool) -> void
|
|
381
369
|
|
|
382
370
|
# Writes a 413 response and closes the socket.
|
|
383
371
|
#
|
|
@@ -395,13 +383,21 @@ module Raptor
|
|
|
395
383
|
# @rbs (TCPSocket socket) -> void
|
|
396
384
|
def reject_malformed: (TCPSocket socket) -> void
|
|
397
385
|
|
|
386
|
+
# Writes a 501 response and closes the socket.
|
|
387
|
+
#
|
|
388
|
+
# @param socket [TCPSocket] the client socket
|
|
389
|
+
# @return [void]
|
|
390
|
+
#
|
|
391
|
+
# @rbs (TCPSocket socket) -> void
|
|
392
|
+
def reject_unsupported_encoding: (TCPSocket socket) -> void
|
|
393
|
+
|
|
398
394
|
# Builds a Rack environment hash from parsed HTTP request data.
|
|
399
395
|
#
|
|
400
396
|
# @param env [Hash] partial env hash from the HTTP parser
|
|
401
397
|
# @param parse_data [Hash] metadata from the parsing pass, including content_length
|
|
402
398
|
# @param body [String, nil] decoded request body, or nil if no body
|
|
403
399
|
# @param socket [TCPSocket] the client socket, used for hijack support
|
|
404
|
-
# @param remote_addr [String] client IP address
|
|
400
|
+
# @param remote_addr [String] the client IP address
|
|
405
401
|
# @param url_scheme [String] "http" or "https"
|
|
406
402
|
# @return [Hash] fully populated Rack environment hash
|
|
407
403
|
#
|
|
@@ -410,7 +406,8 @@ module Raptor
|
|
|
410
406
|
|
|
411
407
|
# Builds the `rack.input` IO object for the request body. Returns an
|
|
412
408
|
# in-memory StringIO for bodies up to the spool threshold, or a Tempfile
|
|
413
|
-
# for larger bodies
|
|
409
|
+
# for larger bodies. The complete body is already buffered at this point,
|
|
410
|
+
# so spooling does not bound peak receive memory.
|
|
414
411
|
#
|
|
415
412
|
# @param body [String, nil] decoded request body
|
|
416
413
|
# @return [IO] an IO-like object positioned at the start of the body
|
|
@@ -481,10 +478,10 @@ module Raptor
|
|
|
481
478
|
# @raise [TypeError] if status is not an Integer
|
|
482
479
|
# @raise [ArgumentError] if status is less than 100
|
|
483
480
|
#
|
|
484
|
-
# @rbs (
|
|
485
|
-
def validate_status: (
|
|
481
|
+
# @rbs (untyped status) -> void
|
|
482
|
+
def validate_status: (untyped status) -> void
|
|
486
483
|
|
|
487
|
-
# Returns a
|
|
484
|
+
# Returns a normalized copy of the response headers with lowercased
|
|
488
485
|
# keys and illegal/`rack.*`/`status` entries dropped.
|
|
489
486
|
#
|
|
490
487
|
# @param headers [Hash] raw headers from the Rack application
|
|
@@ -515,8 +512,8 @@ module Raptor
|
|
|
515
512
|
# @rbs (String http_version, Integer status) -> String
|
|
516
513
|
def build_status_line: (String http_version, Integer status) -> String
|
|
517
514
|
|
|
518
|
-
# Writes the response headers
|
|
519
|
-
#
|
|
515
|
+
# Writes the response headers and hands the raw socket to the hijack
|
|
516
|
+
# callback.
|
|
520
517
|
#
|
|
521
518
|
# @param socket [TCPSocket] the client socket
|
|
522
519
|
# @param response [String] the status line accumulated so far
|
|
@@ -550,6 +547,7 @@ module Raptor
|
|
|
550
547
|
# @param body [Object] the response body
|
|
551
548
|
# @param http_version [String] "HTTP/1.1" or "HTTP/1.0"
|
|
552
549
|
# @return [void]
|
|
550
|
+
# @raise [TypeError] if the body responds to none of `each`, `to_ary`, or `to_path`
|
|
553
551
|
#
|
|
554
552
|
# @rbs (TCPSocket socket, String response, Hash[String, String | Array[String]] headers, untyped body, String http_version) -> void
|
|
555
553
|
def write_full_response: (TCPSocket socket, String response, Hash[String, String | Array[String]] headers, untyped body, String http_version) -> void
|
|
@@ -622,8 +620,27 @@ module Raptor
|
|
|
622
620
|
# @rbs (TCPSocket socket, String response, untyped body, bool use_chunked) -> void
|
|
623
621
|
def write_enumerable_body: (TCPSocket socket, String response, untyped body, bool use_chunked) -> void
|
|
624
622
|
|
|
625
|
-
#
|
|
626
|
-
#
|
|
623
|
+
# Writes response bytes within the configured write timeout.
|
|
624
|
+
#
|
|
625
|
+
# @param socket [TCPSocket] the socket to write to
|
|
626
|
+
# @param string [String] the data to write
|
|
627
|
+
# @return [void]
|
|
628
|
+
# @raise [Http::WriteError] if the socket is not writable within the timeout or raises IOError
|
|
629
|
+
#
|
|
630
|
+
# @rbs (TCPSocket socket, String string) -> void
|
|
631
|
+
def socket_write: (TCPSocket socket, String string) -> void
|
|
632
|
+
|
|
633
|
+
# Writes response buffers in order within the configured write timeout.
|
|
634
|
+
#
|
|
635
|
+
# @param socket [TCPSocket] the socket to write to
|
|
636
|
+
# @param strings [Array<String>] the buffers to write in order
|
|
637
|
+
# @return [void]
|
|
638
|
+
# @raise [Http::WriteError] if the socket is not writable within the timeout or raises IOError
|
|
639
|
+
#
|
|
640
|
+
# @rbs (TCPSocket socket, Array[String] strings) -> void
|
|
641
|
+
def socket_writev: (TCPSocket socket, Array[String] strings) -> void
|
|
642
|
+
|
|
643
|
+
# Writes a completed request to the access log.
|
|
627
644
|
#
|
|
628
645
|
# @param env [Hash] the Rack environment
|
|
629
646
|
# @param status [Integer] the response status code
|