puma 2.1.1 → 7.2.1
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 +3273 -0
- data/LICENSE +23 -20
- data/README.md +388 -100
- data/bin/puma-wild +25 -0
- data/bin/pumactl +1 -1
- 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/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/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 +27 -43
- 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/Http11.java +145 -113
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +139 -172
- 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 +164 -769
- data/lib/puma/client.rb +591 -132
- 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 +370 -202
- data/lib/puma/const.rb +266 -115
- data/lib/puma/control_cli.rb +219 -120
- data/lib/puma/detect.rb +45 -2
- data/lib/puma/dsl.rb +1496 -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 +104 -0
- data/lib/puma/launcher.rb +502 -0
- data/lib/puma/log_writer.rb +147 -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/request.rb +703 -0
- data/lib/puma/runner.rb +211 -0
- data/lib/puma/sd_notify.rb +146 -0
- data/lib/puma/server.rb +544 -436
- data/lib/puma/single.rb +72 -0
- data/lib/puma/state_file.rb +69 -0
- data/lib/puma/thread_pool.rb +282 -56
- 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 +77 -148
- data/COPYING +0 -55
- data/Gemfile +0 -10
- data/History.txt +0 -291
- data/Manifest.txt +0 -60
- data/Rakefile +0 -121
- 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 -207
- 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,7 @@
|
|
|
1
1
|
package org.jruby.puma;
|
|
2
2
|
|
|
3
|
+
import org.jruby.Ruby;
|
|
4
|
+
import org.jruby.RubyHash;
|
|
3
5
|
import org.jruby.util.ByteList;
|
|
4
6
|
|
|
5
7
|
public class Http11Parser {
|
|
@@ -7,8 +9,8 @@ public class Http11Parser {
|
|
|
7
9
|
/** Machine **/
|
|
8
10
|
|
|
9
11
|
%%{
|
|
10
|
-
|
|
11
|
-
machine
|
|
12
|
+
|
|
13
|
+
machine puma_parser;
|
|
12
14
|
|
|
13
15
|
action mark {parser.mark = fpc; }
|
|
14
16
|
|
|
@@ -19,60 +21,51 @@ public class Http11Parser {
|
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
action start_value { parser.mark = fpc; }
|
|
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 write_value {
|
|
25
|
+
Http11.http_field(runtime, parser.data, parser.buffer, parser.field_start, parser.field_len, parser.mark, fpc-parser.mark);
|
|
26
26
|
}
|
|
27
|
-
action request_method {
|
|
28
|
-
|
|
29
|
-
parser.request_method.call(parser.data, parser.mark, fpc-parser.mark);
|
|
27
|
+
action request_method {
|
|
28
|
+
Http11.request_method(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
|
|
30
29
|
}
|
|
31
|
-
action request_uri {
|
|
32
|
-
|
|
33
|
-
parser.request_uri.call(parser.data, parser.mark, fpc-parser.mark);
|
|
30
|
+
action request_uri {
|
|
31
|
+
Http11.request_uri(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
|
|
34
32
|
}
|
|
35
|
-
action fragment {
|
|
36
|
-
|
|
37
|
-
parser.fragment.call(parser.data, parser.mark, fpc-parser.mark);
|
|
33
|
+
action fragment {
|
|
34
|
+
Http11.fragment(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
|
|
38
35
|
}
|
|
39
36
|
|
|
40
37
|
action start_query {parser.query_start = fpc; }
|
|
41
|
-
action query_string {
|
|
42
|
-
|
|
43
|
-
parser.query_string.call(parser.data, parser.query_start, fpc-parser.query_start);
|
|
38
|
+
action query_string {
|
|
39
|
+
Http11.query_string(runtime, parser.data, parser.buffer, parser.query_start, fpc-parser.query_start);
|
|
44
40
|
}
|
|
45
41
|
|
|
46
|
-
action
|
|
47
|
-
|
|
48
|
-
parser.http_version.call(parser.data, parser.mark, fpc-parser.mark);
|
|
42
|
+
action server_protocol {
|
|
43
|
+
Http11.server_protocol(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
|
|
49
44
|
}
|
|
50
45
|
|
|
51
46
|
action request_path {
|
|
52
|
-
|
|
53
|
-
parser.request_path.call(parser.data, parser.mark, fpc-parser.mark);
|
|
47
|
+
Http11.request_path(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
|
|
54
48
|
}
|
|
55
49
|
|
|
56
50
|
action done {
|
|
57
|
-
parser.body_start = fpc + 1;
|
|
58
|
-
|
|
59
|
-
parser.header_done.call(parser.data, fpc + 1, pe - fpc - 1);
|
|
51
|
+
parser.body_start = fpc + 1;
|
|
52
|
+
http.header_done(runtime, parser.data, parser.buffer, fpc + 1, pe - fpc - 1);
|
|
60
53
|
fbreak;
|
|
61
54
|
}
|
|
62
55
|
|
|
63
|
-
include
|
|
56
|
+
include puma_parser_common "http11_parser_common.rl";
|
|
64
57
|
|
|
65
58
|
}%%
|
|
66
59
|
|
|
67
60
|
/** Data **/
|
|
68
|
-
%% write data;
|
|
61
|
+
%% write data noentry;
|
|
69
62
|
|
|
70
63
|
public static interface ElementCB {
|
|
71
|
-
public void call(
|
|
64
|
+
public void call(Ruby runtime, RubyHash data, ByteList buffer, int at, int length);
|
|
72
65
|
}
|
|
73
66
|
|
|
74
67
|
public static interface FieldCB {
|
|
75
|
-
public void call(
|
|
68
|
+
public void call(Ruby runtime, RubyHash data, ByteList buffer, int field, int flen, int value, int vlen);
|
|
76
69
|
}
|
|
77
70
|
|
|
78
71
|
public static class HttpParser {
|
|
@@ -85,18 +78,9 @@ public class Http11Parser {
|
|
|
85
78
|
int field_len;
|
|
86
79
|
int query_start;
|
|
87
80
|
|
|
88
|
-
|
|
81
|
+
RubyHash data;
|
|
89
82
|
ByteList buffer;
|
|
90
83
|
|
|
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
84
|
public void init() {
|
|
101
85
|
cs = 0;
|
|
102
86
|
|
|
@@ -113,7 +97,7 @@ public class Http11Parser {
|
|
|
113
97
|
|
|
114
98
|
public final HttpParser parser = new HttpParser();
|
|
115
99
|
|
|
116
|
-
public int execute(ByteList buffer, int off) {
|
|
100
|
+
public int execute(Ruby runtime, Http11 http, ByteList buffer, int off) {
|
|
117
101
|
int p, pe;
|
|
118
102
|
int cs = parser.cs;
|
|
119
103
|
int len = buffer.length();
|
|
@@ -152,10 +136,10 @@ public class Http11Parser {
|
|
|
152
136
|
}
|
|
153
137
|
|
|
154
138
|
public boolean has_error() {
|
|
155
|
-
return parser.cs ==
|
|
139
|
+
return parser.cs == puma_parser_error;
|
|
156
140
|
}
|
|
157
141
|
|
|
158
142
|
public boolean is_finished() {
|
|
159
|
-
return parser.cs ==
|
|
143
|
+
return parser.cs == puma_parser_first_final;
|
|
160
144
|
}
|
|
161
145
|
}
|
|
@@ -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
|
|