puma 0.8.1 → 0.8.2
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.
- data/Gemfile +6 -0
- data/Manifest.txt +7 -4
- data/Rakefile +2 -0
- data/ext/puma_http11/{Http11Service.java → PumaHttp11Service.java} +2 -2
- data/ext/puma_http11/http11_parser.java.rl +4 -2
- data/ext/puma_http11/org/jruby/{mongrel → puma}/Http11.java +21 -37
- data/ext/puma_http11/org/jruby/{mongrel → puma}/Http11Parser.java +27 -25
- data/lib/puma/cli.rb +39 -6
- data/lib/puma/const.rb +1 -1
- data/lib/puma/rack_patch.rb +22 -0
- data/lib/puma/server.rb +14 -7
- data/lib/rack/handler/puma.rb +17 -2
- data/puma.gemspec +7 -7
- data/tasks/gem.rake +1 -1
- data/tasks/java.rake +2 -2
- data/tasks/native.rake +29 -18
- data/tasks/ragel.rake +7 -3
- data/test/test_cli.rb +19 -0
- data/test/test_persistent.rb +48 -2
- data/test/test_rack_server.rb +10 -1
- data/test/test_unix_socket.rb +31 -28
- metadata +15 -11
data/Gemfile
ADDED
data/Manifest.txt
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
COPYING
|
2
|
+
Gemfile
|
2
3
|
History.txt
|
3
4
|
LICENSE
|
4
5
|
Manifest.txt
|
@@ -17,23 +18,24 @@ examples/monitrc
|
|
17
18
|
examples/random_thrash.rb
|
18
19
|
examples/simpletest.rb
|
19
20
|
examples/webrick_compare.rb
|
20
|
-
ext/puma_http11/
|
21
|
+
ext/puma_http11/PumaHttp11Service.java
|
21
22
|
ext/puma_http11/ext_help.h
|
22
23
|
ext/puma_http11/extconf.rb
|
23
|
-
ext/puma_http11/puma_http11.c
|
24
24
|
ext/puma_http11/http11_parser.c
|
25
25
|
ext/puma_http11/http11_parser.h
|
26
26
|
ext/puma_http11/http11_parser.java.rl
|
27
27
|
ext/puma_http11/http11_parser.rl
|
28
28
|
ext/puma_http11/http11_parser_common.rl
|
29
|
-
ext/puma_http11/org/jruby/
|
30
|
-
ext/puma_http11/org/jruby/
|
29
|
+
ext/puma_http11/org/jruby/puma/Http11.java
|
30
|
+
ext/puma_http11/org/jruby/puma/Http11Parser.java
|
31
|
+
ext/puma_http11/puma_http11.c
|
31
32
|
lib/puma.rb
|
32
33
|
lib/puma/cli.rb
|
33
34
|
lib/puma/const.rb
|
34
35
|
lib/puma/events.rb
|
35
36
|
lib/puma/gems.rb
|
36
37
|
lib/puma/mime_types.yml
|
38
|
+
lib/puma/rack_patch.rb
|
37
39
|
lib/puma/server.rb
|
38
40
|
lib/puma/thread_pool.rb
|
39
41
|
lib/puma/utils.rb
|
@@ -45,6 +47,7 @@ tasks/native.rake
|
|
45
47
|
tasks/ragel.rake
|
46
48
|
test/lobster.ru
|
47
49
|
test/mime.yaml
|
50
|
+
test/test_cli.rb
|
48
51
|
test/test_http10.rb
|
49
52
|
test/test_http11.rb
|
50
53
|
test/test_persistent.rb
|
data/Rakefile
CHANGED
@@ -3,9 +3,9 @@ import java.io.IOException;
|
|
3
3
|
import org.jruby.Ruby;
|
4
4
|
import org.jruby.runtime.load.BasicLibraryService;
|
5
5
|
|
6
|
-
import org.jruby.
|
6
|
+
import org.jruby.puma.Http11;
|
7
7
|
|
8
|
-
public class
|
8
|
+
public class PumaHttp11Service implements BasicLibraryService {
|
9
9
|
public boolean basicLoad(final Ruby runtime) throws IOException {
|
10
10
|
Http11.createHttp11(runtime);
|
11
11
|
return true;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
package org.jruby.
|
1
|
+
package org.jruby.puma;
|
2
2
|
|
3
3
|
import org.jruby.util.ByteList;
|
4
4
|
|
@@ -121,7 +121,9 @@ public class Http11Parser {
|
|
121
121
|
|
122
122
|
p = off;
|
123
123
|
pe = len;
|
124
|
-
|
124
|
+
// get a copy of the bytes, since it may not start at 0
|
125
|
+
// FIXME: figure out how to just use the bytes in-place
|
126
|
+
byte[] data = buffer.bytes();
|
125
127
|
parser.buffer = buffer;
|
126
128
|
|
127
129
|
%% write exec;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
package org.jruby.
|
1
|
+
package org.jruby.puma;
|
2
2
|
|
3
3
|
import org.jruby.Ruby;
|
4
4
|
import org.jruby.RubyClass;
|
@@ -45,21 +45,22 @@ public class Http11 extends RubyObject {
|
|
45
45
|
};
|
46
46
|
|
47
47
|
public static void createHttp11(Ruby runtime) {
|
48
|
-
RubyModule
|
49
|
-
|
48
|
+
RubyModule mPuma = runtime.defineModule("Puma");
|
49
|
+
mPuma.defineClassUnder("HttpParserError",runtime.getClass("IOError"),runtime.getClass("IOError").getAllocator());
|
50
50
|
|
51
|
-
RubyClass cHttpParser =
|
51
|
+
RubyClass cHttpParser = mPuma.defineClassUnder("HttpParser",runtime.getObject(),ALLOCATOR);
|
52
52
|
cHttpParser.defineAnnotatedMethods(Http11.class);
|
53
53
|
}
|
54
54
|
|
55
55
|
private Ruby runtime;
|
56
56
|
private RubyClass eHttpParserError;
|
57
57
|
private Http11Parser hp;
|
58
|
+
private RubyString body;
|
58
59
|
|
59
60
|
public Http11(Ruby runtime, RubyClass clazz) {
|
60
61
|
super(runtime,clazz);
|
61
62
|
this.runtime = runtime;
|
62
|
-
this.eHttpParserError = (RubyClass)runtime.getModule("
|
63
|
+
this.eHttpParserError = (RubyClass)runtime.getModule("Puma").getConstant("HttpParserError");
|
63
64
|
this.hp = new Http11Parser();
|
64
65
|
this.hp.parser.http_field = http_field;
|
65
66
|
this.hp.parser.request_method = request_method;
|
@@ -86,7 +87,6 @@ public class Http11 extends RubyObject {
|
|
86
87
|
validateMaxLength(vlen, MAX_FIELD_VALUE_LENGTH, MAX_FIELD_VALUE_LENGTH_ERR);
|
87
88
|
|
88
89
|
v = RubyString.newString(runtime, new ByteList(Http11.this.hp.parser.buffer,value,vlen));
|
89
|
-
f = RubyString.newString(runtime, "HTTP_");
|
90
90
|
ByteList b = new ByteList(Http11.this.hp.parser.buffer,field,flen);
|
91
91
|
for(int i = 0,j = b.length();i<j;i++) {
|
92
92
|
if((b.get(i) & 0xFF) == '-') {
|
@@ -95,7 +95,15 @@ public class Http11 extends RubyObject {
|
|
95
95
|
b.set(i, (byte)Character.toUpperCase((char)b.get(i)));
|
96
96
|
}
|
97
97
|
}
|
98
|
-
|
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
|
+
}
|
99
107
|
req.op_aset(req.getRuntime().getCurrentContext(), f,v);
|
100
108
|
}
|
101
109
|
};
|
@@ -154,36 +162,7 @@ public class Http11 extends RubyObject {
|
|
154
162
|
|
155
163
|
private Http11Parser.ElementCB header_done = new Http11Parser.ElementCB() {
|
156
164
|
public void call(Object data, int at, int length) {
|
157
|
-
|
158
|
-
ThreadContext context = req.getRuntime().getCurrentContext();
|
159
|
-
IRubyObject temp,ctype,clen;
|
160
|
-
|
161
|
-
clen = req.op_aref(context, runtime.newString("HTTP_CONTENT_LENGTH"));
|
162
|
-
if(!clen.isNil()) {
|
163
|
-
req.op_aset(context, runtime.newString("CONTENT_LENGTH"),clen);
|
164
|
-
}
|
165
|
-
|
166
|
-
ctype = req.op_aref(context, runtime.newString("HTTP_CONTENT_TYPE"));
|
167
|
-
if(!ctype.isNil()) {
|
168
|
-
req.op_aset(context, runtime.newString("CONTENT_TYPE"),ctype);
|
169
|
-
}
|
170
|
-
|
171
|
-
req.op_aset(context, runtime.newString("GATEWAY_INTERFACE"),runtime.newString("CGI/1.2"));
|
172
|
-
if(!(temp = req.op_aref(context, runtime.newString("HTTP_HOST"))).isNil()) {
|
173
|
-
String s = temp.toString();
|
174
|
-
int colon = s.indexOf(':');
|
175
|
-
if(colon != -1) {
|
176
|
-
req.op_aset(context, runtime.newString("SERVER_NAME"),runtime.newString(s.substring(0,colon)));
|
177
|
-
req.op_aset(context, runtime.newString("SERVER_PORT"),runtime.newString(s.substring(colon+1)));
|
178
|
-
} else {
|
179
|
-
req.op_aset(context, runtime.newString("SERVER_NAME"),temp);
|
180
|
-
req.op_aset(context, runtime.newString("SERVER_PORT"),runtime.newString("80"));
|
181
|
-
}
|
182
|
-
}
|
183
|
-
|
184
|
-
req.setInstanceVariable("@http_body", RubyString.newString(runtime, new ByteList(hp.parser.buffer, at, length)));
|
185
|
-
req.op_aset(context, runtime.newString("SERVER_PROTOCOL"),runtime.newString("HTTP/1.1"));
|
186
|
-
req.op_aset(context, runtime.newString("SERVER_SOFTWARE"),runtime.newString("Mongrel 1.2.0.beta.1"));
|
165
|
+
body = RubyString.newString(runtime, new ByteList(hp.parser.buffer, at, length));
|
187
166
|
}
|
188
167
|
};
|
189
168
|
|
@@ -238,4 +217,9 @@ public class Http11 extends RubyObject {
|
|
238
217
|
public IRubyObject nread() {
|
239
218
|
return runtime.newFixnum(this.hp.parser.nread);
|
240
219
|
}
|
220
|
+
|
221
|
+
@JRubyMethod
|
222
|
+
public IRubyObject body() {
|
223
|
+
return body;
|
224
|
+
}
|
241
225
|
}// Http11
|
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
|
-
// line 1 "ext/
|
3
|
-
package org.jruby.
|
2
|
+
// line 1 "ext/puma_http11/http11_parser.java.rl"
|
3
|
+
package org.jruby.puma;
|
4
4
|
|
5
5
|
import org.jruby.util.ByteList;
|
6
6
|
|
@@ -9,12 +9,12 @@ public class Http11Parser {
|
|
9
9
|
/** Machine **/
|
10
10
|
|
11
11
|
|
12
|
-
// line 65 "ext/
|
12
|
+
// line 65 "ext/puma_http11/http11_parser.java.rl"
|
13
13
|
|
14
14
|
|
15
15
|
/** Data **/
|
16
16
|
|
17
|
-
// line 18 "ext/
|
17
|
+
// line 18 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
18
18
|
private static byte[] init__http_parser_actions_0()
|
19
19
|
{
|
20
20
|
return new byte [] {
|
@@ -200,7 +200,7 @@ static final int http_parser_error = 0;
|
|
200
200
|
static final int http_parser_en_main = 1;
|
201
201
|
|
202
202
|
|
203
|
-
// line 69 "ext/
|
203
|
+
// line 69 "ext/puma_http11/http11_parser.java.rl"
|
204
204
|
|
205
205
|
public static interface ElementCB {
|
206
206
|
public void call(Object data, int at, int length);
|
@@ -236,12 +236,12 @@ static final int http_parser_en_main = 1;
|
|
236
236
|
cs = 0;
|
237
237
|
|
238
238
|
|
239
|
-
// line 240 "ext/
|
239
|
+
// line 240 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
240
240
|
{
|
241
241
|
cs = http_parser_start;
|
242
242
|
}
|
243
243
|
|
244
|
-
// line 104 "ext/
|
244
|
+
// line 104 "ext/puma_http11/http11_parser.java.rl"
|
245
245
|
|
246
246
|
body_start = 0;
|
247
247
|
content_len = 0;
|
@@ -262,11 +262,13 @@ static final int http_parser_en_main = 1;
|
|
262
262
|
|
263
263
|
p = off;
|
264
264
|
pe = len;
|
265
|
-
|
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();
|
266
268
|
parser.buffer = buffer;
|
267
269
|
|
268
270
|
|
269
|
-
// line
|
271
|
+
// line 272 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
270
272
|
{
|
271
273
|
int _klen;
|
272
274
|
int _trans = 0;
|
@@ -347,29 +349,29 @@ case 1:
|
|
347
349
|
switch ( _http_parser_actions[_acts++] )
|
348
350
|
{
|
349
351
|
case 0:
|
350
|
-
// line 13 "ext/
|
352
|
+
// line 13 "ext/puma_http11/http11_parser.java.rl"
|
351
353
|
{parser.mark = p; }
|
352
354
|
break;
|
353
355
|
case 1:
|
354
|
-
// line 15 "ext/
|
356
|
+
// line 15 "ext/puma_http11/http11_parser.java.rl"
|
355
357
|
{ parser.field_start = p; }
|
356
358
|
break;
|
357
359
|
case 2:
|
358
|
-
// line 16 "ext/
|
360
|
+
// line 16 "ext/puma_http11/http11_parser.java.rl"
|
359
361
|
{ /* FIXME stub */ }
|
360
362
|
break;
|
361
363
|
case 3:
|
362
|
-
// line 17 "ext/
|
364
|
+
// line 17 "ext/puma_http11/http11_parser.java.rl"
|
363
365
|
{
|
364
366
|
parser.field_len = p-parser.field_start;
|
365
367
|
}
|
366
368
|
break;
|
367
369
|
case 4:
|
368
|
-
// line 21 "ext/
|
370
|
+
// line 21 "ext/puma_http11/http11_parser.java.rl"
|
369
371
|
{ parser.mark = p; }
|
370
372
|
break;
|
371
373
|
case 5:
|
372
|
-
// line 22 "ext/
|
374
|
+
// line 22 "ext/puma_http11/http11_parser.java.rl"
|
373
375
|
{
|
374
376
|
if(parser.http_field != null) {
|
375
377
|
parser.http_field.call(parser.data, parser.field_start, parser.field_len, parser.mark, p-parser.mark);
|
@@ -377,53 +379,53 @@ case 1:
|
|
377
379
|
}
|
378
380
|
break;
|
379
381
|
case 6:
|
380
|
-
// line 27 "ext/
|
382
|
+
// line 27 "ext/puma_http11/http11_parser.java.rl"
|
381
383
|
{
|
382
384
|
if(parser.request_method != null)
|
383
385
|
parser.request_method.call(parser.data, parser.mark, p-parser.mark);
|
384
386
|
}
|
385
387
|
break;
|
386
388
|
case 7:
|
387
|
-
// line 31 "ext/
|
389
|
+
// line 31 "ext/puma_http11/http11_parser.java.rl"
|
388
390
|
{
|
389
391
|
if(parser.request_uri != null)
|
390
392
|
parser.request_uri.call(parser.data, parser.mark, p-parser.mark);
|
391
393
|
}
|
392
394
|
break;
|
393
395
|
case 8:
|
394
|
-
// line 35 "ext/
|
396
|
+
// line 35 "ext/puma_http11/http11_parser.java.rl"
|
395
397
|
{
|
396
398
|
if(parser.fragment != null)
|
397
399
|
parser.fragment.call(parser.data, parser.mark, p-parser.mark);
|
398
400
|
}
|
399
401
|
break;
|
400
402
|
case 9:
|
401
|
-
// line 40 "ext/
|
403
|
+
// line 40 "ext/puma_http11/http11_parser.java.rl"
|
402
404
|
{parser.query_start = p; }
|
403
405
|
break;
|
404
406
|
case 10:
|
405
|
-
// line 41 "ext/
|
407
|
+
// line 41 "ext/puma_http11/http11_parser.java.rl"
|
406
408
|
{
|
407
409
|
if(parser.query_string != null)
|
408
410
|
parser.query_string.call(parser.data, parser.query_start, p-parser.query_start);
|
409
411
|
}
|
410
412
|
break;
|
411
413
|
case 11:
|
412
|
-
// line 46 "ext/
|
414
|
+
// line 46 "ext/puma_http11/http11_parser.java.rl"
|
413
415
|
{
|
414
416
|
if(parser.http_version != null)
|
415
417
|
parser.http_version.call(parser.data, parser.mark, p-parser.mark);
|
416
418
|
}
|
417
419
|
break;
|
418
420
|
case 12:
|
419
|
-
// line 51 "ext/
|
421
|
+
// line 51 "ext/puma_http11/http11_parser.java.rl"
|
420
422
|
{
|
421
423
|
if(parser.request_path != null)
|
422
424
|
parser.request_path.call(parser.data, parser.mark, p-parser.mark);
|
423
425
|
}
|
424
426
|
break;
|
425
427
|
case 13:
|
426
|
-
// line 56 "ext/
|
428
|
+
// line 56 "ext/puma_http11/http11_parser.java.rl"
|
427
429
|
{
|
428
430
|
parser.body_start = p + 1;
|
429
431
|
if(parser.header_done != null)
|
@@ -431,7 +433,7 @@ case 1:
|
|
431
433
|
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
|
432
434
|
}
|
433
435
|
break;
|
434
|
-
// line
|
436
|
+
// line 437 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
435
437
|
}
|
436
438
|
}
|
437
439
|
}
|
@@ -451,7 +453,7 @@ case 5:
|
|
451
453
|
break; }
|
452
454
|
}
|
453
455
|
|
454
|
-
// line
|
456
|
+
// line 130 "ext/puma_http11/http11_parser.java.rl"
|
455
457
|
|
456
458
|
parser.cs = cs;
|
457
459
|
parser.nread += (p - off);
|
data/lib/puma/cli.rb
CHANGED
@@ -4,6 +4,8 @@ require 'uri'
|
|
4
4
|
require 'puma/server'
|
5
5
|
require 'puma/const'
|
6
6
|
|
7
|
+
require 'rack/commonlogger'
|
8
|
+
|
7
9
|
module Puma
|
8
10
|
class CLI
|
9
11
|
DefaultTCPHost = "0.0.0.0"
|
@@ -31,12 +33,25 @@ module Puma
|
|
31
33
|
def setup_options
|
32
34
|
@options = {
|
33
35
|
:min_threads => 0,
|
34
|
-
:max_threads => 16
|
36
|
+
:max_threads => 16,
|
37
|
+
:quiet => false
|
35
38
|
}
|
36
39
|
|
37
40
|
@binds = []
|
38
41
|
|
39
42
|
@parser = OptionParser.new do |o|
|
43
|
+
o.on "-b", "--bind URI", "URI to bind to (tcp:// and unix:// only)" do |arg|
|
44
|
+
@binds << arg
|
45
|
+
end
|
46
|
+
|
47
|
+
o.on "--pidfile PATH", "Use PATH as a pidfile" do |arg|
|
48
|
+
@options[:pidfile] = arg
|
49
|
+
end
|
50
|
+
|
51
|
+
o.on "-q", "--quiet", "Quiet down the output" do
|
52
|
+
@options[:quiet] = true
|
53
|
+
end
|
54
|
+
|
40
55
|
o.on '-t', '--threads INT', "min:max threads to use (default 0:16)" do |arg|
|
41
56
|
min, max = arg.split(":")
|
42
57
|
if max
|
@@ -48,9 +63,6 @@ module Puma
|
|
48
63
|
end
|
49
64
|
end
|
50
65
|
|
51
|
-
o.on "-b", "--bind URI", "URI to bind to (tcp:// and unix:// only)" do |arg|
|
52
|
-
@binds << arg
|
53
|
-
end
|
54
66
|
end
|
55
67
|
|
56
68
|
@parser.banner = "puma <options> <rackup file>"
|
@@ -72,8 +84,20 @@ module Puma
|
|
72
84
|
end
|
73
85
|
end
|
74
86
|
|
75
|
-
def
|
87
|
+
def write_pid
|
88
|
+
if path = @options[:pidfile]
|
89
|
+
File.open(path, "w") do |f|
|
90
|
+
f.puts Process.pid
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def parse_options
|
76
96
|
@parser.parse! @argv
|
97
|
+
end
|
98
|
+
|
99
|
+
def run
|
100
|
+
parse_options
|
77
101
|
|
78
102
|
@rackup = ARGV.shift || "config.ru"
|
79
103
|
|
@@ -82,6 +106,11 @@ module Puma
|
|
82
106
|
end
|
83
107
|
|
84
108
|
load_rackup
|
109
|
+
write_pid
|
110
|
+
|
111
|
+
unless @quiet
|
112
|
+
@app = Rack::CommonLogger.new(@app, STDOUT)
|
113
|
+
end
|
85
114
|
|
86
115
|
if @binds.empty?
|
87
116
|
@options[:Host] ||= DefaultTCPHost
|
@@ -125,7 +154,11 @@ module Puma
|
|
125
154
|
|
126
155
|
log "Use Ctrl-C to stop"
|
127
156
|
|
128
|
-
|
157
|
+
begin
|
158
|
+
server.run.join
|
159
|
+
rescue Interrupt
|
160
|
+
log " - Shutting down..."
|
161
|
+
end
|
129
162
|
end
|
130
163
|
end
|
131
164
|
end
|
data/lib/puma/const.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rack/commonlogger'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
# Patch CommonLogger to use after_reply
|
5
|
+
class CommonLogger
|
6
|
+
remove_method :call
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
began_at = Time.now
|
10
|
+
status, header, body = @app.call(env)
|
11
|
+
header = Utils::HeaderHash.new(header)
|
12
|
+
|
13
|
+
if ary = env['rack.after_reply']
|
14
|
+
ary << lambda { log(env, status, header, began_at) }
|
15
|
+
else
|
16
|
+
body = BodyProxy.new(body) { log(env, status, header, began_at) }
|
17
|
+
end
|
18
|
+
|
19
|
+
[status, header, body]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/puma/server.rb
CHANGED
@@ -142,7 +142,11 @@ module Puma
|
|
142
142
|
nparsed = parser.execute(env, data, nparsed)
|
143
143
|
|
144
144
|
if parser.finished?
|
145
|
-
|
145
|
+
cl = env[CONTENT_LENGTH]
|
146
|
+
|
147
|
+
return unless handle_request(env, client, parser.body, cl)
|
148
|
+
|
149
|
+
nparsed += parser.body.size if cl
|
146
150
|
|
147
151
|
if data.size > nparsed
|
148
152
|
data.slice!(0, nparsed)
|
@@ -219,12 +223,15 @@ module Puma
|
|
219
223
|
env[REMOTE_ADDR] = client.peeraddr.last
|
220
224
|
end
|
221
225
|
|
222
|
-
def handle_request(env, client, body)
|
226
|
+
def handle_request(env, client, body, cl)
|
223
227
|
normalize_env env, client
|
224
228
|
|
225
|
-
|
226
|
-
|
227
|
-
|
229
|
+
if cl
|
230
|
+
body = read_body env, client, body, cl
|
231
|
+
return false unless body
|
232
|
+
else
|
233
|
+
body = StringIO.new("")
|
234
|
+
end
|
228
235
|
|
229
236
|
env["rack.input"] = body
|
230
237
|
env["rack.url_scheme"] = env["HTTPS"] ? "https" : "http"
|
@@ -325,8 +332,8 @@ module Puma
|
|
325
332
|
return keep_alive
|
326
333
|
end
|
327
334
|
|
328
|
-
def read_body(env, client, body)
|
329
|
-
content_length =
|
335
|
+
def read_body(env, client, body, cl)
|
336
|
+
content_length = cl.to_i
|
330
337
|
|
331
338
|
remain = content_length - body.size
|
332
339
|
|
data/lib/rack/handler/puma.rb
CHANGED
@@ -4,13 +4,27 @@ require 'puma'
|
|
4
4
|
module Rack
|
5
5
|
module Handler
|
6
6
|
module Puma
|
7
|
-
DEFAULT_OPTIONS = {
|
7
|
+
DEFAULT_OPTIONS = {
|
8
|
+
:Host => '0.0.0.0',
|
9
|
+
:Port => 8080,
|
10
|
+
:Threads => '0:16',
|
11
|
+
:Quiet => false
|
12
|
+
}
|
8
13
|
|
9
14
|
def self.run(app, options = {})
|
10
15
|
options = DEFAULT_OPTIONS.merge(options)
|
16
|
+
|
17
|
+
unless options[:Quiet]
|
18
|
+
app = Rack::CommonLogger.new(app, STDOUT)
|
19
|
+
end
|
20
|
+
|
11
21
|
server = ::Puma::Server.new(app)
|
12
22
|
min, max = options[:Threads].split(':', 2)
|
13
23
|
|
24
|
+
puts "Puma #{::Puma::Const::PUMA_VERSION} starting..."
|
25
|
+
puts "* Min threads: #{min}, max threads: #{max}"
|
26
|
+
puts "* Listening on tcp://#{options[:Host]}:#{options[:Port]}"
|
27
|
+
|
14
28
|
server.add_tcp_listener options[:Host], options[:Port]
|
15
29
|
server.min_threads = Integer(min)
|
16
30
|
server.max_threads = Integer(max)
|
@@ -23,7 +37,8 @@ module Rack
|
|
23
37
|
{
|
24
38
|
"Host=HOST" => "Hostname to listen on (default: localhost)",
|
25
39
|
"Port=PORT" => "Port to listen on (default: 8080)",
|
26
|
-
"Threads=MIN:MAX" => "min:max threads to use (default 0:16)"
|
40
|
+
"Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
|
41
|
+
"Quiet" => "Don't report each request"
|
27
42
|
}
|
28
43
|
end
|
29
44
|
end
|
data/puma.gemspec
CHANGED
@@ -2,38 +2,38 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "puma"
|
5
|
-
s.version = "0.8.
|
5
|
+
s.version = "0.8.2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Evan Phoenix"]
|
9
|
-
s.date = "2011-
|
9
|
+
s.date = "2011-11-22"
|
10
10
|
s.description = "Puma is a small library that provides a very fast and concurrent HTTP 1.1 server for Ruby web applications. It is designed for running rack apps only.\n\nWhat makes Puma so fast is the careful use of an Ragel extension to provide fast, accurate HTTP 1.1 protocol parsing. This makes the server scream without too many portability issues."
|
11
11
|
s.email = ["evan@phx.io"]
|
12
12
|
s.executables = ["puma"]
|
13
13
|
s.extensions = ["ext/puma_http11/extconf.rb"]
|
14
14
|
s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
|
15
|
-
s.files = ["COPYING", "History.txt", "LICENSE", "Manifest.txt", "README.md", "Rakefile", "TODO", "bin/puma", "examples/builder.rb", "examples/camping/README", "examples/camping/blog.rb", "examples/camping/tepee.rb", "examples/httpd.conf", "examples/mime.yaml", "examples/mongrel.conf", "examples/monitrc", "examples/random_thrash.rb", "examples/simpletest.rb", "examples/webrick_compare.rb", "ext/puma_http11/
|
15
|
+
s.files = ["COPYING", "Gemfile", "History.txt", "LICENSE", "Manifest.txt", "README.md", "Rakefile", "TODO", "bin/puma", "examples/builder.rb", "examples/camping/README", "examples/camping/blog.rb", "examples/camping/tepee.rb", "examples/httpd.conf", "examples/mime.yaml", "examples/mongrel.conf", "examples/monitrc", "examples/random_thrash.rb", "examples/simpletest.rb", "examples/webrick_compare.rb", "ext/puma_http11/PumaHttp11Service.java", "ext/puma_http11/ext_help.h", "ext/puma_http11/extconf.rb", "ext/puma_http11/http11_parser.c", "ext/puma_http11/http11_parser.h", "ext/puma_http11/http11_parser.java.rl", "ext/puma_http11/http11_parser.rl", "ext/puma_http11/http11_parser_common.rl", "ext/puma_http11/org/jruby/puma/Http11.java", "ext/puma_http11/org/jruby/puma/Http11Parser.java", "ext/puma_http11/puma_http11.c", "lib/puma.rb", "lib/puma/cli.rb", "lib/puma/const.rb", "lib/puma/events.rb", "lib/puma/gems.rb", "lib/puma/mime_types.yml", "lib/puma/rack_patch.rb", "lib/puma/server.rb", "lib/puma/thread_pool.rb", "lib/puma/utils.rb", "lib/rack/handler/puma.rb", "puma.gemspec", "tasks/gem.rake", "tasks/java.rake", "tasks/native.rake", "tasks/ragel.rake", "test/lobster.ru", "test/mime.yaml", "test/test_cli.rb", "test/test_http10.rb", "test/test_http11.rb", "test/test_persistent.rb", "test/test_rack_handler.rb", "test/test_rack_server.rb", "test/test_thread_pool.rb", "test/test_unix_socket.rb", "test/test_ws.rb", "test/testhelp.rb", "tools/trickletest.rb", ".gemtest"]
|
16
16
|
s.rdoc_options = ["--main", "README.md"]
|
17
17
|
s.require_paths = ["lib"]
|
18
18
|
s.rubyforge_project = "puma"
|
19
19
|
s.rubygems_version = "1.8.10"
|
20
20
|
s.summary = "Puma is a small library that provides a very fast and concurrent HTTP 1.1 server for Ruby web applications"
|
21
|
-
s.test_files = ["test/test_http10.rb", "test/test_http11.rb", "test/test_persistent.rb", "test/test_rack_handler.rb", "test/test_rack_server.rb", "test/test_thread_pool.rb", "test/test_unix_socket.rb", "test/test_ws.rb"]
|
21
|
+
s.test_files = ["test/test_cli.rb", "test/test_http10.rb", "test/test_http11.rb", "test/test_persistent.rb", "test/test_rack_handler.rb", "test/test_rack_server.rb", "test/test_thread_pool.rb", "test/test_unix_socket.rb", "test/test_ws.rb"]
|
22
22
|
|
23
23
|
if s.respond_to? :specification_version then
|
24
24
|
s.specification_version = 3
|
25
25
|
|
26
26
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
27
|
-
s.add_runtime_dependency(%q<rack>, ["~> 1.
|
27
|
+
s.add_runtime_dependency(%q<rack>, ["~> 1.2"])
|
28
28
|
s.add_development_dependency(%q<rake-compiler>, ["~> 0.7.0"])
|
29
29
|
s.add_development_dependency(%q<hoe>, ["~> 2.10"])
|
30
30
|
else
|
31
|
-
s.add_dependency(%q<rack>, ["~> 1.
|
31
|
+
s.add_dependency(%q<rack>, ["~> 1.2"])
|
32
32
|
s.add_dependency(%q<rake-compiler>, ["~> 0.7.0"])
|
33
33
|
s.add_dependency(%q<hoe>, ["~> 2.10"])
|
34
34
|
end
|
35
35
|
else
|
36
|
-
s.add_dependency(%q<rack>, ["~> 1.
|
36
|
+
s.add_dependency(%q<rack>, ["~> 1.2"])
|
37
37
|
s.add_dependency(%q<rake-compiler>, ["~> 0.7.0"])
|
38
38
|
s.add_dependency(%q<hoe>, ["~> 2.10"])
|
39
39
|
end
|
data/tasks/gem.rake
CHANGED
data/tasks/java.rake
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
if
|
1
|
+
if IS_JRUBY
|
2
2
|
|
3
3
|
require 'rake/javaextensiontask'
|
4
4
|
|
5
5
|
# build http11 java extension
|
6
|
-
Rake::JavaExtensionTask.new('
|
6
|
+
Rake::JavaExtensionTask.new('puma_http11', HOE.spec) do |ext|
|
7
7
|
ext.java_compiling do |gs|
|
8
8
|
gs.dependencies.delete gs.dependencies.find { |d| d.name == 'daemons' }
|
9
9
|
end
|
data/tasks/native.rake
CHANGED
@@ -1,25 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
#
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
1
|
+
unless IS_JRUBY
|
2
|
+
|
3
|
+
# use rake-compiler for building the extension
|
4
|
+
require 'rake/extensiontask'
|
5
|
+
|
6
|
+
# build http11 C extension
|
7
|
+
Rake::ExtensionTask.new('puma_http11', HOE.spec) do |ext|
|
8
|
+
# define target for extension (supporting fat binaries)
|
9
|
+
if RUBY_PLATFORM =~ /mingw|mswin/ then
|
10
|
+
RUBY_VERSION =~ /(\d+\.\d+)/
|
11
|
+
ext.lib_dir = "lib/#{$1}"
|
12
|
+
elsif ENV['CROSS']
|
13
|
+
# define cross-compilation tasks when not on Windows.
|
14
|
+
ext.cross_compile = true
|
15
|
+
ext.cross_platform = ['i386-mswin32', 'i386-mingw32']
|
16
|
+
|
17
|
+
ext.cross_compiling do |gs|
|
18
|
+
gs.dependencies.delete gs.dependencies.find { |d| d.name == 'daemons' }
|
19
|
+
end
|
17
20
|
end
|
21
|
+
|
22
|
+
# cleanup versioned library directory
|
23
|
+
CLEAN.include 'lib/{1.8,1.9}'
|
18
24
|
end
|
25
|
+
end
|
19
26
|
|
20
|
-
|
21
|
-
|
27
|
+
task :ext_clean do
|
28
|
+
sh "rm -rf lib/puma_http11.bundle"
|
29
|
+
sh "rm -rf lib/puma_http11.jar"
|
30
|
+
sh "rm -rf lib/puma_http11.so"
|
22
31
|
end
|
23
32
|
|
24
33
|
# ensure things are built prior testing
|
25
34
|
task :test => [:compile]
|
35
|
+
|
36
|
+
task :clean => :ext_clean
|
data/tasks/ragel.rake
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
# the following tasks ease the build of C file from Ragel one
|
3
3
|
|
4
|
-
file 'ext/
|
4
|
+
file 'ext/puma_http11/http11_parser.c' => ['ext/puma_http11/http11_parser.rl'] do |t|
|
5
5
|
begin
|
6
6
|
sh "ragel #{t.prerequisites.last} -C -G2 -o #{t.name}"
|
7
7
|
rescue
|
@@ -9,7 +9,7 @@ file 'ext/http11/http11_parser.c' => ['ext/http11/http11_parser.rl'] do |t|
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
file 'ext/
|
12
|
+
file 'ext/puma_http11/org/jruby/puma/Http11Parser.java' => ['ext/puma_http11/http11_parser.java.rl'] do |t|
|
13
13
|
begin
|
14
14
|
sh "ragel #{t.prerequisites.last} -J -G2 -o #{t.name}"
|
15
15
|
rescue
|
@@ -17,4 +17,8 @@ file 'ext/http11/org/jruby/puma/Http11Parser.java' => ['ext/http11/http11_parser
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
if IS_JRUBY
|
21
|
+
task :ragel => 'ext/puma_http11/org/jruby/puma/Http11Parser.java'
|
22
|
+
else
|
23
|
+
task :ragel => 'ext/puma_http11/http11_parser.c'
|
24
|
+
end
|
data/test/test_cli.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'puma/cli'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
class TestCLI < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@pid_file = Tempfile.new("puma-test")
|
8
|
+
@pid_path = @pid_file.path
|
9
|
+
@pid_file.close!
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_pid_file
|
13
|
+
cli = Puma::CLI.new ["--pidfile", @pid_path]
|
14
|
+
cli.parse_options
|
15
|
+
cli.write_pid
|
16
|
+
|
17
|
+
assert_equal File.read(@pid_path).strip.to_i, Process.pid
|
18
|
+
end
|
19
|
+
end
|
data/test/test_persistent.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'puma'
|
2
2
|
require 'test/unit'
|
3
|
+
require 'timeout'
|
3
4
|
|
4
5
|
class TestPersistent < Test::Unit::TestCase
|
5
6
|
def setup
|
@@ -8,9 +9,17 @@ class TestPersistent < Test::Unit::TestCase
|
|
8
9
|
@http10_request = "GET / HTTP/1.0\r\nHost: test.com\r\nContent-Type: text/plain\r\n\r\n"
|
9
10
|
@keep_request = "GET / HTTP/1.0\r\nHost: test.com\r\nContent-Type: text/plain\r\nConnection: Keep-Alive\r\n\r\n"
|
10
11
|
|
12
|
+
@valid_post = "POST / HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\nContent-Length: 5\r\n\r\nhello"
|
13
|
+
|
11
14
|
@headers = { "X-Header" => "Works" }
|
12
15
|
@body = ["Hello"]
|
13
|
-
@
|
16
|
+
@inputs = []
|
17
|
+
|
18
|
+
@simple = lambda do |env|
|
19
|
+
@inputs << env['rack.input']
|
20
|
+
[200, @headers, @body]
|
21
|
+
end
|
22
|
+
|
14
23
|
@server = Puma::Server.new @simple
|
15
24
|
@server.add_tcp_listener "127.0.0.1", 9988
|
16
25
|
@server.run
|
@@ -25,7 +34,9 @@ class TestPersistent < Test::Unit::TestCase
|
|
25
34
|
|
26
35
|
def lines(count, s=@client)
|
27
36
|
str = ""
|
28
|
-
|
37
|
+
timeout(5) do
|
38
|
+
count.times { str << s.gets }
|
39
|
+
end
|
29
40
|
str
|
30
41
|
end
|
31
42
|
|
@@ -51,6 +62,20 @@ class TestPersistent < Test::Unit::TestCase
|
|
51
62
|
assert_equal "Hello", @client.read(5)
|
52
63
|
end
|
53
64
|
|
65
|
+
def test_post_then_get
|
66
|
+
@client << @valid_post
|
67
|
+
sz = @body[0].size.to_s
|
68
|
+
|
69
|
+
assert_equal "HTTP/1.1 200 OK\r\nX-Header: Works\r\nContent-Length: #{sz}\r\n\r\n", lines(4)
|
70
|
+
assert_equal "Hello", @client.read(5)
|
71
|
+
|
72
|
+
@client << @valid_request
|
73
|
+
sz = @body[0].size.to_s
|
74
|
+
|
75
|
+
assert_equal "HTTP/1.1 200 OK\r\nX-Header: Works\r\nContent-Length: #{sz}\r\n\r\n", lines(4)
|
76
|
+
assert_equal "Hello", @client.read(5)
|
77
|
+
end
|
78
|
+
|
54
79
|
def test_chunked
|
55
80
|
@body << "Chunked"
|
56
81
|
|
@@ -156,4 +181,25 @@ class TestPersistent < Test::Unit::TestCase
|
|
156
181
|
assert_equal "Hello", @client.read(5)
|
157
182
|
end
|
158
183
|
|
184
|
+
def test_second_request_not_in_first_req_body
|
185
|
+
@server.persistent_timeout = 3
|
186
|
+
|
187
|
+
req = @valid_request.to_s
|
188
|
+
req << "GET /second HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\n\r\n"
|
189
|
+
|
190
|
+
@client << req
|
191
|
+
|
192
|
+
sz = @body[0].size.to_s
|
193
|
+
|
194
|
+
assert_equal "HTTP/1.1 200 OK\r\nX-Header: Works\r\nContent-Length: #{sz}\r\n\r\n", lines(4)
|
195
|
+
assert_equal "Hello", @client.read(5)
|
196
|
+
|
197
|
+
assert_equal "HTTP/1.1 200 OK\r\nX-Header: Works\r\nContent-Length: #{sz}\r\n\r\n", lines(4)
|
198
|
+
assert_equal "Hello", @client.read(5)
|
199
|
+
|
200
|
+
assert_equal "", @inputs[0].string
|
201
|
+
assert_equal "", @inputs[1].string
|
202
|
+
|
203
|
+
end
|
204
|
+
|
159
205
|
end
|
data/test/test_rack_server.rb
CHANGED
@@ -47,10 +47,17 @@ class TestRackServer < Test::Unit::TestCase
|
|
47
47
|
@simple = lambda { |env| [200, { "X-Header" => "Works" }, ["Hello"]] }
|
48
48
|
@server = Puma::Server.new @simple
|
49
49
|
@server.add_tcp_listener "127.0.0.1", 9998
|
50
|
+
|
51
|
+
@stopped = false
|
50
52
|
end
|
51
53
|
|
52
|
-
def
|
54
|
+
def stop
|
53
55
|
@server.stop(true)
|
56
|
+
@stopped = true
|
57
|
+
end
|
58
|
+
|
59
|
+
def teardown
|
60
|
+
@server.stop(true) unless @stopped
|
54
61
|
end
|
55
62
|
|
56
63
|
def test_lint
|
@@ -102,6 +109,8 @@ class TestRackServer < Test::Unit::TestCase
|
|
102
109
|
|
103
110
|
hit(['http://localhost:9998/test'])
|
104
111
|
|
112
|
+
stop
|
113
|
+
|
105
114
|
assert_match %r!GET /test HTTP/1\.1!, log.string
|
106
115
|
end
|
107
116
|
end
|
data/test/test_unix_socket.rb
CHANGED
@@ -3,32 +3,35 @@ require 'puma/server'
|
|
3
3
|
|
4
4
|
require 'socket'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
6
|
+
# UNIX sockets are not recommended on JRuby
|
7
|
+
unless defined?(JRUBY_VERSION)
|
8
|
+
class TestPumaUnixSocket < Test::Unit::TestCase
|
9
|
+
|
10
|
+
App = lambda { |env| [200, {}, ["Works"]] }
|
11
|
+
|
12
|
+
Path = "test/puma.sock"
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@server = Puma::Server.new App
|
16
|
+
@server.add_unix_listener Path
|
17
|
+
@server.run
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown
|
21
|
+
@server.stop(true)
|
22
|
+
File.unlink Path if File.exists? Path
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_server
|
26
|
+
sock = UNIXSocket.new Path
|
27
|
+
|
28
|
+
sock << "GET / HTTP/1.0\r\nHost: blah.com\r\n\r\n"
|
29
|
+
|
30
|
+
expected = "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Length: 5\r\n\r\nWorks"
|
31
|
+
|
32
|
+
assert_equal expected, sock.read(expected.size)
|
33
|
+
|
34
|
+
sock.close
|
35
|
+
end
|
33
36
|
end
|
34
|
-
end
|
37
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 59
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 8
|
9
|
-
-
|
10
|
-
version: 0.8.
|
9
|
+
- 2
|
10
|
+
version: 0.8.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Evan Phoenix
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-11-22 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rack
|
@@ -25,11 +25,11 @@ dependencies:
|
|
25
25
|
requirements:
|
26
26
|
- - ~>
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
hash:
|
28
|
+
hash: 11
|
29
29
|
segments:
|
30
30
|
- 1
|
31
|
-
-
|
32
|
-
version: "1.
|
31
|
+
- 2
|
32
|
+
version: "1.2"
|
33
33
|
type: :runtime
|
34
34
|
version_requirements: *id001
|
35
35
|
- !ruby/object:Gem::Dependency
|
@@ -78,6 +78,7 @@ extra_rdoc_files:
|
|
78
78
|
- Manifest.txt
|
79
79
|
files:
|
80
80
|
- COPYING
|
81
|
+
- Gemfile
|
81
82
|
- History.txt
|
82
83
|
- LICENSE
|
83
84
|
- Manifest.txt
|
@@ -96,23 +97,24 @@ files:
|
|
96
97
|
- examples/random_thrash.rb
|
97
98
|
- examples/simpletest.rb
|
98
99
|
- examples/webrick_compare.rb
|
99
|
-
- ext/puma_http11/
|
100
|
+
- ext/puma_http11/PumaHttp11Service.java
|
100
101
|
- ext/puma_http11/ext_help.h
|
101
102
|
- ext/puma_http11/extconf.rb
|
102
|
-
- ext/puma_http11/puma_http11.c
|
103
103
|
- ext/puma_http11/http11_parser.c
|
104
104
|
- ext/puma_http11/http11_parser.h
|
105
105
|
- ext/puma_http11/http11_parser.java.rl
|
106
106
|
- ext/puma_http11/http11_parser.rl
|
107
107
|
- ext/puma_http11/http11_parser_common.rl
|
108
|
-
- ext/puma_http11/org/jruby/
|
109
|
-
- ext/puma_http11/org/jruby/
|
108
|
+
- ext/puma_http11/org/jruby/puma/Http11.java
|
109
|
+
- ext/puma_http11/org/jruby/puma/Http11Parser.java
|
110
|
+
- ext/puma_http11/puma_http11.c
|
110
111
|
- lib/puma.rb
|
111
112
|
- lib/puma/cli.rb
|
112
113
|
- lib/puma/const.rb
|
113
114
|
- lib/puma/events.rb
|
114
115
|
- lib/puma/gems.rb
|
115
116
|
- lib/puma/mime_types.yml
|
117
|
+
- lib/puma/rack_patch.rb
|
116
118
|
- lib/puma/server.rb
|
117
119
|
- lib/puma/thread_pool.rb
|
118
120
|
- lib/puma/utils.rb
|
@@ -124,6 +126,7 @@ files:
|
|
124
126
|
- tasks/ragel.rake
|
125
127
|
- test/lobster.ru
|
126
128
|
- test/mime.yaml
|
129
|
+
- test/test_cli.rb
|
127
130
|
- test/test_http10.rb
|
128
131
|
- test/test_http11.rb
|
129
132
|
- test/test_persistent.rb
|
@@ -170,6 +173,7 @@ signing_key:
|
|
170
173
|
specification_version: 3
|
171
174
|
summary: Puma is a small library that provides a very fast and concurrent HTTP 1.1 server for Ruby web applications
|
172
175
|
test_files:
|
176
|
+
- test/test_cli.rb
|
173
177
|
- test/test_http10.rb
|
174
178
|
- test/test_http11.rb
|
175
179
|
- test/test_persistent.rb
|