puma 4.3.0

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.

Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/History.md +1532 -0
  3. data/LICENSE +26 -0
  4. data/README.md +291 -0
  5. data/bin/puma +10 -0
  6. data/bin/puma-wild +31 -0
  7. data/bin/pumactl +12 -0
  8. data/docs/architecture.md +37 -0
  9. data/docs/deployment.md +111 -0
  10. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  11. data/docs/images/puma-connection-flow.png +0 -0
  12. data/docs/images/puma-general-arch.png +0 -0
  13. data/docs/nginx.md +80 -0
  14. data/docs/plugins.md +38 -0
  15. data/docs/restart.md +41 -0
  16. data/docs/signals.md +96 -0
  17. data/docs/systemd.md +290 -0
  18. data/docs/tcp_mode.md +96 -0
  19. data/ext/puma_http11/PumaHttp11Service.java +19 -0
  20. data/ext/puma_http11/ext_help.h +15 -0
  21. data/ext/puma_http11/extconf.rb +28 -0
  22. data/ext/puma_http11/http11_parser.c +1044 -0
  23. data/ext/puma_http11/http11_parser.h +65 -0
  24. data/ext/puma_http11/http11_parser.java.rl +145 -0
  25. data/ext/puma_http11/http11_parser.rl +147 -0
  26. data/ext/puma_http11/http11_parser_common.rl +54 -0
  27. data/ext/puma_http11/io_buffer.c +155 -0
  28. data/ext/puma_http11/mini_ssl.c +553 -0
  29. data/ext/puma_http11/org/jruby/puma/Http11.java +226 -0
  30. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +455 -0
  31. data/ext/puma_http11/org/jruby/puma/IOBuffer.java +72 -0
  32. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +363 -0
  33. data/ext/puma_http11/puma_http11.c +502 -0
  34. data/lib/puma.rb +31 -0
  35. data/lib/puma/accept_nonblock.rb +29 -0
  36. data/lib/puma/app/status.rb +80 -0
  37. data/lib/puma/binder.rb +385 -0
  38. data/lib/puma/cli.rb +239 -0
  39. data/lib/puma/client.rb +494 -0
  40. data/lib/puma/cluster.rb +554 -0
  41. data/lib/puma/commonlogger.rb +108 -0
  42. data/lib/puma/configuration.rb +362 -0
  43. data/lib/puma/const.rb +235 -0
  44. data/lib/puma/control_cli.rb +289 -0
  45. data/lib/puma/detect.rb +15 -0
  46. data/lib/puma/dsl.rb +740 -0
  47. data/lib/puma/events.rb +156 -0
  48. data/lib/puma/io_buffer.rb +4 -0
  49. data/lib/puma/jruby_restart.rb +84 -0
  50. data/lib/puma/launcher.rb +475 -0
  51. data/lib/puma/minissl.rb +278 -0
  52. data/lib/puma/minissl/context_builder.rb +76 -0
  53. data/lib/puma/null_io.rb +44 -0
  54. data/lib/puma/plugin.rb +120 -0
  55. data/lib/puma/plugin/tmp_restart.rb +36 -0
  56. data/lib/puma/rack/builder.rb +301 -0
  57. data/lib/puma/rack/urlmap.rb +93 -0
  58. data/lib/puma/rack_default.rb +9 -0
  59. data/lib/puma/reactor.rb +400 -0
  60. data/lib/puma/runner.rb +192 -0
  61. data/lib/puma/server.rb +1030 -0
  62. data/lib/puma/single.rb +123 -0
  63. data/lib/puma/state_file.rb +31 -0
  64. data/lib/puma/tcp_logger.rb +41 -0
  65. data/lib/puma/thread_pool.rb +328 -0
  66. data/lib/puma/util.rb +124 -0
  67. data/lib/rack/handler/puma.rb +115 -0
  68. data/tools/docker/Dockerfile +16 -0
  69. data/tools/jungle/README.md +19 -0
  70. data/tools/jungle/init.d/README.md +61 -0
  71. data/tools/jungle/init.d/puma +421 -0
  72. data/tools/jungle/init.d/run-puma +18 -0
  73. data/tools/jungle/rc.d/README.md +74 -0
  74. data/tools/jungle/rc.d/puma +61 -0
  75. data/tools/jungle/rc.d/puma.conf +10 -0
  76. data/tools/jungle/upstart/README.md +61 -0
  77. data/tools/jungle/upstart/puma-manager.conf +31 -0
  78. data/tools/jungle/upstart/puma.conf +69 -0
  79. data/tools/trickletest.rb +44 -0
  80. metadata +144 -0
@@ -0,0 +1,226 @@
1
+ package org.jruby.puma;
2
+
3
+ import org.jruby.Ruby;
4
+ import org.jruby.RubyClass;
5
+ import org.jruby.RubyHash;
6
+ import org.jruby.RubyModule;
7
+ import org.jruby.RubyNumeric;
8
+ import org.jruby.RubyObject;
9
+ import org.jruby.RubyString;
10
+
11
+ import org.jruby.anno.JRubyMethod;
12
+
13
+ import org.jruby.runtime.ObjectAllocator;
14
+ import org.jruby.runtime.builtin.IRubyObject;
15
+
16
+ import org.jruby.exceptions.RaiseException;
17
+
18
+ import org.jruby.util.ByteList;
19
+
20
+ /**
21
+ * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
22
+ * @author <a href="mailto:headius@headius.com">Charles Oliver Nutter</a>
23
+ */
24
+ public class Http11 extends RubyObject {
25
+ public final static int MAX_FIELD_NAME_LENGTH = 256;
26
+ public final static String MAX_FIELD_NAME_LENGTH_ERR = "HTTP element FIELD_NAME is longer than the 256 allowed length.";
27
+ public final static int MAX_FIELD_VALUE_LENGTH = 80 * 1024;
28
+ public final static String MAX_FIELD_VALUE_LENGTH_ERR = "HTTP element FIELD_VALUE is longer than the 81920 allowed length.";
29
+ public final static int MAX_REQUEST_URI_LENGTH = 1024 * 12;
30
+ public final static String MAX_REQUEST_URI_LENGTH_ERR = "HTTP element REQUEST_URI is longer than the 12288 allowed length.";
31
+ public final static int MAX_FRAGMENT_LENGTH = 1024;
32
+ public final static String MAX_FRAGMENT_LENGTH_ERR = "HTTP element REQUEST_PATH is longer than the 1024 allowed length.";
33
+ public final static int MAX_REQUEST_PATH_LENGTH = 2048;
34
+ public final static String MAX_REQUEST_PATH_LENGTH_ERR = "HTTP element REQUEST_PATH is longer than the 2048 allowed length.";
35
+ public final static int MAX_QUERY_STRING_LENGTH = 1024 * 10;
36
+ public final static String MAX_QUERY_STRING_LENGTH_ERR = "HTTP element QUERY_STRING is longer than the 10240 allowed length.";
37
+ public final static int MAX_HEADER_LENGTH = 1024 * (80 + 32);
38
+ public final static String MAX_HEADER_LENGTH_ERR = "HTTP element HEADER is longer than the 114688 allowed length.";
39
+
40
+ public static final ByteList CONTENT_TYPE_BYTELIST = new ByteList(ByteList.plain("CONTENT_TYPE"));
41
+ public static final ByteList CONTENT_LENGTH_BYTELIST = new ByteList(ByteList.plain("CONTENT_LENGTH"));
42
+ public static final ByteList HTTP_PREFIX_BYTELIST = new ByteList(ByteList.plain("HTTP_"));
43
+ public static final ByteList COMMA_SPACE_BYTELIST = new ByteList(ByteList.plain(", "));
44
+ public static final ByteList REQUEST_METHOD_BYTELIST = new ByteList(ByteList.plain("REQUEST_METHOD"));
45
+ public static final ByteList REQUEST_URI_BYTELIST = new ByteList(ByteList.plain("REQUEST_URI"));
46
+ public static final ByteList FRAGMENT_BYTELIST = new ByteList(ByteList.plain("FRAGMENT"));
47
+ public static final ByteList REQUEST_PATH_BYTELIST = new ByteList(ByteList.plain("REQUEST_PATH"));
48
+ public static final ByteList QUERY_STRING_BYTELIST = new ByteList(ByteList.plain("QUERY_STRING"));
49
+ public static final ByteList HTTP_VERSION_BYTELIST = new ByteList(ByteList.plain("HTTP_VERSION"));
50
+
51
+ private static ObjectAllocator ALLOCATOR = new ObjectAllocator() {
52
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
53
+ return new Http11(runtime, klass);
54
+ }
55
+ };
56
+
57
+ public static void createHttp11(Ruby runtime) {
58
+ RubyModule mPuma = runtime.defineModule("Puma");
59
+ mPuma.defineClassUnder("HttpParserError",runtime.getClass("IOError"),runtime.getClass("IOError").getAllocator());
60
+
61
+ RubyClass cHttpParser = mPuma.defineClassUnder("HttpParser",runtime.getObject(),ALLOCATOR);
62
+ cHttpParser.defineAnnotatedMethods(Http11.class);
63
+ }
64
+
65
+ private Ruby runtime;
66
+ private Http11Parser hp;
67
+ private RubyString body;
68
+
69
+ public Http11(Ruby runtime, RubyClass clazz) {
70
+ super(runtime,clazz);
71
+ this.runtime = runtime;
72
+ this.hp = new Http11Parser();
73
+ this.hp.parser.init();
74
+ }
75
+
76
+ public static void validateMaxLength(Ruby runtime, int len, int max, String msg) {
77
+ if(len>max) {
78
+ throw newHTTPParserError(runtime, msg);
79
+ }
80
+ }
81
+
82
+ private static RaiseException newHTTPParserError(Ruby runtime, String msg) {
83
+ return runtime.newRaiseException(getHTTPParserError(runtime), msg);
84
+ }
85
+
86
+ private static RubyClass getHTTPParserError(Ruby runtime) {
87
+ // Cheaper to look this up lazily than cache eagerly and consume a field, since it's rarely encountered
88
+ return (RubyClass)runtime.getModule("Puma").getConstant("HttpParserError");
89
+ }
90
+
91
+ public static void http_field(Ruby runtime, RubyHash req, ByteList buffer, int field, int flen, int value, int vlen) {
92
+ RubyString f;
93
+ IRubyObject v;
94
+ validateMaxLength(runtime, flen, MAX_FIELD_NAME_LENGTH, MAX_FIELD_NAME_LENGTH_ERR);
95
+ validateMaxLength(runtime, vlen, MAX_FIELD_VALUE_LENGTH, MAX_FIELD_VALUE_LENGTH_ERR);
96
+
97
+ ByteList b = new ByteList(buffer,field,flen);
98
+ for(int i = 0,j = b.length();i<j;i++) {
99
+ int bite = b.get(i) & 0xFF;
100
+ if(bite == '-') {
101
+ b.set(i, (byte)'_');
102
+ } else {
103
+ b.set(i, (byte)Character.toUpperCase(bite));
104
+ }
105
+ }
106
+
107
+ while (vlen > 0 && Character.isWhitespace(buffer.get(value + vlen - 1))) vlen--;
108
+
109
+ if (b.equals(CONTENT_LENGTH_BYTELIST) || b.equals(CONTENT_TYPE_BYTELIST)) {
110
+ f = RubyString.newString(runtime, b);
111
+ } else {
112
+ f = RubyString.newStringShared(runtime, HTTP_PREFIX_BYTELIST);
113
+ f.cat(b);
114
+ }
115
+
116
+ b = new ByteList(buffer, value, vlen);
117
+ v = req.fastARef(f);
118
+ if (v == null || v.isNil()) {
119
+ req.fastASet(f, RubyString.newString(runtime, b));
120
+ } else {
121
+ RubyString vs = v.convertToString();
122
+ vs.cat(COMMA_SPACE_BYTELIST);
123
+ vs.cat(b);
124
+ }
125
+ }
126
+
127
+ public static void request_method(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) {
128
+ RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length));
129
+ req.fastASet(RubyString.newStringShared(runtime, REQUEST_METHOD_BYTELIST),val);
130
+ }
131
+
132
+ public static void request_uri(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) {
133
+ validateMaxLength(runtime, length, MAX_REQUEST_URI_LENGTH, MAX_REQUEST_URI_LENGTH_ERR);
134
+ RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length));
135
+ req.fastASet(RubyString.newStringShared(runtime, REQUEST_URI_BYTELIST),val);
136
+ }
137
+
138
+ public static void fragment(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) {
139
+ validateMaxLength(runtime, length, MAX_FRAGMENT_LENGTH, MAX_FRAGMENT_LENGTH_ERR);
140
+ RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length));
141
+ req.fastASet(RubyString.newStringShared(runtime, FRAGMENT_BYTELIST),val);
142
+ }
143
+
144
+ public static void request_path(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) {
145
+ validateMaxLength(runtime, length, MAX_REQUEST_PATH_LENGTH, MAX_REQUEST_PATH_LENGTH_ERR);
146
+ RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length));
147
+ req.fastASet(RubyString.newStringShared(runtime, REQUEST_PATH_BYTELIST),val);
148
+ }
149
+
150
+ public static void query_string(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) {
151
+ validateMaxLength(runtime, length, MAX_QUERY_STRING_LENGTH, MAX_QUERY_STRING_LENGTH_ERR);
152
+ RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length));
153
+ req.fastASet(RubyString.newStringShared(runtime, QUERY_STRING_BYTELIST),val);
154
+ }
155
+
156
+ public static void http_version(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) {
157
+ RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length));
158
+ req.fastASet(RubyString.newStringShared(runtime, HTTP_VERSION_BYTELIST),val);
159
+ }
160
+
161
+ public void header_done(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) {
162
+ body = RubyString.newStringShared(runtime, new ByteList(buffer, at, length));
163
+ }
164
+
165
+ @JRubyMethod
166
+ public IRubyObject initialize() {
167
+ this.hp.parser.init();
168
+ return this;
169
+ }
170
+
171
+ @JRubyMethod
172
+ public IRubyObject reset() {
173
+ this.hp.parser.init();
174
+ return runtime.getNil();
175
+ }
176
+
177
+ @JRubyMethod
178
+ public IRubyObject finish() {
179
+ this.hp.finish();
180
+ return this.hp.is_finished() ? runtime.getTrue() : runtime.getFalse();
181
+ }
182
+
183
+ @JRubyMethod
184
+ public IRubyObject execute(IRubyObject req_hash, IRubyObject data, IRubyObject start) {
185
+ int from = RubyNumeric.fix2int(start);
186
+ ByteList d = ((RubyString)data).getByteList();
187
+ if(from >= d.length()) {
188
+ throw newHTTPParserError(runtime, "Requested start is after data buffer end.");
189
+ } else {
190
+ Http11Parser hp = this.hp;
191
+ Http11Parser.HttpParser parser = hp.parser;
192
+
193
+ parser.data = (RubyHash) req_hash;
194
+
195
+ hp.execute(runtime, this, d,from);
196
+
197
+ validateMaxLength(runtime, parser.nread,MAX_HEADER_LENGTH, MAX_HEADER_LENGTH_ERR);
198
+
199
+ if(hp.has_error()) {
200
+ throw newHTTPParserError(runtime, "Invalid HTTP format, parsing fails.");
201
+ } else {
202
+ return runtime.newFixnum(parser.nread);
203
+ }
204
+ }
205
+ }
206
+
207
+ @JRubyMethod(name = "error?")
208
+ public IRubyObject has_error() {
209
+ return this.hp.has_error() ? runtime.getTrue() : runtime.getFalse();
210
+ }
211
+
212
+ @JRubyMethod(name = "finished?")
213
+ public IRubyObject is_finished() {
214
+ return this.hp.is_finished() ? runtime.getTrue() : runtime.getFalse();
215
+ }
216
+
217
+ @JRubyMethod
218
+ public IRubyObject nread() {
219
+ return runtime.newFixnum(this.hp.parser.nread);
220
+ }
221
+
222
+ @JRubyMethod
223
+ public IRubyObject body() {
224
+ return body;
225
+ }
226
+ }// Http11
@@ -0,0 +1,455 @@
1
+
2
+ // line 1 "ext/puma_http11/http11_parser.java.rl"
3
+ package org.jruby.puma;
4
+
5
+ import org.jruby.Ruby;
6
+ import org.jruby.RubyHash;
7
+ import org.jruby.util.ByteList;
8
+
9
+ public class Http11Parser {
10
+
11
+ /** Machine **/
12
+
13
+
14
+ // line 58 "ext/puma_http11/http11_parser.java.rl"
15
+
16
+
17
+ /** Data **/
18
+
19
+ // line 20 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
20
+ private static byte[] init__puma_parser_actions_0()
21
+ {
22
+ return new byte [] {
23
+ 0, 1, 0, 1, 2, 1, 3, 1, 4, 1, 5, 1,
24
+ 6, 1, 7, 1, 8, 1, 9, 1, 11, 1, 12, 1,
25
+ 13, 2, 0, 8, 2, 1, 2, 2, 4, 5, 2, 10,
26
+ 7, 2, 12, 7, 3, 9, 10, 7
27
+ };
28
+ }
29
+
30
+ private static final byte _puma_parser_actions[] = init__puma_parser_actions_0();
31
+
32
+
33
+ private static short[] init__puma_parser_key_offsets_0()
34
+ {
35
+ return new short [] {
36
+ 0, 0, 8, 17, 27, 29, 30, 31, 32, 33, 34, 36,
37
+ 39, 41, 44, 45, 61, 62, 78, 80, 81, 89, 97, 107,
38
+ 115, 124, 132, 140, 149, 158, 167, 176, 185, 194, 203, 212,
39
+ 221, 230, 239, 248, 257, 266, 275, 284, 293, 302, 303
40
+ };
41
+ }
42
+
43
+ private static final short _puma_parser_key_offsets[] = init__puma_parser_key_offsets_0();
44
+
45
+
46
+ private static char[] init__puma_parser_trans_keys_0()
47
+ {
48
+ return new char [] {
49
+ 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
50
+ 46, 48, 57, 65, 90, 42, 43, 47, 58, 45, 57, 65,
51
+ 90, 97, 122, 32, 35, 72, 84, 84, 80, 47, 48, 57,
52
+ 46, 48, 57, 48, 57, 13, 48, 57, 10, 13, 33, 124,
53
+ 126, 35, 39, 42, 43, 45, 46, 48, 57, 65, 90, 94,
54
+ 122, 10, 33, 58, 124, 126, 35, 39, 42, 43, 45, 46,
55
+ 48, 57, 65, 90, 94, 122, 13, 32, 13, 32, 60, 62,
56
+ 127, 0, 31, 34, 35, 32, 60, 62, 127, 0, 31, 34,
57
+ 35, 43, 58, 45, 46, 48, 57, 65, 90, 97, 122, 32,
58
+ 34, 35, 60, 62, 127, 0, 31, 32, 34, 35, 60, 62,
59
+ 63, 127, 0, 31, 32, 34, 35, 60, 62, 127, 0, 31,
60
+ 32, 34, 35, 60, 62, 127, 0, 31, 32, 36, 95, 45,
61
+ 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
62
+ 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
63
+ 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
64
+ 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
65
+ 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
66
+ 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
67
+ 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
68
+ 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
69
+ 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
70
+ 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
71
+ 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
72
+ 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
73
+ 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
74
+ 65, 90, 32, 0
75
+ };
76
+ }
77
+
78
+ private static final char _puma_parser_trans_keys[] = init__puma_parser_trans_keys_0();
79
+
80
+
81
+ private static byte[] init__puma_parser_single_lengths_0()
82
+ {
83
+ return new byte [] {
84
+ 0, 2, 3, 4, 2, 1, 1, 1, 1, 1, 0, 1,
85
+ 0, 1, 1, 4, 1, 4, 2, 1, 4, 4, 2, 6,
86
+ 7, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3,
87
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0
88
+ };
89
+ }
90
+
91
+ private static final byte _puma_parser_single_lengths[] = init__puma_parser_single_lengths_0();
92
+
93
+
94
+ private static byte[] init__puma_parser_range_lengths_0()
95
+ {
96
+ return new byte [] {
97
+ 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 1,
98
+ 1, 1, 0, 6, 0, 6, 0, 0, 2, 2, 4, 1,
99
+ 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
100
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0
101
+ };
102
+ }
103
+
104
+ private static final byte _puma_parser_range_lengths[] = init__puma_parser_range_lengths_0();
105
+
106
+
107
+ private static short[] init__puma_parser_index_offsets_0()
108
+ {
109
+ return new short [] {
110
+ 0, 0, 6, 13, 21, 24, 26, 28, 30, 32, 34, 36,
111
+ 39, 41, 44, 46, 57, 59, 70, 73, 75, 82, 89, 96,
112
+ 104, 113, 121, 129, 136, 143, 150, 157, 164, 171, 178, 185,
113
+ 192, 199, 206, 213, 220, 227, 234, 241, 248, 255, 257
114
+ };
115
+ }
116
+
117
+ private static final short _puma_parser_index_offsets[] = init__puma_parser_index_offsets_0();
118
+
119
+
120
+ private static byte[] init__puma_parser_indicies_0()
121
+ {
122
+ return new byte [] {
123
+ 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3,
124
+ 1, 4, 5, 6, 7, 5, 5, 5, 1, 8, 9, 1,
125
+ 10, 1, 11, 1, 12, 1, 13, 1, 14, 1, 15, 1,
126
+ 16, 15, 1, 17, 1, 18, 17, 1, 19, 1, 20, 21,
127
+ 21, 21, 21, 21, 21, 21, 21, 21, 1, 22, 1, 23,
128
+ 24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27,
129
+ 25, 29, 28, 30, 1, 1, 1, 1, 1, 31, 32, 1,
130
+ 1, 1, 1, 1, 33, 34, 35, 34, 34, 34, 34, 1,
131
+ 8, 1, 9, 1, 1, 1, 1, 35, 36, 1, 38, 1,
132
+ 1, 39, 1, 1, 37, 40, 1, 42, 1, 1, 1, 1,
133
+ 41, 43, 1, 45, 1, 1, 1, 1, 44, 2, 46, 46,
134
+ 46, 46, 46, 1, 2, 47, 47, 47, 47, 47, 1, 2,
135
+ 48, 48, 48, 48, 48, 1, 2, 49, 49, 49, 49, 49,
136
+ 1, 2, 50, 50, 50, 50, 50, 1, 2, 51, 51, 51,
137
+ 51, 51, 1, 2, 52, 52, 52, 52, 52, 1, 2, 53,
138
+ 53, 53, 53, 53, 1, 2, 54, 54, 54, 54, 54, 1,
139
+ 2, 55, 55, 55, 55, 55, 1, 2, 56, 56, 56, 56,
140
+ 56, 1, 2, 57, 57, 57, 57, 57, 1, 2, 58, 58,
141
+ 58, 58, 58, 1, 2, 59, 59, 59, 59, 59, 1, 2,
142
+ 60, 60, 60, 60, 60, 1, 2, 61, 61, 61, 61, 61,
143
+ 1, 2, 62, 62, 62, 62, 62, 1, 2, 63, 63, 63,
144
+ 63, 63, 1, 2, 1, 1, 0
145
+ };
146
+ }
147
+
148
+ private static final byte _puma_parser_indicies[] = init__puma_parser_indicies_0();
149
+
150
+
151
+ private static byte[] init__puma_parser_trans_targs_0()
152
+ {
153
+ return new byte [] {
154
+ 2, 0, 3, 27, 4, 22, 24, 23, 5, 20, 6, 7,
155
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 46, 17,
156
+ 18, 19, 14, 18, 19, 14, 5, 21, 5, 21, 22, 23,
157
+ 5, 24, 20, 25, 5, 26, 20, 5, 26, 20, 28, 29,
158
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
159
+ 42, 43, 44, 45
160
+ };
161
+ }
162
+
163
+ private static final byte _puma_parser_trans_targs[] = init__puma_parser_trans_targs_0();
164
+
165
+
166
+ private static byte[] init__puma_parser_trans_actions_0()
167
+ {
168
+ return new byte [] {
169
+ 1, 0, 11, 0, 1, 1, 1, 1, 13, 13, 1, 0,
170
+ 0, 0, 0, 0, 0, 0, 19, 0, 0, 28, 23, 3,
171
+ 5, 7, 31, 7, 0, 9, 25, 1, 15, 0, 0, 0,
172
+ 37, 0, 37, 21, 40, 17, 40, 34, 0, 34, 0, 0,
173
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
174
+ 0, 0, 0, 0
175
+ };
176
+ }
177
+
178
+ private static final byte _puma_parser_trans_actions[] = init__puma_parser_trans_actions_0();
179
+
180
+
181
+ static final int puma_parser_start = 1;
182
+ static final int puma_parser_first_final = 46;
183
+ static final int puma_parser_error = 0;
184
+
185
+ static final int puma_parser_en_main = 1;
186
+
187
+
188
+ // line 62 "ext/puma_http11/http11_parser.java.rl"
189
+
190
+ public static interface ElementCB {
191
+ public void call(Ruby runtime, RubyHash data, ByteList buffer, int at, int length);
192
+ }
193
+
194
+ public static interface FieldCB {
195
+ public void call(Ruby runtime, RubyHash data, ByteList buffer, int field, int flen, int value, int vlen);
196
+ }
197
+
198
+ public static class HttpParser {
199
+ int cs;
200
+ int body_start;
201
+ int content_len;
202
+ int nread;
203
+ int mark;
204
+ int field_start;
205
+ int field_len;
206
+ int query_start;
207
+
208
+ RubyHash data;
209
+ ByteList buffer;
210
+
211
+ public void init() {
212
+ cs = 0;
213
+
214
+
215
+ // line 218 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
216
+ {
217
+ cs = puma_parser_start;
218
+ }
219
+
220
+ // line 90 "ext/puma_http11/http11_parser.java.rl"
221
+
222
+ body_start = 0;
223
+ content_len = 0;
224
+ mark = 0;
225
+ nread = 0;
226
+ field_len = 0;
227
+ field_start = 0;
228
+ }
229
+ }
230
+
231
+ public final HttpParser parser = new HttpParser();
232
+
233
+ public int execute(Ruby runtime, Http11 http, ByteList buffer, int off) {
234
+ int p, pe;
235
+ int cs = parser.cs;
236
+ int len = buffer.length();
237
+ assert off<=len : "offset past end of buffer";
238
+
239
+ p = off;
240
+ pe = len;
241
+ // get a copy of the bytes, since it may not start at 0
242
+ // FIXME: figure out how to just use the bytes in-place
243
+ byte[] data = buffer.bytes();
244
+ parser.buffer = buffer;
245
+
246
+
247
+ // line 250 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
248
+ {
249
+ int _klen;
250
+ int _trans = 0;
251
+ int _acts;
252
+ int _nacts;
253
+ int _keys;
254
+ int _goto_targ = 0;
255
+
256
+ _goto: while (true) {
257
+ switch ( _goto_targ ) {
258
+ case 0:
259
+ if ( p == pe ) {
260
+ _goto_targ = 4;
261
+ continue _goto;
262
+ }
263
+ if ( cs == 0 ) {
264
+ _goto_targ = 5;
265
+ continue _goto;
266
+ }
267
+ case 1:
268
+ _match: do {
269
+ _keys = _puma_parser_key_offsets[cs];
270
+ _trans = _puma_parser_index_offsets[cs];
271
+ _klen = _puma_parser_single_lengths[cs];
272
+ if ( _klen > 0 ) {
273
+ int _lower = _keys;
274
+ int _mid;
275
+ int _upper = _keys + _klen - 1;
276
+ while (true) {
277
+ if ( _upper < _lower )
278
+ break;
279
+
280
+ _mid = _lower + ((_upper-_lower) >> 1);
281
+ if ( data[p] < _puma_parser_trans_keys[_mid] )
282
+ _upper = _mid - 1;
283
+ else if ( data[p] > _puma_parser_trans_keys[_mid] )
284
+ _lower = _mid + 1;
285
+ else {
286
+ _trans += (_mid - _keys);
287
+ break _match;
288
+ }
289
+ }
290
+ _keys += _klen;
291
+ _trans += _klen;
292
+ }
293
+
294
+ _klen = _puma_parser_range_lengths[cs];
295
+ if ( _klen > 0 ) {
296
+ int _lower = _keys;
297
+ int _mid;
298
+ int _upper = _keys + (_klen<<1) - 2;
299
+ while (true) {
300
+ if ( _upper < _lower )
301
+ break;
302
+
303
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1);
304
+ if ( data[p] < _puma_parser_trans_keys[_mid] )
305
+ _upper = _mid - 2;
306
+ else if ( data[p] > _puma_parser_trans_keys[_mid+1] )
307
+ _lower = _mid + 2;
308
+ else {
309
+ _trans += ((_mid - _keys)>>1);
310
+ break _match;
311
+ }
312
+ }
313
+ _trans += _klen;
314
+ }
315
+ } while (false);
316
+
317
+ _trans = _puma_parser_indicies[_trans];
318
+ cs = _puma_parser_trans_targs[_trans];
319
+
320
+ if ( _puma_parser_trans_actions[_trans] != 0 ) {
321
+ _acts = _puma_parser_trans_actions[_trans];
322
+ _nacts = (int) _puma_parser_actions[_acts++];
323
+ while ( _nacts-- > 0 )
324
+ {
325
+ switch ( _puma_parser_actions[_acts++] )
326
+ {
327
+ case 0:
328
+ // line 15 "ext/puma_http11/http11_parser.java.rl"
329
+ {parser.mark = p; }
330
+ break;
331
+ case 1:
332
+ // line 17 "ext/puma_http11/http11_parser.java.rl"
333
+ { parser.field_start = p; }
334
+ break;
335
+ case 2:
336
+ // line 18 "ext/puma_http11/http11_parser.java.rl"
337
+ { /* FIXME stub */ }
338
+ break;
339
+ case 3:
340
+ // line 19 "ext/puma_http11/http11_parser.java.rl"
341
+ {
342
+ parser.field_len = p-parser.field_start;
343
+ }
344
+ break;
345
+ case 4:
346
+ // line 23 "ext/puma_http11/http11_parser.java.rl"
347
+ { parser.mark = p; }
348
+ break;
349
+ case 5:
350
+ // line 24 "ext/puma_http11/http11_parser.java.rl"
351
+ {
352
+ Http11.http_field(runtime, parser.data, parser.buffer, parser.field_start, parser.field_len, parser.mark, p-parser.mark);
353
+ }
354
+ break;
355
+ case 6:
356
+ // line 27 "ext/puma_http11/http11_parser.java.rl"
357
+ {
358
+ Http11.request_method(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
359
+ }
360
+ break;
361
+ case 7:
362
+ // line 30 "ext/puma_http11/http11_parser.java.rl"
363
+ {
364
+ Http11.request_uri(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
365
+ }
366
+ break;
367
+ case 8:
368
+ // line 33 "ext/puma_http11/http11_parser.java.rl"
369
+ {
370
+ Http11.fragment(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
371
+ }
372
+ break;
373
+ case 9:
374
+ // line 37 "ext/puma_http11/http11_parser.java.rl"
375
+ {parser.query_start = p; }
376
+ break;
377
+ case 10:
378
+ // line 38 "ext/puma_http11/http11_parser.java.rl"
379
+ {
380
+ Http11.query_string(runtime, parser.data, parser.buffer, parser.query_start, p-parser.query_start);
381
+ }
382
+ break;
383
+ case 11:
384
+ // line 42 "ext/puma_http11/http11_parser.java.rl"
385
+ {
386
+ Http11.http_version(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
387
+ }
388
+ break;
389
+ case 12:
390
+ // line 46 "ext/puma_http11/http11_parser.java.rl"
391
+ {
392
+ Http11.request_path(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
393
+ }
394
+ break;
395
+ case 13:
396
+ // line 50 "ext/puma_http11/http11_parser.java.rl"
397
+ {
398
+ parser.body_start = p + 1;
399
+ http.header_done(runtime, parser.data, parser.buffer, p + 1, pe - p - 1);
400
+ { p += 1; _goto_targ = 5; if (true) continue _goto;}
401
+ }
402
+ break;
403
+ // line 406 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
404
+ }
405
+ }
406
+ }
407
+
408
+ case 2:
409
+ if ( cs == 0 ) {
410
+ _goto_targ = 5;
411
+ continue _goto;
412
+ }
413
+ if ( ++p != pe ) {
414
+ _goto_targ = 1;
415
+ continue _goto;
416
+ }
417
+ case 4:
418
+ case 5:
419
+ }
420
+ break; }
421
+ }
422
+
423
+ // line 116 "ext/puma_http11/http11_parser.java.rl"
424
+
425
+ parser.cs = cs;
426
+ parser.nread += (p - off);
427
+
428
+ assert p <= pe : "buffer overflow after parsing execute";
429
+ assert parser.nread <= len : "nread longer than length";
430
+ assert parser.body_start <= len : "body starts after buffer end";
431
+ assert parser.mark < len : "mark is after buffer end";
432
+ assert parser.field_len <= len : "field has length longer than whole buffer";
433
+ assert parser.field_start < len : "field starts after buffer end";
434
+
435
+ return parser.nread;
436
+ }
437
+
438
+ public int finish() {
439
+ if(has_error()) {
440
+ return -1;
441
+ } else if(is_finished()) {
442
+ return 1;
443
+ } else {
444
+ return 0;
445
+ }
446
+ }
447
+
448
+ public boolean has_error() {
449
+ return parser.cs == puma_parser_error;
450
+ }
451
+
452
+ public boolean is_finished() {
453
+ return parser.cs == puma_parser_first_final;
454
+ }
455
+ }