wendell-puma 2.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +55 -0
  3. data/DEPLOYMENT.md +92 -0
  4. data/Gemfile +17 -0
  5. data/History.txt +588 -0
  6. data/LICENSE +26 -0
  7. data/Manifest.txt +68 -0
  8. data/README.md +251 -0
  9. data/Rakefile +158 -0
  10. data/bin/puma +10 -0
  11. data/bin/puma-wild +31 -0
  12. data/bin/pumactl +12 -0
  13. data/docs/config.md +0 -0
  14. data/docs/nginx.md +80 -0
  15. data/docs/signals.md +43 -0
  16. data/ext/puma_http11/PumaHttp11Service.java +17 -0
  17. data/ext/puma_http11/ext_help.h +15 -0
  18. data/ext/puma_http11/extconf.rb +9 -0
  19. data/ext/puma_http11/http11_parser.c +1225 -0
  20. data/ext/puma_http11/http11_parser.h +64 -0
  21. data/ext/puma_http11/http11_parser.java.rl +161 -0
  22. data/ext/puma_http11/http11_parser.rl +146 -0
  23. data/ext/puma_http11/http11_parser_common.rl +54 -0
  24. data/ext/puma_http11/io_buffer.c +155 -0
  25. data/ext/puma_http11/mini_ssl.c +198 -0
  26. data/ext/puma_http11/org/jruby/puma/Http11.java +225 -0
  27. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +488 -0
  28. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +391 -0
  29. data/ext/puma_http11/puma_http11.c +491 -0
  30. data/lib/puma.rb +14 -0
  31. data/lib/puma/accept_nonblock.rb +23 -0
  32. data/lib/puma/app/status.rb +59 -0
  33. data/lib/puma/binder.rb +298 -0
  34. data/lib/puma/capistrano.rb +86 -0
  35. data/lib/puma/cli.rb +606 -0
  36. data/lib/puma/client.rb +289 -0
  37. data/lib/puma/cluster.rb +404 -0
  38. data/lib/puma/compat.rb +18 -0
  39. data/lib/puma/configuration.rb +377 -0
  40. data/lib/puma/const.rb +165 -0
  41. data/lib/puma/control_cli.rb +251 -0
  42. data/lib/puma/daemon_ext.rb +25 -0
  43. data/lib/puma/delegation.rb +11 -0
  44. data/lib/puma/detect.rb +4 -0
  45. data/lib/puma/events.rb +130 -0
  46. data/lib/puma/io_buffer.rb +7 -0
  47. data/lib/puma/java_io_buffer.rb +45 -0
  48. data/lib/puma/jruby_restart.rb +83 -0
  49. data/lib/puma/minissl.rb +187 -0
  50. data/lib/puma/null_io.rb +34 -0
  51. data/lib/puma/rack_default.rb +7 -0
  52. data/lib/puma/rack_patch.rb +45 -0
  53. data/lib/puma/reactor.rb +183 -0
  54. data/lib/puma/runner.rb +146 -0
  55. data/lib/puma/server.rb +801 -0
  56. data/lib/puma/single.rb +102 -0
  57. data/lib/puma/tcp_logger.rb +32 -0
  58. data/lib/puma/thread_pool.rb +185 -0
  59. data/lib/puma/util.rb +9 -0
  60. data/lib/rack/handler/puma.rb +66 -0
  61. data/test/test_app_status.rb +92 -0
  62. data/test/test_cli.rb +173 -0
  63. data/test/test_config.rb +26 -0
  64. data/test/test_http10.rb +27 -0
  65. data/test/test_http11.rb +144 -0
  66. data/test/test_integration.rb +165 -0
  67. data/test/test_iobuffer.rb +38 -0
  68. data/test/test_minissl.rb +29 -0
  69. data/test/test_null_io.rb +31 -0
  70. data/test/test_persistent.rb +238 -0
  71. data/test/test_puma_server.rb +288 -0
  72. data/test/test_puma_server_ssl.rb +137 -0
  73. data/test/test_rack_handler.rb +10 -0
  74. data/test/test_rack_server.rb +141 -0
  75. data/test/test_tcp_rack.rb +42 -0
  76. data/test/test_thread_pool.rb +156 -0
  77. data/test/test_unix_socket.rb +39 -0
  78. data/test/test_ws.rb +89 -0
  79. data/tools/jungle/README.md +9 -0
  80. data/tools/jungle/init.d/README.md +54 -0
  81. data/tools/jungle/init.d/puma +332 -0
  82. data/tools/jungle/init.d/run-puma +3 -0
  83. data/tools/jungle/upstart/README.md +61 -0
  84. data/tools/jungle/upstart/puma-manager.conf +31 -0
  85. data/tools/jungle/upstart/puma.conf +63 -0
  86. data/tools/trickletest.rb +45 -0
  87. data/wendell-puma.gemspec +55 -0
  88. metadata +225 -0
@@ -0,0 +1,198 @@
1
+ #define RSTRING_NOT_MODIFIED 1
2
+ #include <ruby.h>
3
+ #include <rubyio.h>
4
+ #include <openssl/bio.h>
5
+ #include <openssl/ssl.h>
6
+ #include <openssl/err.h>
7
+
8
+ typedef struct {
9
+ BIO* read;
10
+ BIO* write;
11
+ SSL* ssl;
12
+ SSL_CTX* ctx;
13
+ } ms_conn;
14
+
15
+ void engine_free(ms_conn* conn) {
16
+ SSL_free(conn->ssl);
17
+ SSL_CTX_free(conn->ctx);
18
+
19
+ free(conn);
20
+ }
21
+
22
+ ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
23
+ ms_conn* conn;
24
+
25
+ *obj = Data_Make_Struct(klass, ms_conn, 0, engine_free, conn);
26
+
27
+ conn->read = BIO_new(BIO_s_mem());
28
+ BIO_set_nbio(conn->read, 1);
29
+
30
+ conn->write = BIO_new(BIO_s_mem());
31
+ BIO_set_nbio(conn->write, 1);
32
+
33
+ conn->ssl = 0;
34
+ conn->ctx = 0;
35
+
36
+ return conn;
37
+ }
38
+
39
+ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
40
+ VALUE obj;
41
+ SSL_CTX* ctx;
42
+ SSL* ssl;
43
+
44
+ ms_conn* conn = engine_alloc(self, &obj);
45
+
46
+ ID sym_key = rb_intern("key");
47
+ VALUE key = rb_funcall(mini_ssl_ctx, sym_key, 0);
48
+
49
+ ID sym_cert = rb_intern("cert");
50
+ VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
51
+
52
+ ctx = SSL_CTX_new(SSLv23_server_method());
53
+ conn->ctx = ctx;
54
+
55
+ SSL_CTX_use_certificate_file(ctx, RSTRING_PTR(cert), SSL_FILETYPE_PEM);
56
+ SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
57
+ /* SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); */
58
+
59
+ ssl = SSL_new(ctx);
60
+ conn->ssl = ssl;
61
+
62
+ /* SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); */
63
+
64
+ SSL_set_bio(ssl, conn->read, conn->write);
65
+
66
+ SSL_set_accept_state(ssl);
67
+ return obj;
68
+ }
69
+
70
+ VALUE engine_init_client(VALUE klass) {
71
+ VALUE obj;
72
+ ms_conn* conn = engine_alloc(klass, &obj);
73
+
74
+ conn->ctx = SSL_CTX_new(DTLSv1_method());
75
+ conn->ssl = SSL_new(conn->ctx);
76
+ SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
77
+
78
+ SSL_set_bio(conn->ssl, conn->read, conn->write);
79
+
80
+ SSL_set_connect_state(conn->ssl);
81
+ return obj;
82
+ }
83
+
84
+ VALUE engine_inject(VALUE self, VALUE str) {
85
+ ms_conn* conn;
86
+ long used;
87
+
88
+ Data_Get_Struct(self, ms_conn, conn);
89
+
90
+ StringValue(str);
91
+
92
+ used = BIO_write(conn->read, RSTRING_PTR(str), (int)RSTRING_LEN(str));
93
+
94
+ if(used == 0 || used == -1) {
95
+ return Qfalse;
96
+ }
97
+
98
+ return INT2FIX(used);
99
+ }
100
+
101
+ static VALUE eError;
102
+
103
+ void raise_error(SSL* ssl, int result) {
104
+ int error = SSL_get_error(ssl, result);
105
+ char* msg = ERR_error_string(error, NULL);
106
+
107
+ ERR_clear_error();
108
+ rb_raise(eError, "OpenSSL error: %s - %d", msg, error);
109
+ }
110
+
111
+ VALUE engine_read(VALUE self) {
112
+ ms_conn* conn;
113
+ char buf[512];
114
+ int bytes, n;
115
+
116
+ Data_Get_Struct(self, ms_conn, conn);
117
+
118
+ bytes = SSL_read(conn->ssl, (void*)buf, sizeof(buf));
119
+
120
+ if(bytes > 0) {
121
+ return rb_str_new(buf, bytes);
122
+ }
123
+
124
+ if(SSL_want_read(conn->ssl)) return Qnil;
125
+
126
+ if(SSL_get_error(conn->ssl, bytes) == SSL_ERROR_ZERO_RETURN) {
127
+ rb_eof_error();
128
+ }
129
+
130
+ raise_error(conn->ssl, bytes);
131
+
132
+ return Qnil;
133
+ }
134
+
135
+ VALUE engine_write(VALUE self, VALUE str) {
136
+ ms_conn* conn;
137
+ char buf[512];
138
+ int bytes;
139
+
140
+ Data_Get_Struct(self, ms_conn, conn);
141
+
142
+ StringValue(str);
143
+
144
+ bytes = SSL_write(conn->ssl, (void*)RSTRING_PTR(str), (int)RSTRING_LEN(str));
145
+ if(bytes > 0) {
146
+ return INT2FIX(bytes);
147
+ }
148
+
149
+ if(SSL_want_write(conn->ssl)) return Qnil;
150
+
151
+ raise_error(conn->ssl, bytes);
152
+
153
+ return Qnil;
154
+ }
155
+
156
+ VALUE engine_extract(VALUE self) {
157
+ ms_conn* conn;
158
+ int bytes;
159
+ size_t pending;
160
+ char buf[512];
161
+
162
+ Data_Get_Struct(self, ms_conn, conn);
163
+
164
+ pending = BIO_pending(conn->write);
165
+ if(pending > 0) {
166
+ bytes = BIO_read(conn->write, buf, sizeof(buf));
167
+ if(bytes > 0) {
168
+ return rb_str_new(buf, bytes);
169
+ } else if(!BIO_should_retry(conn->write)) {
170
+ raise_error(conn->ssl, bytes);
171
+ }
172
+ }
173
+
174
+ return Qnil;
175
+ }
176
+
177
+ void Init_mini_ssl(VALUE puma) {
178
+ VALUE mod, eng;
179
+
180
+ SSL_library_init();
181
+ OpenSSL_add_ssl_algorithms();
182
+ SSL_load_error_strings();
183
+ ERR_load_crypto_strings();
184
+
185
+ mod = rb_define_module_under(puma, "MiniSSL");
186
+ eng = rb_define_class_under(mod, "Engine", rb_cObject);
187
+
188
+ eError = rb_define_class_under(mod, "SSLError", rb_eStandardError);
189
+
190
+ rb_define_singleton_method(eng, "server", engine_init_server, 1);
191
+ rb_define_singleton_method(eng, "client", engine_init_client, 0);
192
+
193
+ rb_define_method(eng, "inject", engine_inject, 1);
194
+ rb_define_method(eng, "read", engine_read, 0);
195
+
196
+ rb_define_method(eng, "write", engine_write, 1);
197
+ rb_define_method(eng, "extract", engine_extract, 0);
198
+ }
@@ -0,0 +1,225 @@
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.ThreadContext;
15
+ import org.jruby.runtime.builtin.IRubyObject;
16
+
17
+ import org.jruby.exceptions.RaiseException;
18
+
19
+ import org.jruby.util.ByteList;
20
+
21
+ /**
22
+ * @author <a href="mailto:ola.bini@ki.se">Ola Bini</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
+
41
+ private static ObjectAllocator ALLOCATOR = new ObjectAllocator() {
42
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
43
+ return new Http11(runtime, klass);
44
+ }
45
+ };
46
+
47
+ public static void createHttp11(Ruby runtime) {
48
+ RubyModule mPuma = runtime.defineModule("Puma");
49
+ mPuma.defineClassUnder("HttpParserError",runtime.getClass("IOError"),runtime.getClass("IOError").getAllocator());
50
+
51
+ RubyClass cHttpParser = mPuma.defineClassUnder("HttpParser",runtime.getObject(),ALLOCATOR);
52
+ cHttpParser.defineAnnotatedMethods(Http11.class);
53
+ }
54
+
55
+ private Ruby runtime;
56
+ private RubyClass eHttpParserError;
57
+ private Http11Parser hp;
58
+ private RubyString body;
59
+
60
+ public Http11(Ruby runtime, RubyClass clazz) {
61
+ super(runtime,clazz);
62
+ this.runtime = runtime;
63
+ this.eHttpParserError = (RubyClass)runtime.getModule("Puma").getConstant("HttpParserError");
64
+ this.hp = new Http11Parser();
65
+ this.hp.parser.http_field = http_field;
66
+ this.hp.parser.request_method = request_method;
67
+ this.hp.parser.request_uri = request_uri;
68
+ this.hp.parser.fragment = fragment;
69
+ this.hp.parser.request_path = request_path;
70
+ this.hp.parser.query_string = query_string;
71
+ this.hp.parser.http_version = http_version;
72
+ this.hp.parser.header_done = header_done;
73
+ this.hp.parser.init();
74
+ }
75
+
76
+ public void validateMaxLength(int len, int max, String msg) {
77
+ if(len>max) {
78
+ throw new RaiseException(runtime, eHttpParserError, msg, true);
79
+ }
80
+ }
81
+
82
+ private Http11Parser.FieldCB http_field = new Http11Parser.FieldCB() {
83
+ public void call(Object data, int field, int flen, int value, int vlen) {
84
+ RubyHash req = (RubyHash)data;
85
+ RubyString v,f;
86
+ validateMaxLength(flen, MAX_FIELD_NAME_LENGTH, MAX_FIELD_NAME_LENGTH_ERR);
87
+ validateMaxLength(vlen, MAX_FIELD_VALUE_LENGTH, MAX_FIELD_VALUE_LENGTH_ERR);
88
+
89
+ v = RubyString.newString(runtime, new ByteList(Http11.this.hp.parser.buffer,value,vlen));
90
+ ByteList b = new ByteList(Http11.this.hp.parser.buffer,field,flen);
91
+ for(int i = 0,j = b.length();i<j;i++) {
92
+ if((b.get(i) & 0xFF) == '-') {
93
+ b.set(i, (byte)'_');
94
+ } else {
95
+ b.set(i, (byte)Character.toUpperCase((char)b.get(i)));
96
+ }
97
+ }
98
+
99
+ String as = b.toString();
100
+
101
+ if(as.equals("CONTENT_LENGTH") || as.equals("CONTENT_TYPE")) {
102
+ f = RubyString.newString(runtime, b);
103
+ } else {
104
+ f = RubyString.newString(runtime, "HTTP_");
105
+ f.cat(b);
106
+ }
107
+ req.op_aset(req.getRuntime().getCurrentContext(), f,v);
108
+ }
109
+ };
110
+
111
+ private Http11Parser.ElementCB request_method = new Http11Parser.ElementCB() {
112
+ public void call(Object data, int at, int length) {
113
+ RubyHash req = (RubyHash)data;
114
+ RubyString val = RubyString.newString(runtime,new ByteList(hp.parser.buffer,at,length));
115
+ req.op_aset(req.getRuntime().getCurrentContext(), runtime.newString("REQUEST_METHOD"),val);
116
+ }
117
+ };
118
+
119
+ private Http11Parser.ElementCB request_uri = new Http11Parser.ElementCB() {
120
+ public void call(Object data, int at, int length) {
121
+ RubyHash req = (RubyHash)data;
122
+ validateMaxLength(length, MAX_REQUEST_URI_LENGTH, MAX_REQUEST_URI_LENGTH_ERR);
123
+ RubyString val = RubyString.newString(runtime,new ByteList(hp.parser.buffer,at,length));
124
+ req.op_aset(req.getRuntime().getCurrentContext(), runtime.newString("REQUEST_URI"),val);
125
+ }
126
+ };
127
+
128
+ private Http11Parser.ElementCB fragment = new Http11Parser.ElementCB() {
129
+ public void call(Object data, int at, int length) {
130
+ RubyHash req = (RubyHash)data;
131
+ validateMaxLength(length, MAX_FRAGMENT_LENGTH, MAX_FRAGMENT_LENGTH_ERR);
132
+ RubyString val = RubyString.newString(runtime,new ByteList(hp.parser.buffer,at,length));
133
+ req.op_aset(req.getRuntime().getCurrentContext(), runtime.newString("FRAGMENT"),val);
134
+ }
135
+ };
136
+
137
+ private Http11Parser.ElementCB request_path = new Http11Parser.ElementCB() {
138
+ public void call(Object data, int at, int length) {
139
+ RubyHash req = (RubyHash)data;
140
+ validateMaxLength(length, MAX_REQUEST_PATH_LENGTH, MAX_REQUEST_PATH_LENGTH_ERR);
141
+ RubyString val = RubyString.newString(runtime,new ByteList(hp.parser.buffer,at,length));
142
+ req.op_aset(req.getRuntime().getCurrentContext(), runtime.newString("REQUEST_PATH"),val);
143
+ }
144
+ };
145
+
146
+ private Http11Parser.ElementCB query_string = new Http11Parser.ElementCB() {
147
+ public void call(Object data, int at, int length) {
148
+ RubyHash req = (RubyHash)data;
149
+ validateMaxLength(length, MAX_QUERY_STRING_LENGTH, MAX_QUERY_STRING_LENGTH_ERR);
150
+ RubyString val = RubyString.newString(runtime,new ByteList(hp.parser.buffer,at,length));
151
+ req.op_aset(req.getRuntime().getCurrentContext(), runtime.newString("QUERY_STRING"),val);
152
+ }
153
+ };
154
+
155
+ private Http11Parser.ElementCB http_version = new Http11Parser.ElementCB() {
156
+ public void call(Object data, int at, int length) {
157
+ RubyHash req = (RubyHash)data;
158
+ RubyString val = RubyString.newString(runtime,new ByteList(hp.parser.buffer,at,length));
159
+ req.op_aset(req.getRuntime().getCurrentContext(), runtime.newString("HTTP_VERSION"),val);
160
+ }
161
+ };
162
+
163
+ private Http11Parser.ElementCB header_done = new Http11Parser.ElementCB() {
164
+ public void call(Object data, int at, int length) {
165
+ body = RubyString.newString(runtime, new ByteList(hp.parser.buffer, at, length));
166
+ }
167
+ };
168
+
169
+ @JRubyMethod
170
+ public IRubyObject initialize() {
171
+ this.hp.parser.init();
172
+ return this;
173
+ }
174
+
175
+ @JRubyMethod
176
+ public IRubyObject reset() {
177
+ this.hp.parser.init();
178
+ return runtime.getNil();
179
+ }
180
+
181
+ @JRubyMethod
182
+ public IRubyObject finish() {
183
+ this.hp.finish();
184
+ return this.hp.is_finished() ? runtime.getTrue() : runtime.getFalse();
185
+ }
186
+
187
+ @JRubyMethod
188
+ public IRubyObject execute(IRubyObject req_hash, IRubyObject data, IRubyObject start) {
189
+ int from = 0;
190
+ from = RubyNumeric.fix2int(start);
191
+ ByteList d = ((RubyString)data).getByteList();
192
+ if(from >= d.length()) {
193
+ throw new RaiseException(runtime, eHttpParserError, "Requested start is after data buffer end.", true);
194
+ } else {
195
+ this.hp.parser.data = req_hash;
196
+ this.hp.execute(d,from);
197
+ validateMaxLength(this.hp.parser.nread,MAX_HEADER_LENGTH, MAX_HEADER_LENGTH_ERR);
198
+ if(this.hp.has_error()) {
199
+ throw new RaiseException(runtime, eHttpParserError, "Invalid HTTP format, parsing fails.", true);
200
+ } else {
201
+ return runtime.newFixnum(this.hp.parser.nread);
202
+ }
203
+ }
204
+ }
205
+
206
+ @JRubyMethod(name = "error?")
207
+ public IRubyObject has_error() {
208
+ return this.hp.has_error() ? runtime.getTrue() : runtime.getFalse();
209
+ }
210
+
211
+ @JRubyMethod(name = "finished?")
212
+ public IRubyObject is_finished() {
213
+ return this.hp.is_finished() ? runtime.getTrue() : runtime.getFalse();
214
+ }
215
+
216
+ @JRubyMethod
217
+ public IRubyObject nread() {
218
+ return runtime.newFixnum(this.hp.parser.nread);
219
+ }
220
+
221
+ @JRubyMethod
222
+ public IRubyObject body() {
223
+ return body;
224
+ }
225
+ }// Http11
@@ -0,0 +1,488 @@
1
+
2
+ // line 1 "ext/puma_http11/http11_parser.java.rl"
3
+ package org.jruby.puma;
4
+
5
+ import org.jruby.util.ByteList;
6
+
7
+ public class Http11Parser {
8
+
9
+ /** Machine **/
10
+
11
+
12
+ // line 65 "ext/puma_http11/http11_parser.java.rl"
13
+
14
+
15
+ /** Data **/
16
+
17
+ // line 18 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
18
+ private static byte[] init__http_parser_actions_0()
19
+ {
20
+ return new byte [] {
21
+ 0, 1, 0, 1, 2, 1, 3, 1, 4, 1, 5, 1,
22
+ 6, 1, 7, 1, 8, 1, 9, 1, 11, 1, 12, 1,
23
+ 13, 2, 0, 8, 2, 1, 2, 2, 4, 5, 2, 10,
24
+ 7, 2, 12, 7, 3, 9, 10, 7
25
+ };
26
+ }
27
+
28
+ private static final byte _http_parser_actions[] = init__http_parser_actions_0();
29
+
30
+
31
+ private static short[] init__http_parser_key_offsets_0()
32
+ {
33
+ return new short [] {
34
+ 0, 0, 8, 17, 27, 29, 30, 31, 32, 33, 34, 36,
35
+ 39, 41, 44, 45, 61, 62, 78, 80, 81, 90, 99, 105,
36
+ 111, 121, 130, 136, 142, 153, 159, 165, 175, 181, 187, 196,
37
+ 205, 211, 217, 226, 235, 244, 253, 262, 271, 280, 289, 298,
38
+ 307, 316, 325, 334, 343, 352, 361, 370, 379, 380
39
+ };
40
+ }
41
+
42
+ private static final short _http_parser_key_offsets[] = init__http_parser_key_offsets_0();
43
+
44
+
45
+ private static char[] init__http_parser_trans_keys_0()
46
+ {
47
+ return new char [] {
48
+ 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
49
+ 46, 48, 57, 65, 90, 42, 43, 47, 58, 45, 57, 65,
50
+ 90, 97, 122, 32, 35, 72, 84, 84, 80, 47, 48, 57,
51
+ 46, 48, 57, 48, 57, 13, 48, 57, 10, 13, 33, 124,
52
+ 126, 35, 39, 42, 43, 45, 46, 48, 57, 65, 90, 94,
53
+ 122, 10, 33, 58, 124, 126, 35, 39, 42, 43, 45, 46,
54
+ 48, 57, 65, 90, 94, 122, 13, 32, 13, 32, 37, 60,
55
+ 62, 127, 0, 31, 34, 35, 32, 37, 60, 62, 127, 0,
56
+ 31, 34, 35, 48, 57, 65, 70, 97, 102, 48, 57, 65,
57
+ 70, 97, 102, 43, 58, 45, 46, 48, 57, 65, 90, 97,
58
+ 122, 32, 34, 35, 37, 60, 62, 127, 0, 31, 48, 57,
59
+ 65, 70, 97, 102, 48, 57, 65, 70, 97, 102, 32, 34,
60
+ 35, 37, 59, 60, 62, 63, 127, 0, 31, 48, 57, 65,
61
+ 70, 97, 102, 48, 57, 65, 70, 97, 102, 32, 34, 35,
62
+ 37, 60, 62, 63, 127, 0, 31, 48, 57, 65, 70, 97,
63
+ 102, 48, 57, 65, 70, 97, 102, 32, 34, 35, 37, 60,
64
+ 62, 127, 0, 31, 32, 34, 35, 37, 60, 62, 127, 0,
65
+ 31, 48, 57, 65, 70, 97, 102, 48, 57, 65, 70, 97,
66
+ 102, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36,
67
+ 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46,
68
+ 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65,
69
+ 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36,
70
+ 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46,
71
+ 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65,
72
+ 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36,
73
+ 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46,
74
+ 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65,
75
+ 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36,
76
+ 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46,
77
+ 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65,
78
+ 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36,
79
+ 95, 45, 46, 48, 57, 65, 90, 32, 0
80
+ };
81
+ }
82
+
83
+ private static final char _http_parser_trans_keys[] = init__http_parser_trans_keys_0();
84
+
85
+
86
+ private static byte[] init__http_parser_single_lengths_0()
87
+ {
88
+ return new byte [] {
89
+ 0, 2, 3, 4, 2, 1, 1, 1, 1, 1, 0, 1,
90
+ 0, 1, 1, 4, 1, 4, 2, 1, 5, 5, 0, 0,
91
+ 2, 7, 0, 0, 9, 0, 0, 8, 0, 0, 7, 7,
92
+ 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
93
+ 3, 3, 3, 3, 3, 3, 3, 3, 1, 0
94
+ };
95
+ }
96
+
97
+ private static final byte _http_parser_single_lengths[] = init__http_parser_single_lengths_0();
98
+
99
+
100
+ private static byte[] init__http_parser_range_lengths_0()
101
+ {
102
+ return new byte [] {
103
+ 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 1,
104
+ 1, 1, 0, 6, 0, 6, 0, 0, 2, 2, 3, 3,
105
+ 4, 1, 3, 3, 1, 3, 3, 1, 3, 3, 1, 1,
106
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
107
+ 3, 3, 3, 3, 3, 3, 3, 3, 0, 0
108
+ };
109
+ }
110
+
111
+ private static final byte _http_parser_range_lengths[] = init__http_parser_range_lengths_0();
112
+
113
+
114
+ private static short[] init__http_parser_index_offsets_0()
115
+ {
116
+ return new short [] {
117
+ 0, 0, 6, 13, 21, 24, 26, 28, 30, 32, 34, 36,
118
+ 39, 41, 44, 46, 57, 59, 70, 73, 75, 83, 91, 95,
119
+ 99, 106, 115, 119, 123, 134, 138, 142, 152, 156, 160, 169,
120
+ 178, 182, 186, 193, 200, 207, 214, 221, 228, 235, 242, 249,
121
+ 256, 263, 270, 277, 284, 291, 298, 305, 312, 314
122
+ };
123
+ }
124
+
125
+ private static final short _http_parser_index_offsets[] = init__http_parser_index_offsets_0();
126
+
127
+
128
+ private static byte[] init__http_parser_indicies_0()
129
+ {
130
+ return new byte [] {
131
+ 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3,
132
+ 1, 4, 5, 6, 7, 5, 5, 5, 1, 8, 9, 1,
133
+ 10, 1, 11, 1, 12, 1, 13, 1, 14, 1, 15, 1,
134
+ 16, 15, 1, 17, 1, 18, 17, 1, 19, 1, 20, 21,
135
+ 21, 21, 21, 21, 21, 21, 21, 21, 1, 22, 1, 23,
136
+ 24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27,
137
+ 25, 29, 28, 30, 32, 1, 1, 1, 1, 1, 31, 33,
138
+ 35, 1, 1, 1, 1, 1, 34, 36, 36, 36, 1, 34,
139
+ 34, 34, 1, 37, 38, 37, 37, 37, 37, 1, 8, 1,
140
+ 9, 39, 1, 1, 1, 1, 38, 40, 40, 40, 1, 38,
141
+ 38, 38, 1, 41, 1, 43, 44, 45, 1, 1, 46, 1,
142
+ 1, 42, 47, 47, 47, 1, 42, 42, 42, 1, 8, 1,
143
+ 9, 49, 1, 1, 50, 1, 1, 48, 51, 51, 51, 1,
144
+ 48, 48, 48, 1, 52, 1, 54, 55, 1, 1, 1, 1,
145
+ 53, 56, 1, 58, 59, 1, 1, 1, 1, 57, 60, 60,
146
+ 60, 1, 57, 57, 57, 1, 2, 61, 61, 61, 61, 61,
147
+ 1, 2, 62, 62, 62, 62, 62, 1, 2, 63, 63, 63,
148
+ 63, 63, 1, 2, 64, 64, 64, 64, 64, 1, 2, 65,
149
+ 65, 65, 65, 65, 1, 2, 66, 66, 66, 66, 66, 1,
150
+ 2, 67, 67, 67, 67, 67, 1, 2, 68, 68, 68, 68,
151
+ 68, 1, 2, 69, 69, 69, 69, 69, 1, 2, 70, 70,
152
+ 70, 70, 70, 1, 2, 71, 71, 71, 71, 71, 1, 2,
153
+ 72, 72, 72, 72, 72, 1, 2, 73, 73, 73, 73, 73,
154
+ 1, 2, 74, 74, 74, 74, 74, 1, 2, 75, 75, 75,
155
+ 75, 75, 1, 2, 76, 76, 76, 76, 76, 1, 2, 77,
156
+ 77, 77, 77, 77, 1, 2, 78, 78, 78, 78, 78, 1,
157
+ 2, 1, 1, 0
158
+ };
159
+ }
160
+
161
+ private static final byte _http_parser_indicies[] = init__http_parser_indicies_0();
162
+
163
+
164
+ private static byte[] init__http_parser_trans_targs_0()
165
+ {
166
+ return new byte [] {
167
+ 2, 0, 3, 38, 4, 24, 28, 25, 5, 20, 6, 7,
168
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 57, 17,
169
+ 18, 19, 14, 18, 19, 14, 5, 21, 22, 5, 21, 22,
170
+ 23, 24, 25, 26, 27, 5, 28, 20, 29, 31, 34, 30,
171
+ 31, 32, 34, 33, 5, 35, 20, 36, 5, 35, 20, 36,
172
+ 37, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
173
+ 50, 51, 52, 53, 54, 55, 56
174
+ };
175
+ }
176
+
177
+ private static final byte _http_parser_trans_targs[] = init__http_parser_trans_targs_0();
178
+
179
+
180
+ private static byte[] init__http_parser_trans_actions_0()
181
+ {
182
+ return new byte [] {
183
+ 1, 0, 11, 0, 1, 1, 1, 1, 13, 13, 1, 0,
184
+ 0, 0, 0, 0, 0, 0, 19, 0, 0, 28, 23, 3,
185
+ 5, 7, 31, 7, 0, 9, 25, 1, 1, 15, 0, 0,
186
+ 0, 0, 0, 0, 0, 37, 0, 37, 0, 21, 21, 0,
187
+ 0, 0, 0, 0, 40, 17, 40, 17, 34, 0, 34, 0,
188
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
189
+ 0, 0, 0, 0, 0, 0, 0
190
+ };
191
+ }
192
+
193
+ private static final byte _http_parser_trans_actions[] = init__http_parser_trans_actions_0();
194
+
195
+
196
+ static final int http_parser_start = 1;
197
+ static final int http_parser_first_final = 57;
198
+ static final int http_parser_error = 0;
199
+
200
+ static final int http_parser_en_main = 1;
201
+
202
+
203
+ // line 69 "ext/puma_http11/http11_parser.java.rl"
204
+
205
+ public static interface ElementCB {
206
+ public void call(Object data, int at, int length);
207
+ }
208
+
209
+ public static interface FieldCB {
210
+ public void call(Object data, int field, int flen, int value, int vlen);
211
+ }
212
+
213
+ public static class HttpParser {
214
+ int cs;
215
+ int body_start;
216
+ int content_len;
217
+ int nread;
218
+ int mark;
219
+ int field_start;
220
+ int field_len;
221
+ int query_start;
222
+
223
+ Object data;
224
+ ByteList buffer;
225
+
226
+ public FieldCB http_field;
227
+ public ElementCB request_method;
228
+ public ElementCB request_uri;
229
+ public ElementCB fragment;
230
+ public ElementCB request_path;
231
+ public ElementCB query_string;
232
+ public ElementCB http_version;
233
+ public ElementCB header_done;
234
+
235
+ public void init() {
236
+ cs = 0;
237
+
238
+
239
+ // line 240 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
240
+ {
241
+ cs = http_parser_start;
242
+ }
243
+
244
+ // line 104 "ext/puma_http11/http11_parser.java.rl"
245
+
246
+ body_start = 0;
247
+ content_len = 0;
248
+ mark = 0;
249
+ nread = 0;
250
+ field_len = 0;
251
+ field_start = 0;
252
+ }
253
+ }
254
+
255
+ public final HttpParser parser = new HttpParser();
256
+
257
+ public int execute(ByteList buffer, int off) {
258
+ int p, pe;
259
+ int cs = parser.cs;
260
+ int len = buffer.length();
261
+ assert off<=len : "offset past end of buffer";
262
+
263
+ p = off;
264
+ pe = len;
265
+ // get a copy of the bytes, since it may not start at 0
266
+ // FIXME: figure out how to just use the bytes in-place
267
+ byte[] data = buffer.bytes();
268
+ parser.buffer = buffer;
269
+
270
+
271
+ // line 272 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
272
+ {
273
+ int _klen;
274
+ int _trans = 0;
275
+ int _acts;
276
+ int _nacts;
277
+ int _keys;
278
+ int _goto_targ = 0;
279
+
280
+ _goto: while (true) {
281
+ switch ( _goto_targ ) {
282
+ case 0:
283
+ if ( p == pe ) {
284
+ _goto_targ = 4;
285
+ continue _goto;
286
+ }
287
+ if ( cs == 0 ) {
288
+ _goto_targ = 5;
289
+ continue _goto;
290
+ }
291
+ case 1:
292
+ _match: do {
293
+ _keys = _http_parser_key_offsets[cs];
294
+ _trans = _http_parser_index_offsets[cs];
295
+ _klen = _http_parser_single_lengths[cs];
296
+ if ( _klen > 0 ) {
297
+ int _lower = _keys;
298
+ int _mid;
299
+ int _upper = _keys + _klen - 1;
300
+ while (true) {
301
+ if ( _upper < _lower )
302
+ break;
303
+
304
+ _mid = _lower + ((_upper-_lower) >> 1);
305
+ if ( data[p] < _http_parser_trans_keys[_mid] )
306
+ _upper = _mid - 1;
307
+ else if ( data[p] > _http_parser_trans_keys[_mid] )
308
+ _lower = _mid + 1;
309
+ else {
310
+ _trans += (_mid - _keys);
311
+ break _match;
312
+ }
313
+ }
314
+ _keys += _klen;
315
+ _trans += _klen;
316
+ }
317
+
318
+ _klen = _http_parser_range_lengths[cs];
319
+ if ( _klen > 0 ) {
320
+ int _lower = _keys;
321
+ int _mid;
322
+ int _upper = _keys + (_klen<<1) - 2;
323
+ while (true) {
324
+ if ( _upper < _lower )
325
+ break;
326
+
327
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1);
328
+ if ( data[p] < _http_parser_trans_keys[_mid] )
329
+ _upper = _mid - 2;
330
+ else if ( data[p] > _http_parser_trans_keys[_mid+1] )
331
+ _lower = _mid + 2;
332
+ else {
333
+ _trans += ((_mid - _keys)>>1);
334
+ break _match;
335
+ }
336
+ }
337
+ _trans += _klen;
338
+ }
339
+ } while (false);
340
+
341
+ _trans = _http_parser_indicies[_trans];
342
+ cs = _http_parser_trans_targs[_trans];
343
+
344
+ if ( _http_parser_trans_actions[_trans] != 0 ) {
345
+ _acts = _http_parser_trans_actions[_trans];
346
+ _nacts = (int) _http_parser_actions[_acts++];
347
+ while ( _nacts-- > 0 )
348
+ {
349
+ switch ( _http_parser_actions[_acts++] )
350
+ {
351
+ case 0:
352
+ // line 13 "ext/puma_http11/http11_parser.java.rl"
353
+ {parser.mark = p; }
354
+ break;
355
+ case 1:
356
+ // line 15 "ext/puma_http11/http11_parser.java.rl"
357
+ { parser.field_start = p; }
358
+ break;
359
+ case 2:
360
+ // line 16 "ext/puma_http11/http11_parser.java.rl"
361
+ { /* FIXME stub */ }
362
+ break;
363
+ case 3:
364
+ // line 17 "ext/puma_http11/http11_parser.java.rl"
365
+ {
366
+ parser.field_len = p-parser.field_start;
367
+ }
368
+ break;
369
+ case 4:
370
+ // line 21 "ext/puma_http11/http11_parser.java.rl"
371
+ { parser.mark = p; }
372
+ break;
373
+ case 5:
374
+ // line 22 "ext/puma_http11/http11_parser.java.rl"
375
+ {
376
+ if(parser.http_field != null) {
377
+ parser.http_field.call(parser.data, parser.field_start, parser.field_len, parser.mark, p-parser.mark);
378
+ }
379
+ }
380
+ break;
381
+ case 6:
382
+ // line 27 "ext/puma_http11/http11_parser.java.rl"
383
+ {
384
+ if(parser.request_method != null)
385
+ parser.request_method.call(parser.data, parser.mark, p-parser.mark);
386
+ }
387
+ break;
388
+ case 7:
389
+ // line 31 "ext/puma_http11/http11_parser.java.rl"
390
+ {
391
+ if(parser.request_uri != null)
392
+ parser.request_uri.call(parser.data, parser.mark, p-parser.mark);
393
+ }
394
+ break;
395
+ case 8:
396
+ // line 35 "ext/puma_http11/http11_parser.java.rl"
397
+ {
398
+ if(parser.fragment != null)
399
+ parser.fragment.call(parser.data, parser.mark, p-parser.mark);
400
+ }
401
+ break;
402
+ case 9:
403
+ // line 40 "ext/puma_http11/http11_parser.java.rl"
404
+ {parser.query_start = p; }
405
+ break;
406
+ case 10:
407
+ // line 41 "ext/puma_http11/http11_parser.java.rl"
408
+ {
409
+ if(parser.query_string != null)
410
+ parser.query_string.call(parser.data, parser.query_start, p-parser.query_start);
411
+ }
412
+ break;
413
+ case 11:
414
+ // line 46 "ext/puma_http11/http11_parser.java.rl"
415
+ {
416
+ if(parser.http_version != null)
417
+ parser.http_version.call(parser.data, parser.mark, p-parser.mark);
418
+ }
419
+ break;
420
+ case 12:
421
+ // line 51 "ext/puma_http11/http11_parser.java.rl"
422
+ {
423
+ if(parser.request_path != null)
424
+ parser.request_path.call(parser.data, parser.mark, p-parser.mark);
425
+ }
426
+ break;
427
+ case 13:
428
+ // line 56 "ext/puma_http11/http11_parser.java.rl"
429
+ {
430
+ parser.body_start = p + 1;
431
+ if(parser.header_done != null)
432
+ parser.header_done.call(parser.data, p + 1, pe - p - 1);
433
+ { p += 1; _goto_targ = 5; if (true) continue _goto;}
434
+ }
435
+ break;
436
+ // line 437 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
437
+ }
438
+ }
439
+ }
440
+
441
+ case 2:
442
+ if ( cs == 0 ) {
443
+ _goto_targ = 5;
444
+ continue _goto;
445
+ }
446
+ if ( ++p != pe ) {
447
+ _goto_targ = 1;
448
+ continue _goto;
449
+ }
450
+ case 4:
451
+ case 5:
452
+ }
453
+ break; }
454
+ }
455
+
456
+ // line 130 "ext/puma_http11/http11_parser.java.rl"
457
+
458
+ parser.cs = cs;
459
+ parser.nread += (p - off);
460
+
461
+ assert p <= pe : "buffer overflow after parsing execute";
462
+ assert parser.nread <= len : "nread longer than length";
463
+ assert parser.body_start <= len : "body starts after buffer end";
464
+ assert parser.mark < len : "mark is after buffer end";
465
+ assert parser.field_len <= len : "field has length longer than whole buffer";
466
+ assert parser.field_start < len : "field starts after buffer end";
467
+
468
+ return parser.nread;
469
+ }
470
+
471
+ public int finish() {
472
+ if(has_error()) {
473
+ return -1;
474
+ } else if(is_finished()) {
475
+ return 1;
476
+ } else {
477
+ return 0;
478
+ }
479
+ }
480
+
481
+ public boolean has_error() {
482
+ return parser.cs == http_parser_error;
483
+ }
484
+
485
+ public boolean is_finished() {
486
+ return parser.cs == http_parser_first_final;
487
+ }
488
+ }