rack 1.2.8 → 1.3.0.beta

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack might be problematic. Click here for more details.

Files changed (89) hide show
  1. data/README +9 -177
  2. data/Rakefile +2 -1
  3. data/SPEC +2 -2
  4. data/lib/rack.rb +2 -13
  5. data/lib/rack/auth/abstract/request.rb +7 -5
  6. data/lib/rack/auth/digest/md5.rb +6 -2
  7. data/lib/rack/auth/digest/params.rb +5 -7
  8. data/lib/rack/auth/digest/request.rb +1 -1
  9. data/lib/rack/backports/uri/common.rb +64 -0
  10. data/lib/rack/builder.rb +60 -3
  11. data/lib/rack/chunked.rb +29 -22
  12. data/lib/rack/conditionalget.rb +35 -16
  13. data/lib/rack/content_length.rb +3 -3
  14. data/lib/rack/deflater.rb +5 -2
  15. data/lib/rack/etag.rb +38 -10
  16. data/lib/rack/file.rb +76 -43
  17. data/lib/rack/handler.rb +13 -7
  18. data/lib/rack/handler/cgi.rb +0 -2
  19. data/lib/rack/handler/fastcgi.rb +13 -4
  20. data/lib/rack/handler/lsws.rb +0 -2
  21. data/lib/rack/handler/mongrel.rb +12 -2
  22. data/lib/rack/handler/scgi.rb +9 -1
  23. data/lib/rack/handler/thin.rb +7 -1
  24. data/lib/rack/handler/webrick.rb +12 -5
  25. data/lib/rack/lint.rb +2 -2
  26. data/lib/rack/lock.rb +29 -3
  27. data/lib/rack/methodoverride.rb +1 -1
  28. data/lib/rack/mime.rb +2 -2
  29. data/lib/rack/mock.rb +28 -33
  30. data/lib/rack/multipart.rb +34 -0
  31. data/lib/rack/multipart/generator.rb +93 -0
  32. data/lib/rack/multipart/parser.rb +164 -0
  33. data/lib/rack/multipart/uploaded_file.rb +30 -0
  34. data/lib/rack/request.rb +55 -19
  35. data/lib/rack/response.rb +10 -8
  36. data/lib/rack/sendfile.rb +14 -18
  37. data/lib/rack/server.rb +55 -8
  38. data/lib/rack/session/abstract/id.rb +233 -22
  39. data/lib/rack/session/cookie.rb +99 -46
  40. data/lib/rack/session/memcache.rb +30 -56
  41. data/lib/rack/session/pool.rb +22 -43
  42. data/lib/rack/showexceptions.rb +40 -11
  43. data/lib/rack/showstatus.rb +9 -2
  44. data/lib/rack/static.rb +29 -9
  45. data/lib/rack/urlmap.rb +6 -1
  46. data/lib/rack/utils.rb +67 -326
  47. data/rack.gemspec +2 -3
  48. data/test/builder/anything.rb +5 -0
  49. data/test/builder/comment.ru +4 -0
  50. data/test/builder/end.ru +3 -0
  51. data/test/builder/options.ru +2 -0
  52. data/test/cgi/lighttpd.conf +1 -1
  53. data/test/cgi/lighttpd.errors +412 -0
  54. data/test/multipart/content_type_and_no_filename +6 -0
  55. data/test/multipart/text +5 -0
  56. data/test/multipart/webkit +32 -0
  57. data/test/registering_handler/rack/handler/registering_myself.rb +8 -0
  58. data/test/spec_auth_digest.rb +20 -5
  59. data/test/spec_builder.rb +29 -0
  60. data/test/spec_cgi.rb +11 -0
  61. data/test/spec_chunked.rb +1 -1
  62. data/test/spec_commonlogger.rb +1 -1
  63. data/test/spec_conditionalget.rb +47 -0
  64. data/test/spec_content_length.rb +0 -6
  65. data/test/spec_content_type.rb +5 -5
  66. data/test/spec_deflater.rb +46 -2
  67. data/test/spec_etag.rb +68 -1
  68. data/test/spec_fastcgi.rb +11 -0
  69. data/test/spec_file.rb +54 -3
  70. data/test/spec_handler.rb +23 -5
  71. data/test/spec_lint.rb +2 -2
  72. data/test/spec_lock.rb +111 -5
  73. data/test/spec_methodoverride.rb +2 -2
  74. data/test/spec_mock.rb +3 -3
  75. data/test/spec_mongrel.rb +1 -2
  76. data/test/spec_multipart.rb +279 -0
  77. data/test/spec_request.rb +222 -38
  78. data/test/spec_response.rb +9 -3
  79. data/test/spec_server.rb +74 -0
  80. data/test/spec_session_abstract_id.rb +43 -0
  81. data/test/spec_session_cookie.rb +97 -15
  82. data/test/spec_session_memcache.rb +60 -50
  83. data/test/spec_session_pool.rb +63 -40
  84. data/test/spec_showexceptions.rb +64 -0
  85. data/test/spec_static.rb +23 -0
  86. data/test/spec_utils.rb +65 -351
  87. data/test/spec_webrick.rb +23 -4
  88. metadata +35 -15
  89. data/test/spec_auth.rb +0 -57
@@ -16,6 +16,7 @@ describe Rack::Request do
16
16
  req.should.not.be.put
17
17
  req.should.not.be.delete
18
18
  req.should.not.be.head
19
+ req.should.not.be.patch
19
20
 
20
21
  req.script_name.should.equal ""
21
22
  req.path_info.should.equal "/"
@@ -52,6 +53,70 @@ describe Rack::Request do
52
53
  req.host.should.equal ""
53
54
  end
54
55
 
56
+ should "figure out the correct port" do
57
+ req = Rack::Request.new \
58
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "www2.example.org")
59
+ req.port.should.equal 80
60
+
61
+ req = Rack::Request.new \
62
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "www2.example.org:81")
63
+ req.port.should.equal 81
64
+
65
+ req = Rack::Request.new \
66
+ Rack::MockRequest.env_for("/", "SERVER_NAME" => "example.org", "SERVER_PORT" => "9292")
67
+ req.port.should.equal 9292
68
+
69
+ req = Rack::Request.new \
70
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org:9292")
71
+ req.port.should.equal 9292
72
+
73
+ req = Rack::Request.new \
74
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org")
75
+ req.port.should.equal 80
76
+
77
+ req = Rack::Request.new \
78
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org", "HTTP_X_FORWARDED_SSL" => "on")
79
+ req.port.should.equal 443
80
+
81
+ req = Rack::Request.new \
82
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org", "HTTP_X_FORWARDED_PROTO" => "https")
83
+ req.port.should.equal 443
84
+
85
+ req = Rack::Request.new \
86
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org", "HTTP_X_FORWARDED_PORT" => "9393")
87
+ req.port.should.equal 9393
88
+
89
+ req = Rack::Request.new \
90
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org:9393", "SERVER_PORT" => "80")
91
+ req.port.should.equal 9393
92
+
93
+ req = Rack::Request.new \
94
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org", "SERVER_PORT" => "9393")
95
+ req.port.should.equal 80
96
+ end
97
+
98
+ should "figure out the correct host with port" do
99
+ req = Rack::Request.new \
100
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "www2.example.org")
101
+ req.host_with_port.should.equal "www2.example.org"
102
+
103
+ req = Rack::Request.new \
104
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81")
105
+ req.host_with_port.should.equal "localhost:81"
106
+
107
+ req = Rack::Request.new \
108
+ Rack::MockRequest.env_for("/", "SERVER_NAME" => "example.org", "SERVER_PORT" => "9292")
109
+ req.host_with_port.should.equal "example.org:9292"
110
+
111
+ req = Rack::Request.new \
112
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org:9292")
113
+ req.host_with_port.should.equal "example.org:9292"
114
+
115
+ req = Rack::Request.new \
116
+ Rack::MockRequest.env_for("/", "HTTP_HOST" => "localhost:81", "HTTP_X_FORWARDED_HOST" => "example.org", "SERVER_PORT" => "9393")
117
+ req.host_with_port.should.equal "example.org"
118
+ end
119
+
55
120
  should "parse the query string" do
56
121
  req = Rack::Request.new(Rack::MockRequest.env_for("/?foo=bar&quux=bla"))
57
122
  req.query_string.should.equal "foo=bar&quux=bla"
@@ -60,6 +125,20 @@ describe Rack::Request do
60
125
  req.params.should.equal "foo" => "bar", "quux" => "bla"
61
126
  end
62
127
 
128
+ should "not unify GET and POST when calling params" do
129
+ mr = Rack::MockRequest.env_for("/?foo=quux",
130
+ "REQUEST_METHOD" => 'POST',
131
+ :input => "foo=bar&quux=bla"
132
+ )
133
+ req = Rack::Request.new mr
134
+
135
+ req.params
136
+
137
+ req.GET.should.equal "foo" => "quux"
138
+ req.POST.should.equal "foo" => "bar", "quux" => "bla"
139
+ req.params.should.equal req.GET.merge(req.POST)
140
+ end
141
+
63
142
  should "raise if rack.input is missing" do
64
143
  req = Rack::Request.new({})
65
144
  lambda { req.POST }.should.raise(RuntimeError)
@@ -78,32 +157,6 @@ describe Rack::Request do
78
157
  req.params.should.equal "foo" => "bar", "quux" => "bla"
79
158
  end
80
159
 
81
- should "limit the keys from the GET query string" do
82
- env = Rack::MockRequest.env_for("/?foo=bar")
83
-
84
- old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 1
85
- begin
86
- req = Rack::Request.new(env)
87
- lambda { req.GET }.should.raise(RangeError)
88
- ensure
89
- Rack::Utils.key_space_limit = old
90
- end
91
- end
92
-
93
- should "limit the keys from the POST form data" do
94
- env = Rack::MockRequest.env_for("",
95
- "REQUEST_METHOD" => 'POST',
96
- :input => "foo=bar&quux=bla")
97
-
98
- old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 1
99
- begin
100
- req = Rack::Request.new(env)
101
- lambda { req.POST }.should.raise(RangeError)
102
- ensure
103
- Rack::Utils.key_space_limit = old
104
- end
105
- end
106
-
107
160
  should "parse POST data with explicit content type regardless of method" do
108
161
  req = Rack::Request.new \
109
162
  Rack::MockRequest.env_for("/",
@@ -197,7 +250,7 @@ describe Rack::Request do
197
250
 
198
251
  req = Rack::Request.new \
199
252
  Rack::MockRequest.env_for("/")
200
- req.referer.should.equal "/"
253
+ req.referer.should.equal nil
201
254
  end
202
255
 
203
256
  should "extract user agent correctly" do
@@ -210,6 +263,24 @@ describe Rack::Request do
210
263
  req.user_agent.should.equal nil
211
264
  end
212
265
 
266
+ should "treat missing content type as nil" do
267
+ req = Rack::Request.new \
268
+ Rack::MockRequest.env_for("/")
269
+ req.content_type.should.equal nil
270
+ end
271
+
272
+ should "treat empty content type as nil" do
273
+ req = Rack::Request.new \
274
+ Rack::MockRequest.env_for("/", "CONTENT_TYPE" => "")
275
+ req.content_type.should.equal nil
276
+ end
277
+
278
+ should "return nil media type for empty content type" do
279
+ req = Rack::Request.new \
280
+ Rack::MockRequest.env_for("/", "CONTENT_TYPE" => "")
281
+ req.media_type.should.equal nil
282
+ end
283
+
213
284
  should "cache, but invalidates the cache" do
214
285
  req = Rack::Request.new \
215
286
  Rack::MockRequest.env_for("/?foo=quux",
@@ -237,6 +308,40 @@ describe Rack::Request do
237
308
  req.should.be.xhr
238
309
  end
239
310
 
311
+ should "ssl detection" do
312
+ request = Rack::Request.new(Rack::MockRequest.env_for("/"))
313
+ request.scheme.should.equal "http"
314
+ request.should.not.be.ssl?
315
+
316
+ request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTPS' => 'on'))
317
+ request.scheme.should.equal "https"
318
+ request.should.be.ssl?
319
+
320
+ request = Rack::Request.new(Rack::MockRequest.env_for("/", 'rack.url_scheme' => 'https'))
321
+ request.scheme.should.equal "https"
322
+ request.should.be.ssl?
323
+
324
+ request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_HOST' => 'www.example.org:8080'))
325
+ request.scheme.should.equal "http"
326
+ request.should.not.be.ssl?
327
+
328
+ request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_HOST' => 'www.example.org:8443', 'HTTPS' => 'on'))
329
+ request.scheme.should.equal "https"
330
+ request.should.be.ssl?
331
+
332
+ request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_HOST' => 'www.example.org:8443', 'HTTP_X_FORWARDED_SSL' => 'on'))
333
+ request.scheme.should.equal "https"
334
+ request.should.be.ssl?
335
+
336
+ request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_PROTO' => 'https'))
337
+ request.scheme.should.equal "https"
338
+ request.should.be.ssl?
339
+
340
+ request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_PROTO' => 'https, http, http'))
341
+ request.scheme.should.equal "https"
342
+ request.should.be.ssl
343
+ end
344
+
240
345
  should "parse cookies" do
241
346
  req = Rack::Request.new \
242
347
  Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m")
@@ -252,6 +357,18 @@ describe Rack::Request do
252
357
  req.cookies.should.equal 'foo' => 'bar'
253
358
  end
254
359
 
360
+ should 'parse cookies with quotes' do
361
+ req = Rack::Request.new Rack::MockRequest.env_for('', {
362
+ 'HTTP_COOKIE' => '$Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"; Part_Number="Rocket_Launcher_0001"; $Path="/acme"'
363
+ })
364
+ req.cookies.should.equal({
365
+ '$Version' => '"1"',
366
+ 'Customer' => '"WILE_E_COYOTE"',
367
+ '$Path' => '"/acme"',
368
+ 'Part_Number' => '"Rocket_Launcher_0001"',
369
+ })
370
+ end
371
+
255
372
  should "provide setters" do
256
373
  req = Rack::Request.new(e=Rack::MockRequest.env_for(""))
257
374
  req.script_name.should.equal ""
@@ -270,6 +387,13 @@ describe Rack::Request do
270
387
  req.env.should == e
271
388
  end
272
389
 
390
+ should "restore the base URL" do
391
+ Rack::Request.new(Rack::MockRequest.env_for("")).base_url.
392
+ should.equal "http://example.org"
393
+ Rack::Request.new(Rack::MockRequest.env_for("", "SCRIPT_NAME" => "/foo")).base_url.
394
+ should.equal "http://example.org"
395
+ end
396
+
273
397
  should "restore the URL" do
274
398
  Rack::Request.new(Rack::MockRequest.env_for("")).url.
275
399
  should.equal "http://example.org/"
@@ -320,29 +444,71 @@ describe Rack::Request do
320
444
  req.media_type_params['bling'].should.equal 'bam'
321
445
  end
322
446
 
323
- should "raise RangeError if the key space is exhausted" do
447
+ should "parse with junk before boundry" do
448
+ # Adapted from RFC 1867.
324
449
  input = <<EOF
450
+ blah blah\r
451
+ \r
452
+ --AaB03x\r
453
+ content-disposition: form-data; name="reply"\r
454
+ \r
455
+ yes\r
325
456
  --AaB03x\r
326
- Content-Disposition: form-data; name="text"\r
327
- Content-Type: text/plain; charset=US-ASCII\r
457
+ content-disposition: form-data; name="fileupload"; filename="dj.jpg"\r
458
+ Content-Type: image/jpeg\r
459
+ Content-Transfer-Encoding: base64\r
328
460
  \r
329
- contents\r
461
+ /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg\r
330
462
  --AaB03x--\r
331
463
  EOF
464
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
465
+ "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
466
+ "CONTENT_LENGTH" => input.size,
467
+ :input => input)
468
+
469
+ req.POST.should.include "fileupload"
470
+ req.POST.should.include "reply"
471
+
472
+ req.should.be.form_data
473
+ req.content_length.should.equal input.size
474
+ req.media_type.should.equal 'multipart/form-data'
475
+ req.media_type_params.should.include 'boundary'
476
+ req.media_type_params['boundary'].should.equal 'AaB03x'
477
+
478
+ req.POST["reply"].should.equal "yes"
479
+
480
+ f = req.POST["fileupload"]
481
+ f.should.be.kind_of Hash
482
+ f[:type].should.equal "image/jpeg"
483
+ f[:filename].should.equal "dj.jpg"
484
+ f.should.include :tempfile
485
+ f[:tempfile].size.should.equal 76
486
+ end
487
+
488
+ should "not infinite loop with a malformed HTTP request" do
489
+ # Adapted from RFC 1867.
490
+ input = <<EOF
491
+ --AaB03x
492
+ content-disposition: form-data; name="reply"
332
493
 
333
- env = Rack::MockRequest.env_for("/",
494
+ yes
495
+ --AaB03x
496
+ content-disposition: form-data; name="fileupload"; filename="dj.jpg"
497
+ Content-Type: image/jpeg
498
+ Content-Transfer-Encoding: base64
499
+
500
+ /9j/4AAQSkZJRgABAQAAAQABAAD//gA+Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
501
+ --AaB03x--
502
+ EOF
503
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
334
504
  "CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
335
505
  "CONTENT_LENGTH" => input.size,
336
506
  :input => input)
337
507
 
338
- old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 1
339
- begin
340
- lambda { Rack::Utils::Multipart.parse_multipart(env) }.should.raise(RangeError)
341
- ensure
342
- Rack::Utils.key_space_limit = old
343
- end
508
+ lambda{req.POST}.should.raise(EOFError)
344
509
  end
345
510
 
511
+
346
512
  should "parse multipart form data" do
347
513
  # Adapted from RFC 1867.
348
514
  input = <<EOF
@@ -443,6 +609,24 @@ EOF
443
609
  lambda { req.POST }.should.raise(EOFError)
444
610
  end
445
611
 
612
+ should "correctly parse the part name from Content-Id header" do
613
+ input = <<EOF
614
+ --AaB03x\r
615
+ Content-Type: text/xml; charset=utf-8\r
616
+ Content-Id: <soap-start>\r
617
+ Content-Transfer-Encoding: 7bit\r
618
+ \r
619
+ foo\r
620
+ --AaB03x--\r
621
+ EOF
622
+ req = Rack::Request.new Rack::MockRequest.env_for("/",
623
+ "CONTENT_TYPE" => "multipart/related, boundary=AaB03x",
624
+ "CONTENT_LENGTH" => input.size,
625
+ :input => input)
626
+
627
+ req.params.keys.should.equal ["<soap-start>"]
628
+ end
629
+
446
630
  should "not try to interpret binary as utf8" do
447
631
  if /regexp/.respond_to?(:kcode) # < 1.9
448
632
  begin
@@ -23,7 +23,7 @@ describe Rack::Response do
23
23
  it "can be written to" do
24
24
  response = Rack::Response.new
25
25
 
26
- status, header, body = response.finish do
26
+ _, _, body = response.finish do
27
27
  response.write "foo"
28
28
  response.write "bar"
29
29
  response.write "baz"
@@ -42,6 +42,11 @@ describe Rack::Response do
42
42
  response["Content-Type"].should.equal "text/plain"
43
43
  end
44
44
 
45
+ it "can override the initial Content-Type with a different case" do
46
+ response = Rack::Response.new("", 200, "content-type" => "text/plain")
47
+ response["Content-Type"].should.equal "text/plain"
48
+ end
49
+
45
50
  it "can set cookies" do
46
51
  response = Rack::Response.new
47
52
 
@@ -147,7 +152,7 @@ describe Rack::Response do
147
152
  res.status = 404
148
153
  res.write "foo"
149
154
  }
150
- status, header, body = r.finish
155
+ status, _, body = r.finish
151
156
  str = ""; body.each { |part| str << part }
152
157
  str.should.equal "foo"
153
158
  status.should.equal 404
@@ -155,10 +160,11 @@ describe Rack::Response do
155
160
 
156
161
  it "doesn't return invalid responses" do
157
162
  r = Rack::Response.new(["foo", "bar"], 204)
158
- status, header, body = r.finish
163
+ _, header, body = r.finish
159
164
  str = ""; body.each { |part| str << part }
160
165
  str.should.be.empty
161
166
  header["Content-Type"].should.equal nil
167
+ header['Content-Length'].should.equal nil
162
168
 
163
169
  lambda {
164
170
  Rack::Response.new(Object.new)
@@ -0,0 +1,74 @@
1
+ require 'rack'
2
+ require 'rack/server'
3
+ require 'tempfile'
4
+ require 'socket'
5
+ require 'open-uri'
6
+
7
+ describe Rack::Server do
8
+
9
+ def app
10
+ lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['success']] }
11
+ end
12
+
13
+ it "overrides :config if :app is passed in" do
14
+ server = Rack::Server.new(:app => "FOO")
15
+ server.app.should == "FOO"
16
+ end
17
+
18
+ should "not include Rack::Lint in deployment or none environments" do
19
+ server = Rack::Server.new(:app => 'foo')
20
+ server.middleware['deployment'].flatten.should.not.include(Rack::Lint)
21
+ server.middleware['none'].flatten.should.not.include(Rack::Lint)
22
+ end
23
+
24
+ should "not include Rack::ShowExceptions in deployment or none environments" do
25
+ server = Rack::Server.new(:app => 'foo')
26
+ server.middleware['deployment'].flatten.should.not.include(Rack::ShowExceptions)
27
+ server.middleware['none'].flatten.should.not.include(Rack::ShowExceptions)
28
+ end
29
+
30
+ should "support CGI" do
31
+ begin
32
+ o, ENV["REQUEST_METHOD"] = ENV["REQUEST_METHOD"], 'foo'
33
+ server = Rack::Server.new(:app => 'foo')
34
+ server.server.name =~ /CGI/
35
+ Rack::Server.logging_middleware.call(server).should.eql(nil)
36
+ ensure
37
+ ENV['REQUEST_METHOD'] = o
38
+ end
39
+ end
40
+
41
+ should "not force any middleware under the none configuration" do
42
+ server = Rack::Server.new(:app => 'foo')
43
+ server.middleware['none'].should.be.empty
44
+ end
45
+
46
+ should "use a full path to the pidfile" do
47
+ # avoids issues with daemonize chdir
48
+ opts = Rack::Server.new.send(:parse_options, %w[--pid testing.pid])
49
+ opts[:pid].should.eql(::File.expand_path('testing.pid'))
50
+ end
51
+
52
+ should "run a server" do
53
+ pidfile = Tempfile.open('pidfile') { |f| break f }.path
54
+ FileUtils.rm pidfile
55
+ server = Rack::Server.new(
56
+ :app => app,
57
+ :environment => 'none',
58
+ :pid => pidfile,
59
+ :Port => TCPServer.open('127.0.0.1', 0){|s| s.addr[1] },
60
+ :Host => '127.0.0.1',
61
+ :daemonize => false,
62
+ :server => 'webrick'
63
+ )
64
+ t = Thread.new { server.start }
65
+ until t.status == 'sleep'; t.join(0.01) end
66
+ body = open("http://127.0.0.1:#{server.options[:Port]}/") { |f| f.read }
67
+ body.should.eql('success')
68
+
69
+ Process.kill(:INT, $$)
70
+ t.join
71
+ open(pidfile) { |f| f.read.should.eql $$.to_s }
72
+ end
73
+
74
+ end