puma 4.1.1 → 5.0.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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +149 -10
  3. data/LICENSE +23 -20
  4. data/README.md +30 -46
  5. data/docs/architecture.md +3 -3
  6. data/docs/deployment.md +9 -3
  7. data/docs/fork_worker.md +31 -0
  8. data/docs/jungle/README.md +13 -0
  9. data/{tools → docs}/jungle/rc.d/README.md +0 -0
  10. data/{tools → docs}/jungle/rc.d/puma +0 -0
  11. data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
  12. data/{tools → docs}/jungle/upstart/README.md +0 -0
  13. data/{tools → docs}/jungle/upstart/puma-manager.conf +0 -0
  14. data/{tools → docs}/jungle/upstart/puma.conf +0 -0
  15. data/docs/plugins.md +20 -10
  16. data/docs/signals.md +7 -6
  17. data/docs/systemd.md +1 -63
  18. data/ext/puma_http11/PumaHttp11Service.java +2 -4
  19. data/ext/puma_http11/extconf.rb +6 -0
  20. data/ext/puma_http11/http11_parser.c +40 -63
  21. data/ext/puma_http11/http11_parser.java.rl +21 -37
  22. data/ext/puma_http11/http11_parser.rl +3 -1
  23. data/ext/puma_http11/http11_parser_common.rl +3 -3
  24. data/ext/puma_http11/mini_ssl.c +15 -2
  25. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  26. data/ext/puma_http11/org/jruby/puma/Http11.java +108 -116
  27. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +91 -106
  28. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +77 -18
  29. data/ext/puma_http11/puma_http11.c +9 -38
  30. data/lib/puma.rb +23 -0
  31. data/lib/puma/app/status.rb +46 -30
  32. data/lib/puma/binder.rb +112 -124
  33. data/lib/puma/cli.rb +11 -15
  34. data/lib/puma/client.rb +250 -209
  35. data/lib/puma/cluster.rb +203 -85
  36. data/lib/puma/commonlogger.rb +2 -2
  37. data/lib/puma/configuration.rb +31 -42
  38. data/lib/puma/const.rb +24 -19
  39. data/lib/puma/control_cli.rb +46 -17
  40. data/lib/puma/detect.rb +17 -0
  41. data/lib/puma/dsl.rb +162 -70
  42. data/lib/puma/error_logger.rb +97 -0
  43. data/lib/puma/events.rb +35 -31
  44. data/lib/puma/io_buffer.rb +9 -2
  45. data/lib/puma/jruby_restart.rb +0 -58
  46. data/lib/puma/launcher.rb +117 -58
  47. data/lib/puma/minissl.rb +60 -18
  48. data/lib/puma/minissl/context_builder.rb +73 -0
  49. data/lib/puma/null_io.rb +1 -1
  50. data/lib/puma/plugin.rb +6 -12
  51. data/lib/puma/rack/builder.rb +0 -4
  52. data/lib/puma/reactor.rb +16 -9
  53. data/lib/puma/runner.rb +11 -32
  54. data/lib/puma/server.rb +173 -193
  55. data/lib/puma/single.rb +7 -64
  56. data/lib/puma/state_file.rb +6 -3
  57. data/lib/puma/thread_pool.rb +104 -81
  58. data/lib/rack/handler/puma.rb +1 -5
  59. data/tools/Dockerfile +16 -0
  60. data/tools/trickletest.rb +0 -1
  61. metadata +23 -24
  62. data/ext/puma_http11/io_buffer.c +0 -155
  63. data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -72
  64. data/lib/puma/convenient.rb +0 -25
  65. data/lib/puma/daemon_ext.rb +0 -33
  66. data/lib/puma/delegation.rb +0 -13
  67. data/lib/puma/tcp_logger.rb +0 -41
  68. data/tools/jungle/README.md +0 -19
  69. data/tools/jungle/init.d/README.md +0 -61
  70. data/tools/jungle/init.d/puma +0 -421
  71. data/tools/jungle/init.d/run-puma +0 -18
@@ -2,6 +2,8 @@
2
2
  // line 1 "ext/puma_http11/http11_parser.java.rl"
3
3
  package org.jruby.puma;
4
4
 
5
+ import org.jruby.Ruby;
6
+ import org.jruby.RubyHash;
5
7
  import org.jruby.util.ByteList;
6
8
 
7
9
  public class Http11Parser {
@@ -9,12 +11,12 @@ public class Http11Parser {
9
11
  /** Machine **/
10
12
 
11
13
 
12
- // line 65 "ext/puma_http11/http11_parser.java.rl"
14
+ // line 58 "ext/puma_http11/http11_parser.java.rl"
13
15
 
14
16
 
15
17
  /** Data **/
16
18
 
17
- // line 18 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
19
+ // line 20 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
18
20
  private static byte[] init__puma_parser_actions_0()
19
21
  {
20
22
  return new byte [] {
@@ -33,8 +35,8 @@ private static short[] init__puma_parser_key_offsets_0()
33
35
  return new short [] {
34
36
  0, 0, 8, 17, 27, 29, 30, 31, 32, 33, 34, 36,
35
37
  39, 41, 44, 45, 61, 62, 78, 80, 81, 89, 97, 107,
36
- 115, 125, 134, 142, 150, 159, 168, 177, 186, 195, 204, 213,
37
- 222, 231, 240, 249, 258, 267, 276, 285, 294, 303, 312, 313
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
38
40
  };
39
41
  }
40
42
 
@@ -53,24 +55,23 @@ private static char[] init__puma_parser_trans_keys_0()
53
55
  48, 57, 65, 90, 94, 122, 13, 32, 13, 32, 60, 62,
54
56
  127, 0, 31, 34, 35, 32, 60, 62, 127, 0, 31, 34,
55
57
  35, 43, 58, 45, 46, 48, 57, 65, 90, 97, 122, 32,
56
- 34, 35, 60, 62, 127, 0, 31, 32, 34, 35, 59, 60,
57
- 62, 63, 127, 0, 31, 32, 34, 35, 60, 62, 63, 127,
58
- 0, 31, 32, 34, 35, 60, 62, 127, 0, 31, 32, 34,
59
- 35, 60, 62, 127, 0, 31, 32, 36, 95, 45, 46, 48,
60
- 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
61
- 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
62
- 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
63
- 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
64
- 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
65
- 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
66
- 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
67
- 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
68
- 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
69
- 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
70
- 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
71
- 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
72
- 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
73
- 32, 0
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
74
75
  };
75
76
  }
76
77
 
@@ -82,8 +83,8 @@ private static byte[] init__puma_parser_single_lengths_0()
82
83
  return new byte [] {
83
84
  0, 2, 3, 4, 2, 1, 1, 1, 1, 1, 0, 1,
84
85
  0, 1, 1, 4, 1, 4, 2, 1, 4, 4, 2, 6,
85
- 8, 7, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
86
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0
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
87
88
  };
88
89
  }
89
90
 
@@ -95,8 +96,8 @@ private static byte[] init__puma_parser_range_lengths_0()
95
96
  return new byte [] {
96
97
  0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 1,
97
98
  1, 1, 0, 6, 0, 6, 0, 0, 2, 2, 4, 1,
98
- 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3,
99
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0
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
100
101
  };
101
102
  }
102
103
 
@@ -108,8 +109,8 @@ private static short[] init__puma_parser_index_offsets_0()
108
109
  return new short [] {
109
110
  0, 0, 6, 13, 21, 24, 26, 28, 30, 32, 34, 36,
110
111
  39, 41, 44, 46, 57, 59, 70, 73, 75, 82, 89, 96,
111
- 104, 114, 123, 131, 139, 146, 153, 160, 167, 174, 181, 188,
112
- 195, 202, 209, 216, 223, 230, 237, 244, 251, 258, 265, 267
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
113
114
  };
114
115
  }
115
116
 
@@ -127,21 +128,20 @@ private static byte[] init__puma_parser_indicies_0()
127
128
  24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27,
128
129
  25, 29, 28, 30, 1, 1, 1, 1, 1, 31, 32, 1,
129
130
  1, 1, 1, 1, 33, 34, 35, 34, 34, 34, 34, 1,
130
- 8, 1, 9, 1, 1, 1, 1, 35, 36, 1, 38, 39,
131
- 1, 1, 40, 1, 1, 37, 8, 1, 9, 1, 1, 42,
132
- 1, 1, 41, 43, 1, 45, 1, 1, 1, 1, 44, 46,
133
- 1, 48, 1, 1, 1, 1, 47, 2, 49, 49, 49, 49,
134
- 49, 1, 2, 50, 50, 50, 50, 50, 1, 2, 51, 51,
135
- 51, 51, 51, 1, 2, 52, 52, 52, 52, 52, 1, 2,
136
- 53, 53, 53, 53, 53, 1, 2, 54, 54, 54, 54, 54,
137
- 1, 2, 55, 55, 55, 55, 55, 1, 2, 56, 56, 56,
138
- 56, 56, 1, 2, 57, 57, 57, 57, 57, 1, 2, 58,
139
- 58, 58, 58, 58, 1, 2, 59, 59, 59, 59, 59, 1,
140
- 2, 60, 60, 60, 60, 60, 1, 2, 61, 61, 61, 61,
141
- 61, 1, 2, 62, 62, 62, 62, 62, 1, 2, 63, 63,
142
- 63, 63, 63, 1, 2, 64, 64, 64, 64, 64, 1, 2,
143
- 65, 65, 65, 65, 65, 1, 2, 66, 66, 66, 66, 66,
144
- 1, 2, 1, 1, 0
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
145
  };
146
146
  }
147
147
 
@@ -151,12 +151,12 @@ private static final byte _puma_parser_indicies[] = init__puma_parser_indicies_0
151
151
  private static byte[] init__puma_parser_trans_targs_0()
152
152
  {
153
153
  return new byte [] {
154
- 2, 0, 3, 28, 4, 22, 24, 23, 5, 20, 6, 7,
155
- 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 47, 17,
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
156
  18, 19, 14, 18, 19, 14, 5, 21, 5, 21, 22, 23,
157
- 5, 24, 20, 25, 26, 25, 26, 5, 27, 20, 5, 27,
158
- 20, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
159
- 40, 41, 42, 43, 44, 45, 46
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
160
  };
161
161
  }
162
162
 
@@ -169,9 +169,9 @@ private static byte[] init__puma_parser_trans_actions_0()
169
169
  1, 0, 11, 0, 1, 1, 1, 1, 13, 13, 1, 0,
170
170
  0, 0, 0, 0, 0, 0, 19, 0, 0, 28, 23, 3,
171
171
  5, 7, 31, 7, 0, 9, 25, 1, 15, 0, 0, 0,
172
- 37, 0, 37, 21, 21, 0, 0, 40, 17, 40, 34, 0,
173
- 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
174
- 0, 0, 0, 0, 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
175
  };
176
176
  }
177
177
 
@@ -179,17 +179,20 @@ private static final byte _puma_parser_trans_actions[] = init__puma_parser_trans
179
179
 
180
180
 
181
181
  static final int puma_parser_start = 1;
182
- static final int puma_parser_first_final = 47;
182
+ static final int puma_parser_first_final = 46;
183
183
  static final int puma_parser_error = 0;
184
184
 
185
- // line 69 "ext/puma_http11/http11_parser.java.rl"
185
+ static final int puma_parser_en_main = 1;
186
+
187
+
188
+ // line 62 "ext/puma_http11/http11_parser.java.rl"
186
189
 
187
190
  public static interface ElementCB {
188
- public void call(Object data, int at, int length);
191
+ public void call(Ruby runtime, RubyHash data, ByteList buffer, int at, int length);
189
192
  }
190
193
 
191
194
  public static interface FieldCB {
192
- public void call(Object data, int field, int flen, int value, int vlen);
195
+ public void call(Ruby runtime, RubyHash data, ByteList buffer, int field, int flen, int value, int vlen);
193
196
  }
194
197
 
195
198
  public static class HttpParser {
@@ -202,28 +205,19 @@ static final int puma_parser_error = 0;
202
205
  int field_len;
203
206
  int query_start;
204
207
 
205
- Object data;
208
+ RubyHash data;
206
209
  ByteList buffer;
207
210
 
208
- public FieldCB http_field;
209
- public ElementCB request_method;
210
- public ElementCB request_uri;
211
- public ElementCB fragment;
212
- public ElementCB request_path;
213
- public ElementCB query_string;
214
- public ElementCB http_version;
215
- public ElementCB header_done;
216
-
217
211
  public void init() {
218
212
  cs = 0;
219
213
 
220
-
221
- // line 225 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
214
+
215
+ // line 218 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
222
216
  {
223
217
  cs = puma_parser_start;
224
218
  }
225
219
 
226
- // line 104 "ext/puma_http11/http11_parser.java.rl"
220
+ // line 90 "ext/puma_http11/http11_parser.java.rl"
227
221
 
228
222
  body_start = 0;
229
223
  content_len = 0;
@@ -236,7 +230,7 @@ static final int puma_parser_error = 0;
236
230
 
237
231
  public final HttpParser parser = new HttpParser();
238
232
 
239
- public int execute(ByteList buffer, int off) {
233
+ public int execute(Ruby runtime, Http11 http, ByteList buffer, int off) {
240
234
  int p, pe;
241
235
  int cs = parser.cs;
242
236
  int len = buffer.length();
@@ -249,8 +243,8 @@ static final int puma_parser_error = 0;
249
243
  byte[] data = buffer.bytes();
250
244
  parser.buffer = buffer;
251
245
 
252
-
253
- // line 257 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
246
+
247
+ // line 250 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
254
248
  {
255
249
  int _klen;
256
250
  int _trans = 0;
@@ -331,91 +325,82 @@ case 1:
331
325
  switch ( _puma_parser_actions[_acts++] )
332
326
  {
333
327
  case 0:
334
- // line 13 "ext/puma_http11/http11_parser.java.rl"
328
+ // line 15 "ext/puma_http11/http11_parser.java.rl"
335
329
  {parser.mark = p; }
336
330
  break;
337
331
  case 1:
338
- // line 15 "ext/puma_http11/http11_parser.java.rl"
332
+ // line 17 "ext/puma_http11/http11_parser.java.rl"
339
333
  { parser.field_start = p; }
340
334
  break;
341
335
  case 2:
342
- // line 16 "ext/puma_http11/http11_parser.java.rl"
336
+ // line 18 "ext/puma_http11/http11_parser.java.rl"
343
337
  { /* FIXME stub */ }
344
338
  break;
345
339
  case 3:
346
- // line 17 "ext/puma_http11/http11_parser.java.rl"
347
- {
340
+ // line 19 "ext/puma_http11/http11_parser.java.rl"
341
+ {
348
342
  parser.field_len = p-parser.field_start;
349
343
  }
350
344
  break;
351
345
  case 4:
352
- // line 21 "ext/puma_http11/http11_parser.java.rl"
346
+ // line 23 "ext/puma_http11/http11_parser.java.rl"
353
347
  { parser.mark = p; }
354
348
  break;
355
349
  case 5:
356
- // line 22 "ext/puma_http11/http11_parser.java.rl"
350
+ // line 24 "ext/puma_http11/http11_parser.java.rl"
357
351
  {
358
- if(parser.http_field != null) {
359
- parser.http_field.call(parser.data, parser.field_start, parser.field_len, parser.mark, p-parser.mark);
360
- }
352
+ Http11.http_field(runtime, parser.data, parser.buffer, parser.field_start, parser.field_len, parser.mark, p-parser.mark);
361
353
  }
362
354
  break;
363
355
  case 6:
364
356
  // line 27 "ext/puma_http11/http11_parser.java.rl"
365
357
  {
366
- if(parser.request_method != null)
367
- parser.request_method.call(parser.data, parser.mark, p-parser.mark);
358
+ Http11.request_method(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
368
359
  }
369
360
  break;
370
361
  case 7:
371
- // line 31 "ext/puma_http11/http11_parser.java.rl"
362
+ // line 30 "ext/puma_http11/http11_parser.java.rl"
372
363
  {
373
- if(parser.request_uri != null)
374
- parser.request_uri.call(parser.data, parser.mark, p-parser.mark);
364
+ Http11.request_uri(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
375
365
  }
376
366
  break;
377
367
  case 8:
378
- // line 35 "ext/puma_http11/http11_parser.java.rl"
368
+ // line 33 "ext/puma_http11/http11_parser.java.rl"
379
369
  {
380
- if(parser.fragment != null)
381
- parser.fragment.call(parser.data, parser.mark, p-parser.mark);
370
+ Http11.fragment(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
382
371
  }
383
372
  break;
384
373
  case 9:
385
- // line 40 "ext/puma_http11/http11_parser.java.rl"
374
+ // line 37 "ext/puma_http11/http11_parser.java.rl"
386
375
  {parser.query_start = p; }
387
376
  break;
388
377
  case 10:
389
- // line 41 "ext/puma_http11/http11_parser.java.rl"
378
+ // line 38 "ext/puma_http11/http11_parser.java.rl"
390
379
  {
391
- if(parser.query_string != null)
392
- parser.query_string.call(parser.data, parser.query_start, p-parser.query_start);
380
+ Http11.query_string(runtime, parser.data, parser.buffer, parser.query_start, p-parser.query_start);
393
381
  }
394
382
  break;
395
383
  case 11:
396
- // line 46 "ext/puma_http11/http11_parser.java.rl"
384
+ // line 42 "ext/puma_http11/http11_parser.java.rl"
397
385
  {
398
- if(parser.http_version != null)
399
- parser.http_version.call(parser.data, parser.mark, p-parser.mark);
386
+ Http11.http_version(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
400
387
  }
401
388
  break;
402
389
  case 12:
403
- // line 51 "ext/puma_http11/http11_parser.java.rl"
390
+ // line 46 "ext/puma_http11/http11_parser.java.rl"
404
391
  {
405
- if(parser.request_path != null)
406
- parser.request_path.call(parser.data, parser.mark, p-parser.mark);
392
+ Http11.request_path(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
407
393
  }
408
394
  break;
409
395
  case 13:
410
- // line 56 "ext/puma_http11/http11_parser.java.rl"
411
- {
396
+ // line 50 "ext/puma_http11/http11_parser.java.rl"
397
+ {
412
398
  parser.body_start = p + 1;
413
- if(parser.header_done != null)
414
- parser.header_done.call(parser.data, p + 1, pe - p - 1);
399
+ http.header_done(runtime, parser.data, parser.buffer, p + 1, pe - p - 1);
415
400
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
416
401
  }
417
402
  break;
418
- // line 422 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
403
+ // line 406 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
419
404
  }
420
405
  }
421
406
  }
@@ -435,11 +420,11 @@ case 5:
435
420
  break; }
436
421
  }
437
422
 
438
- // line 130 "ext/puma_http11/http11_parser.java.rl"
423
+ // line 116 "ext/puma_http11/http11_parser.java.rl"
439
424
 
440
425
  parser.cs = cs;
441
426
  parser.nread += (p - off);
442
-
427
+
443
428
  assert p <= pe : "buffer overflow after parsing execute";
444
429
  assert parser.nread <= len : "nread longer than length";
445
430
  assert parser.body_start <= len : "body starts after buffer end";
@@ -22,6 +22,7 @@ import javax.net.ssl.SSLException;
22
22
  import javax.net.ssl.SSLPeerUnverifiedException;
23
23
  import javax.net.ssl.SSLSession;
24
24
  import java.io.FileInputStream;
25
+ import java.io.InputStream;
25
26
  import java.io.IOException;
26
27
  import java.nio.Buffer;
27
28
  import java.nio.ByteBuffer;
@@ -32,6 +33,8 @@ import java.security.NoSuchAlgorithmException;
32
33
  import java.security.UnrecoverableKeyException;
33
34
  import java.security.cert.CertificateEncodingException;
34
35
  import java.security.cert.CertificateException;
36
+ import java.util.concurrent.ConcurrentHashMap;
37
+ import java.util.Map;
35
38
 
36
39
  import static javax.net.ssl.SSLEngineResult.Status;
37
40
  import static javax.net.ssl.SSLEngineResult.HandshakeStatus;
@@ -120,6 +123,8 @@ public class MiniSSL extends RubyObject {
120
123
  }
121
124
 
122
125
  private SSLEngine engine;
126
+ private boolean closed;
127
+ private boolean handshake;
123
128
  private MiniSSLBuffer inboundNetData;
124
129
  private MiniSSLBuffer outboundAppData;
125
130
  private MiniSSLBuffer outboundNetData;
@@ -128,10 +133,39 @@ public class MiniSSL extends RubyObject {
128
133
  super(runtime, klass);
129
134
  }
130
135
 
136
+ private static Map<String, KeyManagerFactory> keyManagerFactoryMap = new ConcurrentHashMap<String, KeyManagerFactory>();
137
+ private static Map<String, TrustManagerFactory> trustManagerFactoryMap = new ConcurrentHashMap<String, TrustManagerFactory>();
138
+
131
139
  @JRubyMethod(meta = true)
132
- public static IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext) {
133
- RubyClass klass = (RubyClass) recv;
140
+ public static synchronized IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
141
+ throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
142
+ // Create the KeyManagerFactory and TrustManagerFactory for this server
143
+ String keystoreFile = miniSSLContext.callMethod(context, "keystore").convertToString().asJavaString();
144
+ char[] password = miniSSLContext.callMethod(context, "keystore_pass").convertToString().asJavaString().toCharArray();
134
145
 
146
+ KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
147
+ InputStream is = new FileInputStream(keystoreFile);
148
+ try {
149
+ ks.load(is, password);
150
+ } finally {
151
+ is.close();
152
+ }
153
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
154
+ kmf.init(ks, password);
155
+ keyManagerFactoryMap.put(keystoreFile, kmf);
156
+
157
+ KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
158
+ is = new FileInputStream(keystoreFile);
159
+ try {
160
+ ts.load(is, password);
161
+ } finally {
162
+ is.close();
163
+ }
164
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
165
+ tmf.init(ts);
166
+ trustManagerFactoryMap.put(keystoreFile, tmf);
167
+
168
+ RubyClass klass = (RubyClass) recv;
135
169
  return klass.newInstance(context,
136
170
  new IRubyObject[] { miniSSLContext },
137
171
  Block.NULL_BLOCK);
@@ -139,24 +173,22 @@ public class MiniSSL extends RubyObject {
139
173
 
140
174
  @JRubyMethod
141
175
  public IRubyObject initialize(ThreadContext threadContext, IRubyObject miniSSLContext)
142
- throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
176
+ throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
143
177
  KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
144
178
  KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
145
179
 
146
- char[] password = miniSSLContext.callMethod(threadContext, "keystore_pass").convertToString().asJavaString().toCharArray();
147
180
  String keystoreFile = miniSSLContext.callMethod(threadContext, "keystore").convertToString().asJavaString();
148
- ks.load(new FileInputStream(keystoreFile), password);
149
- ts.load(new FileInputStream(keystoreFile), password);
150
-
151
- KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
152
- kmf.init(ks, password);
153
-
154
- TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
155
- tmf.init(ts);
181
+ KeyManagerFactory kmf = keyManagerFactoryMap.get(keystoreFile);
182
+ TrustManagerFactory tmf = trustManagerFactoryMap.get(keystoreFile);
183
+ if(kmf == null || tmf == null) {
184
+ throw new KeyStoreException("Could not find KeyManagerFactory/TrustManagerFactory for keystore: " + keystoreFile);
185
+ }
156
186
 
157
187
  SSLContext sslCtx = SSLContext.getInstance("TLS");
158
188
 
159
189
  sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
190
+ closed = false;
191
+ handshake = false;
160
192
  engine = sslCtx.createSSLEngine();
161
193
 
162
194
  String[] protocols;
@@ -173,7 +205,7 @@ public class MiniSSL extends RubyObject {
173
205
  engine.setEnabledProtocols(protocols);
174
206
  engine.setUseClientMode(false);
175
207
 
176
- long verify_mode = miniSSLContext.callMethod(threadContext, "verify_mode").convertToInteger().getLongValue();
208
+ long verify_mode = miniSSLContext.callMethod(threadContext, "verify_mode").convertToInteger("to_i").getLongValue();
177
209
  if ((verify_mode & 0x1) != 0) { // 'peer'
178
210
  engine.setWantClientAuth(true);
179
211
  }
@@ -240,14 +272,21 @@ public class MiniSSL extends RubyObject {
240
272
  // need to wait for more data to come in before we retry
241
273
  retryOp = false;
242
274
  break;
275
+ case CLOSED:
276
+ closed = true;
277
+ retryOp = false;
278
+ break;
243
279
  default:
244
- // other cases are OK and CLOSED. We're done here.
280
+ // other case is OK. We're done here.
245
281
  retryOp = false;
246
282
  }
283
+ if (res.getHandshakeStatus() == HandshakeStatus.FINISHED) {
284
+ handshake = true;
285
+ }
247
286
  }
248
287
 
249
288
  // after each op, run any delegated tasks if needed
250
- if(engine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
289
+ if(res.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
251
290
  Runnable runnable;
252
291
  while ((runnable = engine.getDelegatedTask()) != null) {
253
292
  runnable.run();
@@ -271,13 +310,14 @@ public class MiniSSL extends RubyObject {
271
310
 
272
311
  HandshakeStatus handshakeStatus = engine.getHandshakeStatus();
273
312
  boolean done = false;
313
+ SSLEngineResult res = null;
274
314
  while (!done) {
275
315
  switch (handshakeStatus) {
276
316
  case NEED_WRAP:
277
- doOp(SSLOperation.WRAP, inboundAppData, outboundNetData);
317
+ res = doOp(SSLOperation.WRAP, inboundAppData, outboundNetData);
278
318
  break;
279
319
  case NEED_UNWRAP:
280
- SSLEngineResult res = doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData);
320
+ res = doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData);
281
321
  if (res.getStatus() == Status.BUFFER_UNDERFLOW) {
282
322
  // need more data before we can shake more hands
283
323
  done = true;
@@ -286,7 +326,9 @@ public class MiniSSL extends RubyObject {
286
326
  default:
287
327
  done = true;
288
328
  }
289
- handshakeStatus = engine.getHandshakeStatus();
329
+ if (!done) {
330
+ handshakeStatus = res.getHandshakeStatus();
331
+ }
290
332
  }
291
333
 
292
334
  if (inboundNetData.hasRemaining()) {
@@ -360,4 +402,21 @@ public class MiniSSL extends RubyObject {
360
402
  return getRuntime().getNil();
361
403
  }
362
404
  }
405
+
406
+ @JRubyMethod(name = "init?")
407
+ public IRubyObject isInit(ThreadContext context) {
408
+ return handshake ? getRuntime().getFalse() : getRuntime().getTrue();
409
+ }
410
+
411
+ @JRubyMethod
412
+ public IRubyObject shutdown() {
413
+ if (closed || engine.isInboundDone() && engine.isOutboundDone()) {
414
+ if (engine.isOutboundDone()) {
415
+ engine.closeOutbound();
416
+ }
417
+ return getRuntime().getTrue();
418
+ } else {
419
+ return getRuntime().getFalse();
420
+ }
421
+ }
363
422
  }