puma 5.0.3 → 5.2.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +110 -40
  3. data/README.md +48 -18
  4. data/docs/compile_options.md +19 -0
  5. data/docs/deployment.md +1 -1
  6. data/docs/fork_worker.md +2 -0
  7. data/docs/kubernetes.md +66 -0
  8. data/docs/plugins.md +1 -1
  9. data/docs/rails_dev_mode.md +29 -0
  10. data/docs/stats.md +142 -0
  11. data/docs/systemd.md +24 -2
  12. data/ext/puma_http11/extconf.rb +18 -5
  13. data/ext/puma_http11/http11_parser.c +45 -47
  14. data/ext/puma_http11/http11_parser.java.rl +1 -1
  15. data/ext/puma_http11/http11_parser.rl +1 -1
  16. data/ext/puma_http11/mini_ssl.c +162 -84
  17. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +5 -7
  18. data/ext/puma_http11/puma_http11.c +8 -2
  19. data/lib/puma.rb +20 -10
  20. data/lib/puma/app/status.rb +4 -7
  21. data/lib/puma/binder.rb +60 -24
  22. data/lib/puma/cli.rb +4 -0
  23. data/lib/puma/client.rb +4 -9
  24. data/lib/puma/cluster.rb +13 -7
  25. data/lib/puma/cluster/worker.rb +8 -2
  26. data/lib/puma/cluster/worker_handle.rb +5 -2
  27. data/lib/puma/configuration.rb +13 -1
  28. data/lib/puma/const.rb +11 -3
  29. data/lib/puma/control_cli.rb +73 -70
  30. data/lib/puma/detect.rb +14 -10
  31. data/lib/puma/dsl.rb +100 -22
  32. data/lib/puma/error_logger.rb +10 -3
  33. data/lib/puma/events.rb +18 -3
  34. data/lib/puma/json.rb +96 -0
  35. data/lib/puma/launcher.rb +52 -6
  36. data/lib/puma/minissl.rb +48 -17
  37. data/lib/puma/minissl/context_builder.rb +6 -0
  38. data/lib/puma/null_io.rb +4 -0
  39. data/lib/puma/reactor.rb +19 -12
  40. data/lib/puma/request.rb +20 -7
  41. data/lib/puma/runner.rb +14 -7
  42. data/lib/puma/server.rb +20 -75
  43. data/lib/puma/state_file.rb +5 -3
  44. data/lib/puma/systemd.rb +46 -0
  45. data/lib/rack/handler/puma.rb +1 -0
  46. metadata +12 -6
@@ -58,7 +58,7 @@ public class Http11Parser {
58
58
  }%%
59
59
 
60
60
  /** Data **/
61
- %% write data;
61
+ %% write data noentry;
62
62
 
63
63
  public static interface ElementCB {
64
64
  public void call(Ruby runtime, RubyHash data, ByteList buffer, int at, int length);
@@ -81,7 +81,7 @@ static void snake_upcase_char(char *c)
81
81
  }%%
82
82
 
83
83
  /** Data **/
84
- %% write data;
84
+ %% write data noentry;
85
85
 
86
86
  int puma_parser_init(puma_parser *parser) {
87
87
  int cs = 0;
@@ -28,6 +28,8 @@ typedef struct {
28
28
  int bytes;
29
29
  } ms_cert_buf;
30
30
 
31
+ VALUE eError;
32
+
31
33
  void engine_free(void *ptr) {
32
34
  ms_conn *conn = ptr;
33
35
  ms_cert_buf* cert_buf = (ms_cert_buf*)SSL_get_app_data(conn->ssl);
@@ -47,61 +49,65 @@ const rb_data_type_t engine_data_type = {
47
49
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
48
50
  };
49
51
 
50
- ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
51
- ms_conn* conn;
52
-
53
- *obj = TypedData_Make_Struct(klass, ms_conn, &engine_data_type, conn);
54
-
55
- conn->read = BIO_new(BIO_s_mem());
56
- BIO_set_nbio(conn->read, 1);
57
-
58
- conn->write = BIO_new(BIO_s_mem());
59
- BIO_set_nbio(conn->write, 1);
60
-
61
- conn->ssl = 0;
62
- conn->ctx = 0;
63
-
64
- return conn;
65
- }
66
-
67
- DH *get_dh1024() {
68
- /* `openssl dhparam 1024 -C`
52
+ DH *get_dh2048() {
53
+ /* `openssl dhparam -C 2048`
69
54
  * -----BEGIN DH PARAMETERS-----
70
- * MIGHAoGBALPwcEv0OstmQCZdfHw0N5r+07lmXMxkpQacy1blwj0LUqC+Divp6pBk
71
- * usTJ9W2/dOYr1X7zi6yXNLp4oLzc/31PUL3D9q8CpGS7vPz5gijKSw9BwCTT5z9+
72
- * KF9v46qw8XqT5HHV87sWFlGQcVFq+pEkA2kPikkKZ/X/CCcpCAV7AgEC
55
+ * MIIBCAKCAQEAjmh1uQHdTfxOyxEbKAV30fUfzqMDF/ChPzjfyzl2jcrqQMhrk76o
56
+ * 2NPNXqxHwsddMZ1RzvU8/jl+uhRuPWjXCFZbhET4N1vrviZM3VJhV8PPHuiVOACO
57
+ * y32jFd+Szx4bo2cXSK83hJ6jRd+0asP1awWjz9/06dFkrILCXMIfQLo0D8rqmppn
58
+ * EfDDAwuudCpM9kcDmBRAm9JsKbQ6gzZWjkc5+QWSaQofojIHbjvj3xzguaCJn+oQ
59
+ * vHWM+hsAnaOgEwCyeZ3xqs+/5lwSbkE/tqJW98cEZGygBUVo9jxZRZx6KOfjpdrb
60
+ * yenO9LJr/qtyrZB31WJbqxI0m0AKTAO8UwIBAg==
73
61
  * -----END DH PARAMETERS-----
74
62
  */
75
- static unsigned char dh1024_p[] = {
76
- 0xB3,0xF0,0x70,0x4B,0xF4,0x3A,0xCB,0x66,0x40,0x26,0x5D,0x7C,
77
- 0x7C,0x34,0x37,0x9A,0xFE,0xD3,0xB9,0x66,0x5C,0xCC,0x64,0xA5,
78
- 0x06,0x9C,0xCB,0x56,0xE5,0xC2,0x3D,0x0B,0x52,0xA0,0xBE,0x0E,
79
- 0x2B,0xE9,0xEA,0x90,0x64,0xBA,0xC4,0xC9,0xF5,0x6D,0xBF,0x74,
80
- 0xE6,0x2B,0xD5,0x7E,0xF3,0x8B,0xAC,0x97,0x34,0xBA,0x78,0xA0,
81
- 0xBC,0xDC,0xFF,0x7D,0x4F,0x50,0xBD,0xC3,0xF6,0xAF,0x02,0xA4,
82
- 0x64,0xBB,0xBC,0xFC,0xF9,0x82,0x28,0xCA,0x4B,0x0F,0x41,0xC0,
83
- 0x24,0xD3,0xE7,0x3F,0x7E,0x28,0x5F,0x6F,0xE3,0xAA,0xB0,0xF1,
84
- 0x7A,0x93,0xE4,0x71,0xD5,0xF3,0xBB,0x16,0x16,0x51,0x90,0x71,
85
- 0x51,0x6A,0xFA,0x91,0x24,0x03,0x69,0x0F,0x8A,0x49,0x0A,0x67,
86
- 0xF5,0xFF,0x08,0x27,0x29,0x08,0x05,0x7B
63
+ static unsigned char dh2048_p[] = {
64
+ 0x8E, 0x68, 0x75, 0xB9, 0x01, 0xDD, 0x4D, 0xFC, 0x4E, 0xCB,
65
+ 0x11, 0x1B, 0x28, 0x05, 0x77, 0xD1, 0xF5, 0x1F, 0xCE, 0xA3,
66
+ 0x03, 0x17, 0xF0, 0xA1, 0x3F, 0x38, 0xDF, 0xCB, 0x39, 0x76,
67
+ 0x8D, 0xCA, 0xEA, 0x40, 0xC8, 0x6B, 0x93, 0xBE, 0xA8, 0xD8,
68
+ 0xD3, 0xCD, 0x5E, 0xAC, 0x47, 0xC2, 0xC7, 0x5D, 0x31, 0x9D,
69
+ 0x51, 0xCE, 0xF5, 0x3C, 0xFE, 0x39, 0x7E, 0xBA, 0x14, 0x6E,
70
+ 0x3D, 0x68, 0xD7, 0x08, 0x56, 0x5B, 0x84, 0x44, 0xF8, 0x37,
71
+ 0x5B, 0xEB, 0xBE, 0x26, 0x4C, 0xDD, 0x52, 0x61, 0x57, 0xC3,
72
+ 0xCF, 0x1E, 0xE8, 0x95, 0x38, 0x00, 0x8E, 0xCB, 0x7D, 0xA3,
73
+ 0x15, 0xDF, 0x92, 0xCF, 0x1E, 0x1B, 0xA3, 0x67, 0x17, 0x48,
74
+ 0xAF, 0x37, 0x84, 0x9E, 0xA3, 0x45, 0xDF, 0xB4, 0x6A, 0xC3,
75
+ 0xF5, 0x6B, 0x05, 0xA3, 0xCF, 0xDF, 0xF4, 0xE9, 0xD1, 0x64,
76
+ 0xAC, 0x82, 0xC2, 0x5C, 0xC2, 0x1F, 0x40, 0xBA, 0x34, 0x0F,
77
+ 0xCA, 0xEA, 0x9A, 0x9A, 0x67, 0x11, 0xF0, 0xC3, 0x03, 0x0B,
78
+ 0xAE, 0x74, 0x2A, 0x4C, 0xF6, 0x47, 0x03, 0x98, 0x14, 0x40,
79
+ 0x9B, 0xD2, 0x6C, 0x29, 0xB4, 0x3A, 0x83, 0x36, 0x56, 0x8E,
80
+ 0x47, 0x39, 0xF9, 0x05, 0x92, 0x69, 0x0A, 0x1F, 0xA2, 0x32,
81
+ 0x07, 0x6E, 0x3B, 0xE3, 0xDF, 0x1C, 0xE0, 0xB9, 0xA0, 0x89,
82
+ 0x9F, 0xEA, 0x10, 0xBC, 0x75, 0x8C, 0xFA, 0x1B, 0x00, 0x9D,
83
+ 0xA3, 0xA0, 0x13, 0x00, 0xB2, 0x79, 0x9D, 0xF1, 0xAA, 0xCF,
84
+ 0xBF, 0xE6, 0x5C, 0x12, 0x6E, 0x41, 0x3F, 0xB6, 0xA2, 0x56,
85
+ 0xF7, 0xC7, 0x04, 0x64, 0x6C, 0xA0, 0x05, 0x45, 0x68, 0xF6,
86
+ 0x3C, 0x59, 0x45, 0x9C, 0x7A, 0x28, 0xE7, 0xE3, 0xA5, 0xDA,
87
+ 0xDB, 0xC9, 0xE9, 0xCE, 0xF4, 0xB2, 0x6B, 0xFE, 0xAB, 0x72,
88
+ 0xAD, 0x90, 0x77, 0xD5, 0x62, 0x5B, 0xAB, 0x12, 0x34, 0x9B,
89
+ 0x40, 0x0A, 0x4C, 0x03, 0xBC, 0x53
87
90
  };
88
- static unsigned char dh1024_g[] = { 0x02 };
91
+ static unsigned char dh2048_g[] = { 0x02 };
89
92
 
90
93
  DH *dh;
94
+ #if !(OPENSSL_VERSION_NUMBER < 0x10100005L || defined(LIBRESSL_VERSION_NUMBER))
95
+ BIGNUM *p, *g;
96
+ #endif
97
+
91
98
  dh = DH_new();
92
99
 
93
100
  #if OPENSSL_VERSION_NUMBER < 0x10100005L || defined(LIBRESSL_VERSION_NUMBER)
94
- dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
95
- dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
101
+ dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
102
+ dh->g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
96
103
 
97
104
  if ((dh->p == NULL) || (dh->g == NULL)) {
98
105
  DH_free(dh);
99
106
  return NULL;
100
107
  }
101
108
  #else
102
- BIGNUM *p, *g;
103
- p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
104
- g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
109
+ p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
110
+ g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
105
111
 
106
112
  if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) {
107
113
  DH_free(dh);
@@ -114,6 +120,37 @@ DH *get_dh1024() {
114
120
  return dh;
115
121
  }
116
122
 
123
+ static void
124
+ sslctx_free(void *ptr) {
125
+ SSL_CTX *ctx = ptr;
126
+ SSL_CTX_free(ctx);
127
+ }
128
+
129
+ static const rb_data_type_t sslctx_type = {
130
+ "MiniSSL/SSLContext",
131
+ {
132
+ 0, sslctx_free,
133
+ },
134
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
135
+ };
136
+
137
+ ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
138
+ ms_conn* conn;
139
+
140
+ *obj = TypedData_Make_Struct(klass, ms_conn, &engine_data_type, conn);
141
+
142
+ conn->read = BIO_new(BIO_s_mem());
143
+ BIO_set_nbio(conn->read, 1);
144
+
145
+ conn->write = BIO_new(BIO_s_mem());
146
+ BIO_set_nbio(conn->write, 1);
147
+
148
+ conn->ssl = 0;
149
+ conn->ctx = 0;
150
+
151
+ return conn;
152
+ }
153
+
117
154
  static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
118
155
  X509* err_cert;
119
156
  SSL* ssl;
@@ -140,49 +177,73 @@ static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
140
177
  return preverify_ok;
141
178
  }
142
179
 
143
- VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
144
- VALUE obj;
180
+ static VALUE
181
+ sslctx_alloc(VALUE klass) {
182
+ SSL_CTX *ctx;
183
+ long mode = 0 |
184
+ SSL_MODE_ENABLE_PARTIAL_WRITE |
185
+ SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
186
+ SSL_MODE_RELEASE_BUFFERS;
187
+
188
+ #ifdef HAVE_TLS_SERVER_METHOD
189
+ ctx = SSL_CTX_new(TLS_method());
190
+ // printf("\nctx using TLS_method security_level %d\n", SSL_CTX_get_security_level(ctx));
191
+ #else
192
+ ctx = SSL_CTX_new(SSLv23_method());
193
+ #endif
194
+ if (!ctx) {
195
+ rb_raise(eError, "SSL_CTX_new");
196
+ }
197
+ SSL_CTX_set_mode(ctx, mode);
198
+
199
+ return TypedData_Wrap_Struct(klass, &sslctx_type, ctx);
200
+ }
201
+
202
+ VALUE
203
+ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
145
204
  SSL_CTX* ctx;
146
- SSL* ssl;
147
- int min, ssl_options;
148
205
 
149
- ms_conn* conn = engine_alloc(self, &obj);
206
+ #ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
207
+ int min;
208
+ #endif
209
+ int ssl_options;
210
+ VALUE key, cert, ca, verify_mode, ssl_cipher_filter, no_tlsv1, no_tlsv1_1,
211
+ verification_flags;
212
+ DH *dh;
213
+
214
+ #if OPENSSL_VERSION_NUMBER < 0x10002000L
215
+ EC_KEY *ecdh;
216
+ #endif
150
217
 
151
- ID sym_key = rb_intern("key");
152
- VALUE key = rb_funcall(mini_ssl_ctx, sym_key, 0);
218
+ TypedData_Get_Struct(self, SSL_CTX, &sslctx_type, ctx);
153
219
 
220
+ key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
154
221
  StringValue(key);
155
222
 
156
- ID sym_cert = rb_intern("cert");
157
- VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
158
-
223
+ cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
159
224
  StringValue(cert);
160
225
 
161
- ID sym_ca = rb_intern("ca");
162
- VALUE ca = rb_funcall(mini_ssl_ctx, sym_ca, 0);
226
+ ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
163
227
 
164
- ID sym_verify_mode = rb_intern("verify_mode");
165
- VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
228
+ verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0);
166
229
 
167
- ID sym_ssl_cipher_filter = rb_intern("ssl_cipher_filter");
168
- VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
230
+ ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0);
169
231
 
170
- ID sym_no_tlsv1 = rb_intern("no_tlsv1");
171
- VALUE no_tlsv1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1, 0);
232
+ no_tlsv1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1"), 0);
172
233
 
173
- ID sym_no_tlsv1_1 = rb_intern("no_tlsv1_1");
174
- VALUE no_tlsv1_1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1_1, 0);
175
-
176
- #ifdef HAVE_TLS_SERVER_METHOD
177
- ctx = SSL_CTX_new(TLS_server_method());
178
- #else
179
- ctx = SSL_CTX_new(SSLv23_server_method());
180
- #endif
181
- conn->ctx = ctx;
234
+ no_tlsv1_1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1_1"), 0);
182
235
 
183
236
  SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
184
237
  SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
185
238
 
239
+ verification_flags = rb_funcall(mini_ssl_ctx, rb_intern_const("verification_flags"), 0);
240
+
241
+ if (!NIL_P(verification_flags)) {
242
+ X509_VERIFY_PARAM *param = SSL_CTX_get0_param(ctx);
243
+ X509_VERIFY_PARAM_set_flags(param, NUM2INT(verification_flags));
244
+ SSL_CTX_set1_param(ctx, param);
245
+ }
246
+
186
247
  if (!NIL_P(ca)) {
187
248
  StringValue(ca);
188
249
  SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL);
@@ -228,35 +289,45 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
228
289
  SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
229
290
  }
230
291
 
231
- DH *dh = get_dh1024();
292
+ dh = get_dh2048();
232
293
  SSL_CTX_set_tmp_dh(ctx, dh);
233
294
 
234
295
  #if OPENSSL_VERSION_NUMBER < 0x10002000L
235
296
  // Remove this case if OpenSSL 1.0.1 (now EOL) support is no
236
297
  // longer needed.
237
- EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
298
+ ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
238
299
  if (ecdh) {
239
300
  SSL_CTX_set_tmp_ecdh(ctx, ecdh);
240
301
  EC_KEY_free(ecdh);
241
302
  }
242
303
  #elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
243
- // Prior to OpenSSL 1.1.0, servers must manually enable server-side ECDH
244
- // negotiation.
245
304
  SSL_CTX_set_ecdh_auto(ctx, 1);
246
305
  #endif
247
306
 
248
- ssl = SSL_new(ctx);
249
- conn->ssl = ssl;
250
- SSL_set_app_data(ssl, NULL);
251
-
252
307
  if (NIL_P(verify_mode)) {
253
- /* SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); */
308
+ /* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */
254
309
  } else {
255
- SSL_set_verify(ssl, NUM2INT(verify_mode), engine_verify_callback);
310
+ SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
256
311
  }
312
+ // printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx));
313
+ rb_obj_freeze(self);
314
+ return self;
315
+ }
257
316
 
258
- SSL_set_bio(ssl, conn->read, conn->write);
317
+ VALUE engine_init_server(VALUE self, VALUE sslctx) {
318
+ ms_conn* conn;
319
+ VALUE obj;
320
+ SSL_CTX* ctx;
321
+ SSL* ssl;
322
+
323
+ conn = engine_alloc(self, &obj);
324
+
325
+ TypedData_Get_Struct(sslctx, SSL_CTX, &sslctx_type, ctx);
259
326
 
327
+ ssl = SSL_new(ctx);
328
+ conn->ssl = ssl;
329
+ SSL_set_app_data(ssl, NULL);
330
+ SSL_set_bio(ssl, conn->read, conn->write);
260
331
  SSL_set_accept_state(ssl);
261
332
  return obj;
262
333
  }
@@ -296,7 +367,7 @@ VALUE engine_inject(VALUE self, VALUE str) {
296
367
  return INT2FIX(used);
297
368
  }
298
369
 
299
- static VALUE eError;
370
+ NORETURN(void raise_error(SSL* ssl, int result));
300
371
 
301
372
  void raise_error(SSL* ssl, int result) {
302
373
  char buf[512];
@@ -320,8 +391,7 @@ void raise_error(SSL* ssl, int result) {
320
391
  } else {
321
392
  err = (int) ERR_get_error();
322
393
  ERR_error_string_n(err, buf, sizeof(buf));
323
- int errexp = err & mask;
324
- snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, errexp);
394
+ snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err & mask);
325
395
  }
326
396
  } else {
327
397
  snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err);
@@ -385,7 +455,9 @@ VALUE engine_extract(VALUE self) {
385
455
  ms_conn* conn;
386
456
  int bytes;
387
457
  size_t pending;
388
- char buf[512];
458
+ // https://www.openssl.org/docs/manmaster/man3/BIO_f_buffer.html
459
+ // crypto/bio/bf_buff.c DEFAULT_BUFFER_SIZE
460
+ char buf[4096];
389
461
 
390
462
  TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
391
463
 
@@ -480,7 +552,7 @@ VALUE noop(VALUE self) {
480
552
  }
481
553
 
482
554
  void Init_mini_ssl(VALUE puma) {
483
- VALUE mod, eng;
555
+ VALUE mod, eng, sslctx;
484
556
 
485
557
  /* Fake operation for documentation (RDoc, YARD) */
486
558
  #if 0 == 1
@@ -494,6 +566,11 @@ void Init_mini_ssl(VALUE puma) {
494
566
 
495
567
  mod = rb_define_module_under(puma, "MiniSSL");
496
568
  eng = rb_define_class_under(mod, "Engine", rb_cObject);
569
+ sslctx = rb_define_class_under(mod, "SSLContext", rb_cObject);
570
+ rb_define_alloc_func(sslctx, sslctx_alloc);
571
+ rb_define_method(sslctx, "initialize", sslctx_initialize, 1);
572
+ rb_undef_method(sslctx, "initialize_copy");
573
+
497
574
 
498
575
  // OpenSSL Build / Runtime/Load versions
499
576
 
@@ -552,9 +629,10 @@ void Init_mini_ssl(VALUE puma) {
552
629
 
553
630
  #else
554
631
 
632
+ NORETURN(VALUE raise_error(VALUE self));
633
+
555
634
  VALUE raise_error(VALUE self) {
556
635
  rb_raise(rb_eStandardError, "SSL not available in this build");
557
- return Qnil;
558
636
  }
559
637
 
560
638
  void Init_mini_ssl(VALUE puma) {
@@ -182,8 +182,6 @@ static final int puma_parser_start = 1;
182
182
  static final int puma_parser_first_final = 46;
183
183
  static final int puma_parser_error = 0;
184
184
 
185
- static final int puma_parser_en_main = 1;
186
-
187
185
 
188
186
  // line 62 "ext/puma_http11/http11_parser.java.rl"
189
187
 
@@ -212,12 +210,12 @@ static final int puma_parser_en_main = 1;
212
210
  cs = 0;
213
211
 
214
212
 
215
- // line 218 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
213
+ // line 214 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
216
214
  {
217
215
  cs = puma_parser_start;
218
216
  }
219
217
 
220
- // line 90 "ext/puma_http11/http11_parser.java.rl"
218
+ // line 88 "ext/puma_http11/http11_parser.java.rl"
221
219
 
222
220
  body_start = 0;
223
221
  content_len = 0;
@@ -244,7 +242,7 @@ static final int puma_parser_en_main = 1;
244
242
  parser.buffer = buffer;
245
243
 
246
244
 
247
- // line 250 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
245
+ // line 246 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
248
246
  {
249
247
  int _klen;
250
248
  int _trans = 0;
@@ -400,7 +398,7 @@ case 1:
400
398
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
401
399
  }
402
400
  break;
403
- // line 406 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
401
+ // line 402 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
404
402
  }
405
403
  }
406
404
  }
@@ -420,7 +418,7 @@ case 5:
420
418
  break; }
421
419
  }
422
420
 
423
- // line 116 "ext/puma_http11/http11_parser.java.rl"
421
+ // line 114 "ext/puma_http11/http11_parser.java.rl"
424
422
 
425
423
  parser.cs = cs;
426
424
  parser.nread += (p - off);
@@ -40,7 +40,9 @@ static VALUE global_http_version;
40
40
  static VALUE global_request_path;
41
41
 
42
42
  /** Defines common length and error messages for input length validation. */
43
- #define DEF_MAX_LENGTH(N,length) const size_t MAX_##N##_LENGTH = length; const char *MAX_##N##_LENGTH_ERR = "HTTP element " # N " is longer than the " # length " allowed length (was %d)"
43
+ #define QUOTE(s) #s
44
+ #define EXPLAIN_MAX_LENGTH_VALUE(s) QUOTE(s)
45
+ #define DEF_MAX_LENGTH(N,length) const size_t MAX_##N##_LENGTH = length; const char *MAX_##N##_LENGTH_ERR = "HTTP element " # N " is longer than the " EXPLAIN_MAX_LENGTH_VALUE(length) " allowed length (was %d)"
44
46
 
45
47
  /** Validates the max length of given input and throws an HttpParserError exception if over. */
46
48
  #define VALIDATE_MAX_LENGTH(len, N) if(len > MAX_##N##_LENGTH) { rb_raise(eHttpParserError, MAX_##N##_LENGTH_ERR, len); }
@@ -50,12 +52,16 @@ static VALUE global_request_path;
50
52
 
51
53
 
52
54
  /* Defines the maximum allowed lengths for various input elements.*/
55
+ #ifndef PUMA_QUERY_STRING_MAX_LENGTH
56
+ #define PUMA_QUERY_STRING_MAX_LENGTH (1024 * 10)
57
+ #endif
58
+
53
59
  DEF_MAX_LENGTH(FIELD_NAME, 256);
54
60
  DEF_MAX_LENGTH(FIELD_VALUE, 80 * 1024);
55
61
  DEF_MAX_LENGTH(REQUEST_URI, 1024 * 12);
56
62
  DEF_MAX_LENGTH(FRAGMENT, 1024); /* Don't know if this length is specified somewhere or not */
57
63
  DEF_MAX_LENGTH(REQUEST_PATH, 8192);
58
- DEF_MAX_LENGTH(QUERY_STRING, (1024 * 10));
64
+ DEF_MAX_LENGTH(QUERY_STRING, PUMA_QUERY_STRING_MAX_LENGTH);
59
65
  DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32)));
60
66
 
61
67
  struct common_field {