puma 2.2.0 → 8.0.2
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 +7 -0
- data/History.md +3334 -0
- data/LICENSE +23 -20
- data/README.md +387 -100
- data/bin/puma-wild +25 -0
- data/bin/pumactl +1 -1
- data/docs/5.0-Upgrade.md +98 -0
- data/docs/6.0-Upgrade.md +56 -0
- data/docs/7.0-Upgrade.md +52 -0
- data/docs/8.0-Upgrade.md +100 -0
- data/docs/architecture.md +74 -0
- data/docs/compile_options.md +55 -0
- data/docs/deployment.md +137 -0
- data/docs/fork_worker.md +41 -0
- data/docs/grpc.md +62 -0
- data/docs/images/favicon.svg +1 -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/images/running-puma.svg +1 -0
- data/docs/images/standard-logo.svg +1 -0
- data/docs/java_options.md +54 -0
- data/docs/jungle/README.md +9 -0
- data/docs/jungle/rc.d/README.md +74 -0
- data/docs/jungle/rc.d/puma +61 -0
- data/docs/jungle/rc.d/puma.conf +10 -0
- data/docs/kubernetes.md +73 -0
- data/docs/nginx.md +5 -5
- data/docs/plugins.md +42 -0
- data/docs/rails_dev_mode.md +28 -0
- data/docs/restart.md +65 -0
- data/docs/signals.md +98 -0
- data/docs/stats.md +148 -0
- data/docs/systemd.md +253 -0
- 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/extconf.rb +59 -2
- data/ext/puma_http11/http11_parser.c +319 -487
- data/ext/puma_http11/http11_parser.h +15 -13
- data/ext/puma_http11/http11_parser.java.rl +64 -94
- data/ext/puma_http11/http11_parser.rl +27 -24
- data/ext/puma_http11/http11_parser_common.rl +8 -8
- data/ext/puma_http11/mini_ssl.c +696 -38
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/EnvKey.java +241 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +241 -145
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +174 -221
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +413 -193
- data/ext/puma_http11/puma_http11.c +183 -175
- data/lib/puma/app/status.rb +77 -29
- data/lib/puma/binder.rb +349 -119
- data/lib/puma/cli.rb +163 -801
- data/lib/puma/client.rb +627 -144
- data/lib/puma/client_env.rb +171 -0
- data/lib/puma/cluster/worker.rb +183 -0
- data/lib/puma/cluster/worker_handle.rb +127 -0
- data/lib/puma/cluster.rb +634 -0
- data/lib/puma/cluster_accept_loop_delay.rb +91 -0
- data/lib/puma/commonlogger.rb +115 -0
- data/lib/puma/configuration.rb +420 -198
- data/lib/puma/const.rb +266 -115
- data/lib/puma/control_cli.rb +219 -120
- data/lib/puma/detect.rb +56 -2
- data/lib/puma/dsl.rb +1562 -0
- data/lib/puma/error_logger.rb +115 -0
- data/lib/puma/events.rb +44 -60
- data/lib/puma/io_buffer.rb +48 -5
- data/lib/puma/jruby_restart.rb +2 -51
- data/lib/puma/json_serialization.rb +96 -0
- data/lib/puma/launcher/bundle_pruner.rb +102 -0
- data/lib/puma/launcher.rb +501 -0
- data/lib/puma/log_writer.rb +153 -0
- data/lib/puma/minissl/context_builder.rb +96 -0
- data/lib/puma/minissl.rb +355 -37
- data/lib/puma/null_io.rb +79 -12
- data/lib/puma/plugin/systemd.rb +90 -0
- data/lib/puma/plugin/tmp_restart.rb +36 -0
- data/lib/puma/plugin.rb +111 -0
- data/lib/puma/rack/builder.rb +297 -0
- data/lib/puma/rack/urlmap.rb +93 -0
- data/lib/puma/rack_default.rb +21 -4
- data/lib/puma/reactor.rb +102 -133
- data/lib/puma/response.rb +532 -0
- data/lib/puma/runner.rb +211 -0
- data/lib/puma/sd_notify.rb +146 -0
- data/lib/puma/server.rb +582 -445
- data/lib/puma/server_plugin_control.rb +32 -0
- data/lib/puma/single.rb +72 -0
- data/lib/puma/state_file.rb +69 -0
- data/lib/puma/thread_pool.rb +389 -57
- data/lib/puma/util.rb +125 -0
- data/lib/puma.rb +80 -6
- data/lib/rack/handler/puma.rb +125 -47
- data/tools/Dockerfile +26 -0
- data/tools/trickletest.rb +44 -0
- metadata +88 -148
- data/COPYING +0 -55
- data/Gemfile +0 -10
- data/History.txt +0 -302
- data/Manifest.txt +0 -60
- data/Rakefile +0 -165
- data/TODO +0 -5
- data/docs/config.md +0 -0
- data/ext/puma_http11/ext_help.h +0 -15
- data/ext/puma_http11/io_buffer.c +0 -154
- data/lib/puma/accept_nonblock.rb +0 -23
- data/lib/puma/capistrano.rb +0 -34
- data/lib/puma/compat.rb +0 -11
- data/lib/puma/daemon_ext.rb +0 -20
- data/lib/puma/delegation.rb +0 -11
- data/lib/puma/java_io_buffer.rb +0 -45
- data/lib/puma/rack_patch.rb +0 -25
- data/puma.gemspec +0 -45
- data/test/test_app_status.rb +0 -88
- data/test/test_cli.rb +0 -171
- data/test/test_config.rb +0 -16
- data/test/test_http10.rb +0 -27
- data/test/test_http11.rb +0 -126
- data/test/test_integration.rb +0 -154
- data/test/test_iobuffer.rb +0 -38
- data/test/test_minissl.rb +0 -25
- data/test/test_null_io.rb +0 -31
- data/test/test_persistent.rb +0 -238
- data/test/test_puma_server.rb +0 -224
- data/test/test_rack_handler.rb +0 -10
- data/test/test_rack_server.rb +0 -141
- data/test/test_thread_pool.rb +0 -146
- data/test/test_unix_socket.rb +0 -39
- data/test/test_ws.rb +0 -89
- data/tools/jungle/init.d/README.md +0 -54
- data/tools/jungle/init.d/puma +0 -332
- data/tools/jungle/init.d/run-puma +0 -3
- data/tools/jungle/upstart/README.md +0 -61
- data/tools/jungle/upstart/puma-manager.conf +0 -31
- data/tools/jungle/upstart/puma.conf +0 -52
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Copyright (c) 2005 Zed A. Shaw
|
|
3
3
|
* You can redistribute it and/or modify it under the same terms as Ruby.
|
|
4
|
+
* License 3-clause BSD
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
#ifndef http11_parser_h
|
|
7
8
|
#define http11_parser_h
|
|
8
9
|
|
|
10
|
+
#define RSTRING_NOT_MODIFIED 1
|
|
9
11
|
#include "ruby.h"
|
|
10
12
|
|
|
11
13
|
#include <sys/types.h>
|
|
@@ -16,19 +18,19 @@
|
|
|
16
18
|
|
|
17
19
|
#define BUFFER_LEN 1024
|
|
18
20
|
|
|
19
|
-
struct
|
|
21
|
+
struct puma_parser;
|
|
20
22
|
|
|
21
|
-
typedef void (*element_cb)(struct
|
|
23
|
+
typedef void (*element_cb)(struct puma_parser* hp,
|
|
22
24
|
const char *at, size_t length);
|
|
23
25
|
|
|
24
|
-
typedef void (*field_cb)(struct
|
|
26
|
+
typedef void (*field_cb)(struct puma_parser* hp,
|
|
25
27
|
const char *field, size_t flen,
|
|
26
28
|
const char *value, size_t vlen);
|
|
27
29
|
|
|
28
|
-
typedef struct
|
|
30
|
+
typedef struct puma_parser {
|
|
29
31
|
int cs;
|
|
30
|
-
size_t body_start;
|
|
31
32
|
int content_len;
|
|
33
|
+
size_t body_start;
|
|
32
34
|
size_t nread;
|
|
33
35
|
size_t mark;
|
|
34
36
|
size_t field_start;
|
|
@@ -44,20 +46,20 @@ typedef struct http_parser {
|
|
|
44
46
|
element_cb fragment;
|
|
45
47
|
element_cb request_path;
|
|
46
48
|
element_cb query_string;
|
|
47
|
-
element_cb
|
|
49
|
+
element_cb server_protocol;
|
|
48
50
|
element_cb header_done;
|
|
49
51
|
|
|
50
52
|
char buf[BUFFER_LEN];
|
|
51
53
|
|
|
52
|
-
}
|
|
54
|
+
} puma_parser;
|
|
53
55
|
|
|
54
|
-
int
|
|
55
|
-
int
|
|
56
|
-
size_t
|
|
56
|
+
int puma_parser_init(puma_parser *parser);
|
|
57
|
+
int puma_parser_finish(puma_parser *parser);
|
|
58
|
+
size_t puma_parser_execute(puma_parser *parser, const char *data,
|
|
57
59
|
size_t len, size_t off);
|
|
58
|
-
int
|
|
59
|
-
int
|
|
60
|
+
int puma_parser_has_error(puma_parser *parser);
|
|
61
|
+
int puma_parser_is_finished(puma_parser *parser);
|
|
60
62
|
|
|
61
|
-
#define
|
|
63
|
+
#define puma_parser_nread(parser) (parser)->nread
|
|
62
64
|
|
|
63
65
|
#endif
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
package org.jruby.puma;
|
|
2
2
|
|
|
3
|
+
import org.jruby.Ruby;
|
|
4
|
+
import org.jruby.RubyHash;
|
|
5
|
+
import org.jruby.RubyString;
|
|
3
6
|
import org.jruby.util.ByteList;
|
|
4
7
|
|
|
5
8
|
public class Http11Parser {
|
|
@@ -7,138 +10,105 @@ public class Http11Parser {
|
|
|
7
10
|
/** Machine **/
|
|
8
11
|
|
|
9
12
|
%%{
|
|
10
|
-
|
|
11
|
-
machine http_parser;
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
machine puma_parser;
|
|
15
|
+
|
|
16
|
+
action mark {this.mark = fpc; }
|
|
14
17
|
|
|
15
|
-
action start_field {
|
|
16
|
-
action snake_upcase_field { /*
|
|
18
|
+
action start_field { this.field_start = fpc; }
|
|
19
|
+
action snake_upcase_field { /* done lazily as needed */ }
|
|
17
20
|
action write_field {
|
|
18
|
-
|
|
21
|
+
this.field_len = fpc-this.field_start;
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
action start_value {
|
|
22
|
-
action write_value {
|
|
23
|
-
|
|
24
|
-
parser.http_field.call(parser.data, parser.field_start, parser.field_len, parser.mark, fpc-parser.mark);
|
|
25
|
-
}
|
|
24
|
+
action start_value { this.mark = fpc; }
|
|
25
|
+
action write_value {
|
|
26
|
+
Http11.http_field(runtime, envStrings, this, fpc-this.mark);
|
|
26
27
|
}
|
|
27
|
-
action request_method {
|
|
28
|
-
|
|
29
|
-
parser.request_method.call(parser.data, parser.mark, fpc-parser.mark);
|
|
28
|
+
action request_method {
|
|
29
|
+
Http11.request_method(runtime, envStrings, this, fpc-this.mark);
|
|
30
30
|
}
|
|
31
|
-
action request_uri {
|
|
32
|
-
|
|
33
|
-
parser.request_uri.call(parser.data, parser.mark, fpc-parser.mark);
|
|
31
|
+
action request_uri {
|
|
32
|
+
Http11.request_uri(runtime, envStrings, this, fpc-this.mark);
|
|
34
33
|
}
|
|
35
|
-
action fragment {
|
|
36
|
-
|
|
37
|
-
parser.fragment.call(parser.data, parser.mark, fpc-parser.mark);
|
|
34
|
+
action fragment {
|
|
35
|
+
Http11.fragment(runtime, envStrings, this, fpc-this.mark);
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
action start_query {
|
|
41
|
-
action query_string {
|
|
42
|
-
|
|
43
|
-
parser.query_string.call(parser.data, parser.query_start, fpc-parser.query_start);
|
|
38
|
+
action start_query {this.query_start = fpc; }
|
|
39
|
+
action query_string {
|
|
40
|
+
Http11.query_string(runtime, envStrings, this, fpc-this.query_start);
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
action
|
|
47
|
-
|
|
48
|
-
parser.http_version.call(parser.data, parser.mark, fpc-parser.mark);
|
|
43
|
+
action server_protocol {
|
|
44
|
+
Http11.server_protocol(runtime, envStrings, this, fpc-this.mark);
|
|
49
45
|
}
|
|
50
46
|
|
|
51
47
|
action request_path {
|
|
52
|
-
|
|
53
|
-
parser.request_path.call(parser.data, parser.mark, fpc-parser.mark);
|
|
48
|
+
Http11.request_path(runtime, envStrings, this, fpc-this.mark);
|
|
54
49
|
}
|
|
55
50
|
|
|
56
51
|
action done {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
parser.header_done.call(parser.data, fpc + 1, pe - fpc - 1);
|
|
52
|
+
this.body_start = fpc + 1;
|
|
53
|
+
http.header_done(runtime, this, fpc + 1, pe - fpc - 1);
|
|
60
54
|
fbreak;
|
|
61
55
|
}
|
|
62
56
|
|
|
63
|
-
include
|
|
57
|
+
include puma_parser_common "http11_parser_common.rl";
|
|
64
58
|
|
|
65
59
|
}%%
|
|
66
60
|
|
|
67
61
|
/** Data **/
|
|
68
|
-
%% write data;
|
|
62
|
+
%% write data noentry;
|
|
69
63
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
int cs;
|
|
65
|
+
int body_start;
|
|
66
|
+
int nread;
|
|
67
|
+
int mark;
|
|
68
|
+
int field_start;
|
|
69
|
+
int field_len;
|
|
70
|
+
int query_start;
|
|
73
71
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
72
|
+
RubyHash data;
|
|
73
|
+
byte[] buffer;
|
|
77
74
|
|
|
78
|
-
public
|
|
79
|
-
int cs;
|
|
80
|
-
int body_start;
|
|
81
|
-
int content_len;
|
|
82
|
-
int nread;
|
|
83
|
-
int mark;
|
|
84
|
-
int field_start;
|
|
85
|
-
int field_len;
|
|
86
|
-
int query_start;
|
|
87
|
-
|
|
88
|
-
Object data;
|
|
89
|
-
ByteList buffer;
|
|
90
|
-
|
|
91
|
-
public FieldCB http_field;
|
|
92
|
-
public ElementCB request_method;
|
|
93
|
-
public ElementCB request_uri;
|
|
94
|
-
public ElementCB fragment;
|
|
95
|
-
public ElementCB request_path;
|
|
96
|
-
public ElementCB query_string;
|
|
97
|
-
public ElementCB http_version;
|
|
98
|
-
public ElementCB header_done;
|
|
99
|
-
|
|
100
|
-
public void init() {
|
|
101
|
-
cs = 0;
|
|
102
|
-
|
|
103
|
-
%% write init;
|
|
104
|
-
|
|
105
|
-
body_start = 0;
|
|
106
|
-
content_len = 0;
|
|
107
|
-
mark = 0;
|
|
108
|
-
nread = 0;
|
|
109
|
-
field_len = 0;
|
|
110
|
-
field_start = 0;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
75
|
+
public void init() {
|
|
113
76
|
|
|
114
|
-
|
|
77
|
+
%% write init;
|
|
78
|
+
|
|
79
|
+
body_start = 0;
|
|
80
|
+
mark = 0;
|
|
81
|
+
nread = 0;
|
|
82
|
+
field_len = 0;
|
|
83
|
+
field_start = 0;
|
|
84
|
+
}
|
|
115
85
|
|
|
116
|
-
public int execute(ByteList buffer, int off) {
|
|
86
|
+
public int execute(Ruby runtime, Http11 http, ByteList buffer, int off) {
|
|
117
87
|
int p, pe;
|
|
118
|
-
int cs =
|
|
88
|
+
int cs = this.cs;
|
|
119
89
|
int len = buffer.length();
|
|
90
|
+
int beg = buffer.begin();
|
|
91
|
+
RubyString[] envStrings = http.envStrings;
|
|
120
92
|
assert off<=len : "offset past end of buffer";
|
|
121
93
|
|
|
122
|
-
p = off;
|
|
123
|
-
pe = len;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
byte[] data = buffer.bytes();
|
|
127
|
-
parser.buffer = buffer;
|
|
94
|
+
p = beg + off;
|
|
95
|
+
pe = beg + len;
|
|
96
|
+
byte[] data = buffer.unsafeBytes();
|
|
97
|
+
this.buffer = data;
|
|
128
98
|
|
|
129
99
|
%% write exec;
|
|
130
100
|
|
|
131
|
-
|
|
132
|
-
|
|
101
|
+
this.cs = cs;
|
|
102
|
+
this.nread += (p - off);
|
|
133
103
|
|
|
134
104
|
assert p <= pe : "buffer overflow after parsing execute";
|
|
135
|
-
assert
|
|
136
|
-
assert
|
|
137
|
-
assert
|
|
138
|
-
assert
|
|
139
|
-
assert
|
|
105
|
+
assert this.nread <= len : "nread longer than length";
|
|
106
|
+
assert this.body_start <= len : "body starts after buffer end";
|
|
107
|
+
assert this.mark < len : "mark is after buffer end";
|
|
108
|
+
assert this.field_len <= len : "field has length longer than whole buffer";
|
|
109
|
+
assert this.field_start < len : "field starts after buffer end";
|
|
140
110
|
|
|
141
|
-
return
|
|
111
|
+
return this.nread;
|
|
142
112
|
}
|
|
143
113
|
|
|
144
114
|
public int finish() {
|
|
@@ -152,10 +122,10 @@ public class Http11Parser {
|
|
|
152
122
|
}
|
|
153
123
|
|
|
154
124
|
public boolean has_error() {
|
|
155
|
-
return
|
|
125
|
+
return this.cs == puma_parser_error;
|
|
156
126
|
}
|
|
157
127
|
|
|
158
128
|
public boolean is_finished() {
|
|
159
|
-
return
|
|
129
|
+
return this.cs == puma_parser_first_final;
|
|
160
130
|
}
|
|
161
131
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Copyright (c) 2005 Zed A. Shaw
|
|
3
3
|
* You can redistribute it and/or modify it under the same terms as Ruby.
|
|
4
|
+
* License 3-clause BSD
|
|
4
5
|
*/
|
|
5
6
|
#include "http11_parser.h"
|
|
6
7
|
#include <stdio.h>
|
|
@@ -11,12 +12,14 @@
|
|
|
11
12
|
|
|
12
13
|
/*
|
|
13
14
|
* capitalizes all lower-case ASCII characters,
|
|
14
|
-
* converts dashes to underscores.
|
|
15
|
+
* converts dashes to underscores, and underscores to commas.
|
|
15
16
|
*/
|
|
16
17
|
static void snake_upcase_char(char *c)
|
|
17
18
|
{
|
|
18
19
|
if (*c >= 'a' && *c <= 'z')
|
|
19
20
|
*c &= ~0x20;
|
|
21
|
+
else if (*c == '_')
|
|
22
|
+
*c = ',';
|
|
20
23
|
else if (*c == '-')
|
|
21
24
|
*c = '_';
|
|
22
25
|
}
|
|
@@ -28,15 +31,15 @@ static void snake_upcase_char(char *c)
|
|
|
28
31
|
/** Machine **/
|
|
29
32
|
|
|
30
33
|
%%{
|
|
31
|
-
|
|
32
|
-
machine
|
|
34
|
+
|
|
35
|
+
machine puma_parser;
|
|
33
36
|
|
|
34
37
|
action mark { MARK(mark, fpc); }
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
action start_field { MARK(field_start, fpc); }
|
|
38
41
|
action snake_upcase_field { snake_upcase_char((char *)fpc); }
|
|
39
|
-
action write_field {
|
|
42
|
+
action write_field {
|
|
40
43
|
parser->field_len = LEN(field_start, fpc);
|
|
41
44
|
}
|
|
42
45
|
|
|
@@ -44,10 +47,10 @@ static void snake_upcase_char(char *c)
|
|
|
44
47
|
action write_value {
|
|
45
48
|
parser->http_field(parser, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, fpc));
|
|
46
49
|
}
|
|
47
|
-
action request_method {
|
|
50
|
+
action request_method {
|
|
48
51
|
parser->request_method(parser, PTR_TO(mark), LEN(mark, fpc));
|
|
49
52
|
}
|
|
50
|
-
action request_uri {
|
|
53
|
+
action request_uri {
|
|
51
54
|
parser->request_uri(parser, PTR_TO(mark), LEN(mark, fpc));
|
|
52
55
|
}
|
|
53
56
|
action fragment {
|
|
@@ -55,32 +58,32 @@ static void snake_upcase_char(char *c)
|
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
action start_query { MARK(query_start, fpc); }
|
|
58
|
-
action query_string {
|
|
61
|
+
action query_string {
|
|
59
62
|
parser->query_string(parser, PTR_TO(query_start), LEN(query_start, fpc));
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
action
|
|
63
|
-
parser->
|
|
65
|
+
action server_protocol {
|
|
66
|
+
parser->server_protocol(parser, PTR_TO(mark), LEN(mark, fpc));
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
action request_path {
|
|
67
70
|
parser->request_path(parser, PTR_TO(mark), LEN(mark,fpc));
|
|
68
71
|
}
|
|
69
72
|
|
|
70
|
-
action done {
|
|
71
|
-
parser->body_start = fpc - buffer + 1;
|
|
73
|
+
action done {
|
|
74
|
+
parser->body_start = fpc - buffer + 1;
|
|
72
75
|
parser->header_done(parser, fpc + 1, pe - fpc - 1);
|
|
73
76
|
fbreak;
|
|
74
77
|
}
|
|
75
78
|
|
|
76
|
-
include
|
|
79
|
+
include puma_parser_common "http11_parser_common.rl";
|
|
77
80
|
|
|
78
81
|
}%%
|
|
79
82
|
|
|
80
83
|
/** Data **/
|
|
81
|
-
%% write data;
|
|
84
|
+
%% write data noentry;
|
|
82
85
|
|
|
83
|
-
int
|
|
86
|
+
int puma_parser_init(puma_parser *parser) {
|
|
84
87
|
int cs = 0;
|
|
85
88
|
%% write init;
|
|
86
89
|
parser->cs = cs;
|
|
@@ -98,7 +101,7 @@ int http_parser_init(http_parser *parser) {
|
|
|
98
101
|
|
|
99
102
|
|
|
100
103
|
/** exec **/
|
|
101
|
-
size_t
|
|
104
|
+
size_t puma_parser_execute(puma_parser *parser, const char *buffer, size_t len, size_t off) {
|
|
102
105
|
const char *p, *pe;
|
|
103
106
|
int cs = parser->cs;
|
|
104
107
|
|
|
@@ -108,11 +111,11 @@ size_t http_parser_execute(http_parser *parser, const char *buffer, size_t len,
|
|
|
108
111
|
pe = buffer+len;
|
|
109
112
|
|
|
110
113
|
/* assert(*pe == '\0' && "pointer does not end on NUL"); */
|
|
111
|
-
assert(pe - p == len - off && "pointers aren't same distance");
|
|
114
|
+
assert((size_t) (pe - p) == len - off && "pointers aren't same distance");
|
|
112
115
|
|
|
113
116
|
%% write exec;
|
|
114
117
|
|
|
115
|
-
if (!
|
|
118
|
+
if (!puma_parser_has_error(parser))
|
|
116
119
|
parser->cs = cs;
|
|
117
120
|
parser->nread += p - (buffer + off);
|
|
118
121
|
|
|
@@ -126,21 +129,21 @@ size_t http_parser_execute(http_parser *parser, const char *buffer, size_t len,
|
|
|
126
129
|
return(parser->nread);
|
|
127
130
|
}
|
|
128
131
|
|
|
129
|
-
int
|
|
132
|
+
int puma_parser_finish(puma_parser *parser)
|
|
130
133
|
{
|
|
131
|
-
if (
|
|
134
|
+
if (puma_parser_has_error(parser) ) {
|
|
132
135
|
return -1;
|
|
133
|
-
} else if (
|
|
136
|
+
} else if (puma_parser_is_finished(parser) ) {
|
|
134
137
|
return 1;
|
|
135
138
|
} else {
|
|
136
139
|
return 0;
|
|
137
140
|
}
|
|
138
141
|
}
|
|
139
142
|
|
|
140
|
-
int
|
|
141
|
-
return parser->cs ==
|
|
143
|
+
int puma_parser_has_error(puma_parser *parser) {
|
|
144
|
+
return parser->cs == puma_parser_error;
|
|
142
145
|
}
|
|
143
146
|
|
|
144
|
-
int
|
|
145
|
-
return parser->cs >=
|
|
147
|
+
int puma_parser_is_finished(puma_parser *parser) {
|
|
148
|
+
return parser->cs >= puma_parser_first_final;
|
|
146
149
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
%%{
|
|
2
|
-
|
|
3
|
-
machine
|
|
2
|
+
|
|
3
|
+
machine puma_parser_common;
|
|
4
4
|
|
|
5
5
|
#### HTTP PROTOCOL GRAMMAR
|
|
6
6
|
# line endings
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
national = any -- (alpha | digit | reserved | extra | safe | unsafe);
|
|
16
16
|
unreserved = (alpha | digit | safe | extra | national);
|
|
17
17
|
escape = ("%" xdigit xdigit);
|
|
18
|
-
uchar = (unreserved | escape);
|
|
19
|
-
pchar = (uchar | ":" | "@" | "&" | "=" | "+");
|
|
18
|
+
uchar = (unreserved | escape | "%");
|
|
19
|
+
pchar = (uchar | ":" | "@" | "&" | "=" | "+" | ";");
|
|
20
20
|
tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t");
|
|
21
21
|
|
|
22
22
|
# elements
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
query = ( uchar | reserved )* %query_string ;
|
|
31
31
|
param = ( pchar | "/" )* ;
|
|
32
32
|
params = ( param ( ";" param )* ) ;
|
|
33
|
-
rel_path = ( path? %request_path
|
|
33
|
+
rel_path = ( path? %request_path ) ("?" %start_query query)?;
|
|
34
34
|
absolute_path = ( "/"+ rel_path );
|
|
35
35
|
|
|
36
36
|
Request_URI = ( "*" | absolute_uri | absolute_path ) >mark %request_uri;
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
Method = ( upper | digit | safe ){1,20} >mark %request_method;
|
|
39
39
|
|
|
40
40
|
http_number = ( digit+ "." digit+ ) ;
|
|
41
|
-
|
|
42
|
-
Request_Line = ( Method " " Request_URI ("#" Fragment){0,1} " "
|
|
41
|
+
Server_Protocol = ( "HTTP/" http_number ) >mark %server_protocol ;
|
|
42
|
+
Request_Line = ( Method " " Request_URI ("#" Fragment){0,1} " " Server_Protocol CRLF ) ;
|
|
43
43
|
|
|
44
44
|
field_name = ( token -- ":" )+ >start_field $snake_upcase_field %write_field;
|
|
45
45
|
|
|
46
|
-
field_value = any* >start_value %write_value;
|
|
46
|
+
field_value = ( (any -- CTL) | "\t" )* >start_value %write_value;
|
|
47
47
|
|
|
48
48
|
message_header = field_name ":" " "* field_value :> CRLF;
|
|
49
49
|
|