puma 3.12.6 → 6.2.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +1775 -451
- data/LICENSE +23 -20
- data/README.md +193 -65
- data/bin/puma-wild +3 -9
- data/docs/architecture.md +59 -21
- data/docs/compile_options.md +55 -0
- data/docs/deployment.md +69 -58
- data/docs/fork_worker.md +31 -0
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -0
- data/docs/jungle/README.md +9 -0
- data/{tools → docs}/jungle/rc.d/README.md +1 -1
- data/{tools → docs}/jungle/rc.d/puma +2 -2
- data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +66 -0
- data/docs/nginx.md +2 -2
- data/docs/plugins.md +22 -12
- data/docs/rails_dev_mode.md +28 -0
- data/docs/restart.md +47 -22
- data/docs/signals.md +13 -11
- data/docs/stats.md +142 -0
- data/docs/systemd.md +94 -120
- data/docs/testing_benchmarks_local_files.md +150 -0
- data/docs/testing_test_rackup_ci_files.md +36 -0
- data/ext/puma_http11/PumaHttp11Service.java +2 -2
- data/ext/puma_http11/ext_help.h +1 -1
- data/ext/puma_http11/extconf.rb +61 -3
- data/ext/puma_http11/http11_parser.c +103 -117
- data/ext/puma_http11/http11_parser.h +2 -2
- data/ext/puma_http11/http11_parser.java.rl +22 -38
- data/ext/puma_http11/http11_parser.rl +3 -3
- data/ext/puma_http11/http11_parser_common.rl +6 -6
- data/ext/puma_http11/mini_ssl.c +361 -99
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +108 -116
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +84 -99
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +248 -92
- data/ext/puma_http11/puma_http11.c +49 -57
- data/lib/puma/app/status.rb +71 -49
- data/lib/puma/binder.rb +242 -150
- data/lib/puma/cli.rb +38 -34
- data/lib/puma/client.rb +387 -244
- data/lib/puma/cluster/worker.rb +180 -0
- data/lib/puma/cluster/worker_handle.rb +97 -0
- data/lib/puma/cluster.rb +261 -243
- data/lib/puma/commonlogger.rb +21 -14
- data/lib/puma/configuration.rb +116 -88
- data/lib/puma/const.rb +101 -100
- data/lib/puma/control_cli.rb +115 -70
- data/lib/puma/detect.rb +33 -2
- data/lib/puma/dsl.rb +731 -134
- data/lib/puma/error_logger.rb +113 -0
- data/lib/puma/events.rb +16 -112
- data/lib/puma/io_buffer.rb +42 -5
- data/lib/puma/jruby_restart.rb +2 -59
- data/lib/puma/json_serialization.rb +96 -0
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +184 -133
- data/lib/puma/log_writer.rb +147 -0
- data/lib/puma/minissl/context_builder.rb +92 -0
- data/lib/puma/minissl.rb +246 -70
- data/lib/puma/null_io.rb +18 -1
- data/lib/puma/plugin/systemd.rb +90 -0
- data/lib/puma/plugin/tmp_restart.rb +3 -1
- data/lib/puma/plugin.rb +7 -13
- data/lib/puma/rack/builder.rb +7 -9
- data/lib/puma/rack/urlmap.rb +2 -0
- data/lib/puma/rack_default.rb +21 -4
- data/lib/puma/reactor.rb +85 -316
- data/lib/puma/request.rb +665 -0
- data/lib/puma/runner.rb +94 -69
- data/lib/puma/sd_notify.rb +149 -0
- data/lib/puma/server.rb +314 -771
- data/lib/puma/single.rb +20 -74
- data/lib/puma/state_file.rb +45 -8
- data/lib/puma/thread_pool.rb +142 -92
- data/lib/puma/util.rb +22 -10
- data/lib/puma.rb +60 -5
- data/lib/rack/handler/puma.rb +113 -91
- data/tools/Dockerfile +16 -0
- data/tools/trickletest.rb +0 -1
- metadata +54 -32
- data/ext/puma_http11/io_buffer.c +0 -155
- data/lib/puma/accept_nonblock.rb +0 -23
- data/lib/puma/compat.rb +0 -14
- data/lib/puma/convenient.rb +0 -25
- data/lib/puma/daemon_ext.rb +0 -33
- data/lib/puma/delegation.rb +0 -13
- data/lib/puma/java_io_buffer.rb +0 -47
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
- data/lib/puma/tcp_logger.rb +0 -41
- data/tools/jungle/README.md +0 -19
- data/tools/jungle/init.d/README.md +0 -61
- data/tools/jungle/init.d/puma +0 -421
- data/tools/jungle/init.d/run-puma +0 -18
- data/tools/jungle/upstart/README.md +0 -61
- data/tools/jungle/upstart/puma-manager.conf +0 -31
- data/tools/jungle/upstart/puma.conf +0 -69
@@ -10,6 +10,7 @@
|
|
10
10
|
#include "ext_help.h"
|
11
11
|
#include <assert.h>
|
12
12
|
#include <string.h>
|
13
|
+
#include <ctype.h>
|
13
14
|
#include "http11_parser.h"
|
14
15
|
|
15
16
|
#ifndef MANAGED_STRINGS
|
@@ -35,11 +36,13 @@ static VALUE global_request_method;
|
|
35
36
|
static VALUE global_request_uri;
|
36
37
|
static VALUE global_fragment;
|
37
38
|
static VALUE global_query_string;
|
38
|
-
static VALUE
|
39
|
+
static VALUE global_server_protocol;
|
39
40
|
static VALUE global_request_path;
|
40
41
|
|
41
42
|
/** Defines common length and error messages for input length validation. */
|
42
|
-
#define
|
43
|
+
#define QUOTE(s) #s
|
44
|
+
#define EXPAND_MAX_LENGTH_VALUE(s) QUOTE(s)
|
45
|
+
#define DEF_MAX_LENGTH(N,length) const size_t MAX_##N##_LENGTH = length; const char *MAX_##N##_LENGTH_ERR = "HTTP element " # N " is longer than the " EXPAND_MAX_LENGTH_VALUE(length) " allowed length (was %d)"
|
43
46
|
|
44
47
|
/** Validates the max length of given input and throws an HttpParserError exception if over. */
|
45
48
|
#define VALIDATE_MAX_LENGTH(len, N) if(len > MAX_##N##_LENGTH) { rb_raise(eHttpParserError, MAX_##N##_LENGTH_ERR, len); }
|
@@ -49,12 +52,24 @@ static VALUE global_request_path;
|
|
49
52
|
|
50
53
|
|
51
54
|
/* Defines the maximum allowed lengths for various input elements.*/
|
55
|
+
#ifndef PUMA_REQUEST_URI_MAX_LENGTH
|
56
|
+
#define PUMA_REQUEST_URI_MAX_LENGTH (1024 * 12)
|
57
|
+
#endif
|
58
|
+
|
59
|
+
#ifndef PUMA_REQUEST_PATH_MAX_LENGTH
|
60
|
+
#define PUMA_REQUEST_PATH_MAX_LENGTH (8192)
|
61
|
+
#endif
|
62
|
+
|
63
|
+
#ifndef PUMA_QUERY_STRING_MAX_LENGTH
|
64
|
+
#define PUMA_QUERY_STRING_MAX_LENGTH (1024 * 10)
|
65
|
+
#endif
|
66
|
+
|
52
67
|
DEF_MAX_LENGTH(FIELD_NAME, 256);
|
53
68
|
DEF_MAX_LENGTH(FIELD_VALUE, 80 * 1024);
|
54
|
-
DEF_MAX_LENGTH(REQUEST_URI,
|
69
|
+
DEF_MAX_LENGTH(REQUEST_URI, PUMA_REQUEST_URI_MAX_LENGTH);
|
55
70
|
DEF_MAX_LENGTH(FRAGMENT, 1024); /* Don't know if this length is specified somewhere or not */
|
56
|
-
DEF_MAX_LENGTH(REQUEST_PATH,
|
57
|
-
DEF_MAX_LENGTH(QUERY_STRING,
|
71
|
+
DEF_MAX_LENGTH(REQUEST_PATH, PUMA_REQUEST_PATH_MAX_LENGTH);
|
72
|
+
DEF_MAX_LENGTH(QUERY_STRING, PUMA_QUERY_STRING_MAX_LENGTH);
|
58
73
|
DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32)));
|
59
74
|
|
60
75
|
struct common_field {
|
@@ -111,21 +126,6 @@ static struct common_field common_http_fields[] = {
|
|
111
126
|
# undef f
|
112
127
|
};
|
113
128
|
|
114
|
-
/*
|
115
|
-
* qsort(3) and bsearch(3) improve average performance slightly, but may
|
116
|
-
* not be worth it for lack of portability to certain platforms...
|
117
|
-
*/
|
118
|
-
#if defined(HAVE_QSORT_BSEARCH)
|
119
|
-
/* sort by length, then by name if there's a tie */
|
120
|
-
static int common_field_cmp(const void *a, const void *b)
|
121
|
-
{
|
122
|
-
struct common_field *cfa = (struct common_field *)a;
|
123
|
-
struct common_field *cfb = (struct common_field *)b;
|
124
|
-
signed long diff = cfa->len - cfb->len;
|
125
|
-
return diff ? diff : memcmp(cfa->name, cfb->name, cfa->len);
|
126
|
-
}
|
127
|
-
#endif /* HAVE_QSORT_BSEARCH */
|
128
|
-
|
129
129
|
static void init_common_fields(void)
|
130
130
|
{
|
131
131
|
unsigned i;
|
@@ -142,28 +142,10 @@ static void init_common_fields(void)
|
|
142
142
|
}
|
143
143
|
rb_global_variable(&cf->value);
|
144
144
|
}
|
145
|
-
|
146
|
-
#if defined(HAVE_QSORT_BSEARCH)
|
147
|
-
qsort(common_http_fields,
|
148
|
-
ARRAY_SIZE(common_http_fields),
|
149
|
-
sizeof(struct common_field),
|
150
|
-
common_field_cmp);
|
151
|
-
#endif /* HAVE_QSORT_BSEARCH */
|
152
145
|
}
|
153
146
|
|
154
147
|
static VALUE find_common_field_value(const char *field, size_t flen)
|
155
148
|
{
|
156
|
-
#if defined(HAVE_QSORT_BSEARCH)
|
157
|
-
struct common_field key;
|
158
|
-
struct common_field *found;
|
159
|
-
key.name = field;
|
160
|
-
key.len = (signed long)flen;
|
161
|
-
found = (struct common_field *)bsearch(&key, common_http_fields,
|
162
|
-
ARRAY_SIZE(common_http_fields),
|
163
|
-
sizeof(struct common_field),
|
164
|
-
common_field_cmp);
|
165
|
-
return found ? found->value : Qnil;
|
166
|
-
#else /* !HAVE_QSORT_BSEARCH */
|
167
149
|
unsigned i;
|
168
150
|
struct common_field *cf = common_http_fields;
|
169
151
|
for(i = 0; i < ARRAY_SIZE(common_http_fields); i++, cf++) {
|
@@ -171,7 +153,6 @@ static VALUE find_common_field_value(const char *field, size_t flen)
|
|
171
153
|
return cf->value;
|
172
154
|
}
|
173
155
|
return Qnil;
|
174
|
-
#endif /* !HAVE_QSORT_BSEARCH */
|
175
156
|
}
|
176
157
|
|
177
158
|
void http_field(puma_parser* hp, const char *field, size_t flen,
|
@@ -200,6 +181,8 @@ void http_field(puma_parser* hp, const char *field, size_t flen,
|
|
200
181
|
f = rb_str_new(hp->buf, new_size);
|
201
182
|
}
|
202
183
|
|
184
|
+
while (vlen > 0 && isspace(value[vlen - 1])) vlen--;
|
185
|
+
|
203
186
|
/* check for duplicate header */
|
204
187
|
v = rb_hash_aref(hp->request, f);
|
205
188
|
|
@@ -261,10 +244,10 @@ void query_string(puma_parser* hp, const char *at, size_t length)
|
|
261
244
|
rb_hash_aset(hp->request, global_query_string, val);
|
262
245
|
}
|
263
246
|
|
264
|
-
void
|
247
|
+
void server_protocol(puma_parser* hp, const char *at, size_t length)
|
265
248
|
{
|
266
249
|
VALUE val = rb_str_new(at, length);
|
267
|
-
rb_hash_aset(hp->request,
|
250
|
+
rb_hash_aset(hp->request, global_server_protocol, val);
|
268
251
|
}
|
269
252
|
|
270
253
|
/** Finalizes the request header to have a bunch of stuff that's
|
@@ -284,11 +267,18 @@ void HttpParser_free(void *data) {
|
|
284
267
|
}
|
285
268
|
}
|
286
269
|
|
287
|
-
void HttpParser_mark(
|
270
|
+
void HttpParser_mark(void *ptr) {
|
271
|
+
puma_parser *hp = ptr;
|
288
272
|
if(hp->request) rb_gc_mark(hp->request);
|
289
273
|
if(hp->body) rb_gc_mark(hp->body);
|
290
274
|
}
|
291
275
|
|
276
|
+
const rb_data_type_t HttpParser_data_type = {
|
277
|
+
"HttpParser",
|
278
|
+
{ HttpParser_mark, HttpParser_free, 0 },
|
279
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
280
|
+
};
|
281
|
+
|
292
282
|
VALUE HttpParser_alloc(VALUE klass)
|
293
283
|
{
|
294
284
|
puma_parser *hp = ALLOC_N(puma_parser, 1);
|
@@ -299,13 +289,13 @@ VALUE HttpParser_alloc(VALUE klass)
|
|
299
289
|
hp->fragment = fragment;
|
300
290
|
hp->request_path = request_path;
|
301
291
|
hp->query_string = query_string;
|
302
|
-
hp->
|
292
|
+
hp->server_protocol = server_protocol;
|
303
293
|
hp->header_done = header_done;
|
304
294
|
hp->request = Qnil;
|
305
295
|
|
306
296
|
puma_parser_init(hp);
|
307
297
|
|
308
|
-
return
|
298
|
+
return TypedData_Wrap_Struct(klass, &HttpParser_data_type, hp);
|
309
299
|
}
|
310
300
|
|
311
301
|
/**
|
@@ -317,7 +307,7 @@ VALUE HttpParser_alloc(VALUE klass)
|
|
317
307
|
VALUE HttpParser_init(VALUE self)
|
318
308
|
{
|
319
309
|
puma_parser *http = NULL;
|
320
|
-
DATA_GET(self, puma_parser, http);
|
310
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
321
311
|
puma_parser_init(http);
|
322
312
|
|
323
313
|
return self;
|
@@ -334,7 +324,7 @@ VALUE HttpParser_init(VALUE self)
|
|
334
324
|
VALUE HttpParser_reset(VALUE self)
|
335
325
|
{
|
336
326
|
puma_parser *http = NULL;
|
337
|
-
DATA_GET(self, puma_parser, http);
|
327
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
338
328
|
puma_parser_init(http);
|
339
329
|
|
340
330
|
return Qnil;
|
@@ -351,7 +341,7 @@ VALUE HttpParser_reset(VALUE self)
|
|
351
341
|
VALUE HttpParser_finish(VALUE self)
|
352
342
|
{
|
353
343
|
puma_parser *http = NULL;
|
354
|
-
DATA_GET(self, puma_parser, http);
|
344
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
355
345
|
puma_parser_finish(http);
|
356
346
|
|
357
347
|
return puma_parser_is_finished(http) ? Qtrue : Qfalse;
|
@@ -382,7 +372,7 @@ VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
|
|
382
372
|
char *dptr = NULL;
|
383
373
|
long dlen = 0;
|
384
374
|
|
385
|
-
DATA_GET(self, puma_parser, http);
|
375
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
386
376
|
|
387
377
|
from = FIX2INT(start);
|
388
378
|
dptr = rb_extract_chars(data, &dlen);
|
@@ -398,7 +388,7 @@ VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
|
|
398
388
|
VALIDATE_MAX_LENGTH(puma_parser_nread(http), HEADER);
|
399
389
|
|
400
390
|
if(puma_parser_has_error(http)) {
|
401
|
-
rb_raise(eHttpParserError, "%s", "Invalid HTTP format, parsing fails.");
|
391
|
+
rb_raise(eHttpParserError, "%s", "Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?");
|
402
392
|
} else {
|
403
393
|
return INT2FIX(puma_parser_nread(http));
|
404
394
|
}
|
@@ -416,7 +406,7 @@ VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
|
|
416
406
|
VALUE HttpParser_has_error(VALUE self)
|
417
407
|
{
|
418
408
|
puma_parser *http = NULL;
|
419
|
-
DATA_GET(self, puma_parser, http);
|
409
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
420
410
|
|
421
411
|
return puma_parser_has_error(http) ? Qtrue : Qfalse;
|
422
412
|
}
|
@@ -431,7 +421,7 @@ VALUE HttpParser_has_error(VALUE self)
|
|
431
421
|
VALUE HttpParser_is_finished(VALUE self)
|
432
422
|
{
|
433
423
|
puma_parser *http = NULL;
|
434
|
-
DATA_GET(self, puma_parser, http);
|
424
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
435
425
|
|
436
426
|
return puma_parser_is_finished(http) ? Qtrue : Qfalse;
|
437
427
|
}
|
@@ -447,7 +437,7 @@ VALUE HttpParser_is_finished(VALUE self)
|
|
447
437
|
VALUE HttpParser_nread(VALUE self)
|
448
438
|
{
|
449
439
|
puma_parser *http = NULL;
|
450
|
-
DATA_GET(self, puma_parser, http);
|
440
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
451
441
|
|
452
442
|
return INT2FIX(http->nread);
|
453
443
|
}
|
@@ -460,15 +450,16 @@ VALUE HttpParser_nread(VALUE self)
|
|
460
450
|
*/
|
461
451
|
VALUE HttpParser_body(VALUE self) {
|
462
452
|
puma_parser *http = NULL;
|
463
|
-
DATA_GET(self, puma_parser, http);
|
453
|
+
DATA_GET(self, puma_parser, &HttpParser_data_type, http);
|
464
454
|
|
465
455
|
return http->body;
|
466
456
|
}
|
467
457
|
|
468
|
-
|
458
|
+
#ifdef HAVE_OPENSSL_BIO_H
|
469
459
|
void Init_mini_ssl(VALUE mod);
|
460
|
+
#endif
|
470
461
|
|
471
|
-
void Init_puma_http11()
|
462
|
+
void Init_puma_http11(void)
|
472
463
|
{
|
473
464
|
|
474
465
|
VALUE mPuma = rb_define_module("Puma");
|
@@ -478,7 +469,7 @@ void Init_puma_http11()
|
|
478
469
|
DEF_GLOBAL(request_uri, "REQUEST_URI");
|
479
470
|
DEF_GLOBAL(fragment, "FRAGMENT");
|
480
471
|
DEF_GLOBAL(query_string, "QUERY_STRING");
|
481
|
-
DEF_GLOBAL(
|
472
|
+
DEF_GLOBAL(server_protocol, "SERVER_PROTOCOL");
|
482
473
|
DEF_GLOBAL(request_path, "REQUEST_PATH");
|
483
474
|
|
484
475
|
eHttpParserError = rb_define_class_under(mPuma, "HttpParserError", rb_eIOError);
|
@@ -495,6 +486,7 @@ void Init_puma_http11()
|
|
495
486
|
rb_define_method(cHttpParser, "body", HttpParser_body, 0);
|
496
487
|
init_common_fields();
|
497
488
|
|
498
|
-
|
489
|
+
#ifdef HAVE_OPENSSL_BIO_H
|
499
490
|
Init_mini_ssl(mPuma);
|
491
|
+
#endif
|
500
492
|
}
|
data/lib/puma/app/status.rb
CHANGED
@@ -1,73 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative '../json_serialization'
|
3
|
+
|
1
4
|
module Puma
|
2
5
|
module App
|
6
|
+
# Check out {#call}'s source code to see what actions this web application
|
7
|
+
# can respond to.
|
3
8
|
class Status
|
4
|
-
def initialize(cli)
|
5
|
-
@cli = cli
|
6
|
-
@auth_token = nil
|
7
|
-
end
|
8
9
|
OK_STATUS = '{ "status": "ok" }'.freeze
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def rack_response(status, body, content_type='application/json')
|
18
|
-
headers = {
|
19
|
-
'Content-Type' => content_type,
|
20
|
-
'Content-Length' => body.bytesize.to_s
|
21
|
-
}
|
22
|
-
|
23
|
-
[status, headers, [body]]
|
11
|
+
# @param launcher [::Puma::Launcher]
|
12
|
+
# @param token [String, nil] the token used for authentication
|
13
|
+
#
|
14
|
+
def initialize(launcher, token = nil)
|
15
|
+
@launcher = launcher
|
16
|
+
@auth_token = token
|
24
17
|
end
|
25
18
|
|
19
|
+
# most commands call methods in `::Puma::Launcher` based on command in
|
20
|
+
# `env['PATH_INFO']`
|
26
21
|
def call(env)
|
27
22
|
unless authenticate(env)
|
28
23
|
return rack_response(403, 'Invalid auth token', 'text/plain')
|
29
24
|
end
|
30
25
|
|
31
|
-
case
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
# resp_type is processed by following case statement, return
|
27
|
+
# is a number (status) or a string used as the body of a 200 response
|
28
|
+
resp_type =
|
29
|
+
case env['PATH_INFO'][/\/([^\/]+)$/, 1]
|
30
|
+
when 'stop'
|
31
|
+
@launcher.stop ; 200
|
35
32
|
|
36
|
-
|
37
|
-
|
38
|
-
return rack_response(200, OK_STATUS)
|
33
|
+
when 'halt'
|
34
|
+
@launcher.halt ; 200
|
39
35
|
|
40
|
-
|
41
|
-
|
42
|
-
return rack_response(200, OK_STATUS)
|
36
|
+
when 'restart'
|
37
|
+
@launcher.restart ; 200
|
43
38
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
39
|
+
when 'phased-restart'
|
40
|
+
@launcher.phased_restart ? 200 : 404
|
41
|
+
|
42
|
+
when 'refork'
|
43
|
+
@launcher.refork ? 200 : 404
|
44
|
+
|
45
|
+
when 'reload-worker-directory'
|
46
|
+
@launcher.send(:reload_worker_directory) ? 200 : 404
|
47
|
+
|
48
|
+
when 'gc'
|
49
|
+
GC.start ; 200
|
50
|
+
|
51
|
+
when 'gc-stats'
|
52
|
+
Puma::JSONSerialization.generate GC.stat
|
53
|
+
|
54
|
+
when 'stats'
|
55
|
+
Puma::JSONSerialization.generate @launcher.stats
|
56
|
+
|
57
|
+
when 'thread-backtraces'
|
58
|
+
backtraces = []
|
59
|
+
@launcher.thread_status do |name, backtrace|
|
60
|
+
backtraces << { name: name, backtrace: backtrace }
|
61
|
+
end
|
62
|
+
Puma::JSONSerialization.generate backtraces
|
50
63
|
|
51
|
-
when /\/reload-worker-directory$/
|
52
|
-
if !@cli.send(:reload_worker_directory)
|
53
|
-
return rack_response(404, '{ "error": "reload_worker_directory not available" }')
|
54
64
|
else
|
55
|
-
return rack_response(
|
65
|
+
return rack_response(404, "Unsupported action", 'text/plain')
|
56
66
|
end
|
57
67
|
|
58
|
-
|
59
|
-
|
60
|
-
|
68
|
+
case resp_type
|
69
|
+
when String
|
70
|
+
rack_response 200, resp_type
|
71
|
+
when 200
|
72
|
+
rack_response 200, OK_STATUS
|
73
|
+
when 404
|
74
|
+
str = env['PATH_INFO'][/\/(\S+)/, 1].tr '-', '_'
|
75
|
+
rack_response 404, "{ \"error\": \"#{str} not available\" }"
|
76
|
+
end
|
77
|
+
end
|
61
78
|
|
62
|
-
|
63
|
-
json = "{" + GC.stat.map { |k, v| "\"#{k}\": #{v}" }.join(",") + "}"
|
64
|
-
return rack_response(200, json)
|
79
|
+
private
|
65
80
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
81
|
+
def authenticate(env)
|
82
|
+
return true unless @auth_token
|
83
|
+
env['QUERY_STRING'].to_s.split(/&;/).include?("token=#{@auth_token}")
|
84
|
+
end
|
85
|
+
|
86
|
+
def rack_response(status, body, content_type='application/json')
|
87
|
+
headers = {
|
88
|
+
'content-type' => content_type,
|
89
|
+
'content-length' => body.bytesize.to_s
|
90
|
+
}
|
91
|
+
|
92
|
+
[status, headers, [body]]
|
71
93
|
end
|
72
94
|
end
|
73
95
|
end
|