rack 1.6.13 → 2.0.0.alpha

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 (138) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.md +139 -18
  3. data/README.rdoc +17 -25
  4. data/Rakefile +6 -14
  5. data/SPEC +8 -9
  6. data/contrib/rack_logo.svg +164 -111
  7. data/lib/rack.rb +70 -21
  8. data/lib/rack/auth/digest/request.rb +1 -1
  9. data/lib/rack/body_proxy.rb +14 -9
  10. data/lib/rack/builder.rb +3 -3
  11. data/lib/rack/chunked.rb +5 -5
  12. data/lib/rack/{commonlogger.rb → common_logger.rb} +2 -2
  13. data/lib/rack/{conditionalget.rb → conditional_get.rb} +0 -0
  14. data/lib/rack/content_length.rb +2 -2
  15. data/lib/rack/deflater.rb +4 -4
  16. data/lib/rack/directory.rb +49 -55
  17. data/lib/rack/etag.rb +2 -1
  18. data/lib/rack/events.rb +154 -0
  19. data/lib/rack/file.rb +55 -40
  20. data/lib/rack/handler.rb +2 -24
  21. data/lib/rack/handler/cgi.rb +15 -16
  22. data/lib/rack/handler/fastcgi.rb +13 -14
  23. data/lib/rack/handler/lsws.rb +11 -11
  24. data/lib/rack/handler/scgi.rb +15 -15
  25. data/lib/rack/handler/thin.rb +3 -0
  26. data/lib/rack/handler/webrick.rb +22 -24
  27. data/lib/rack/head.rb +15 -17
  28. data/lib/rack/lint.rb +38 -38
  29. data/lib/rack/lobster.rb +1 -1
  30. data/lib/rack/lock.rb +6 -10
  31. data/lib/rack/logger.rb +2 -2
  32. data/lib/rack/media_type.rb +38 -0
  33. data/lib/rack/{methodoverride.rb → method_override.rb} +4 -11
  34. data/lib/rack/mime.rb +18 -5
  35. data/lib/rack/mock.rb +35 -52
  36. data/lib/rack/multipart.rb +35 -6
  37. data/lib/rack/multipart/generator.rb +4 -4
  38. data/lib/rack/multipart/parser.rb +273 -158
  39. data/lib/rack/multipart/uploaded_file.rb +1 -2
  40. data/lib/rack/{nulllogger.rb → null_logger.rb} +1 -1
  41. data/lib/rack/query_parser.rb +174 -0
  42. data/lib/rack/recursive.rb +8 -8
  43. data/lib/rack/reloader.rb +1 -2
  44. data/lib/rack/request.rb +370 -304
  45. data/lib/rack/response.rb +129 -56
  46. data/lib/rack/rewindable_input.rb +1 -12
  47. data/lib/rack/runtime.rb +10 -18
  48. data/lib/rack/sendfile.rb +5 -7
  49. data/lib/rack/server.rb +31 -25
  50. data/lib/rack/session/abstract/id.rb +93 -135
  51. data/lib/rack/session/cookie.rb +26 -28
  52. data/lib/rack/session/memcache.rb +8 -14
  53. data/lib/rack/session/pool.rb +14 -21
  54. data/lib/rack/show_exceptions.rb +386 -0
  55. data/lib/rack/{showstatus.rb → show_status.rb} +3 -3
  56. data/lib/rack/static.rb +30 -5
  57. data/lib/rack/tempfile_reaper.rb +2 -2
  58. data/lib/rack/urlmap.rb +13 -14
  59. data/lib/rack/utils.rb +128 -221
  60. data/rack.gemspec +9 -5
  61. data/test/builder/an_underscore_app.rb +5 -0
  62. data/test/builder/options.ru +1 -1
  63. data/test/cgi/test.fcgi +1 -0
  64. data/test/cgi/test.gz +0 -0
  65. data/test/helper.rb +31 -0
  66. data/test/multipart/filename_with_encoded_words +7 -0
  67. data/test/multipart/{filename_with_null_byte → filename_with_single_quote} +1 -1
  68. data/test/multipart/quoted +15 -0
  69. data/test/multipart/rack-logo.png +0 -0
  70. data/test/registering_handler/rack/handler/registering_myself.rb +1 -1
  71. data/test/spec_auth_basic.rb +20 -19
  72. data/test/spec_auth_digest.rb +47 -46
  73. data/test/spec_body_proxy.rb +27 -27
  74. data/test/spec_builder.rb +51 -41
  75. data/test/spec_cascade.rb +24 -22
  76. data/test/spec_cgi.rb +49 -67
  77. data/test/spec_chunked.rb +36 -34
  78. data/test/{spec_commonlogger.rb → spec_common_logger.rb} +23 -21
  79. data/test/{spec_conditionalget.rb → spec_conditional_get.rb} +29 -28
  80. data/test/spec_config.rb +3 -2
  81. data/test/spec_content_length.rb +18 -17
  82. data/test/spec_content_type.rb +13 -12
  83. data/test/spec_deflater.rb +66 -40
  84. data/test/spec_directory.rb +72 -27
  85. data/test/spec_etag.rb +32 -31
  86. data/test/spec_events.rb +133 -0
  87. data/test/spec_fastcgi.rb +50 -72
  88. data/test/spec_file.rb +96 -77
  89. data/test/spec_handler.rb +19 -34
  90. data/test/spec_head.rb +15 -14
  91. data/test/spec_lint.rb +162 -197
  92. data/test/spec_lobster.rb +24 -23
  93. data/test/spec_lock.rb +69 -39
  94. data/test/spec_logger.rb +4 -3
  95. data/test/spec_media_type.rb +42 -0
  96. data/test/spec_method_override.rb +83 -0
  97. data/test/spec_mime.rb +19 -19
  98. data/test/spec_mock.rb +196 -151
  99. data/test/spec_multipart.rb +310 -202
  100. data/test/{spec_nulllogger.rb → spec_null_logger.rb} +5 -4
  101. data/test/spec_recursive.rb +17 -14
  102. data/test/spec_request.rb +763 -607
  103. data/test/spec_response.rb +209 -156
  104. data/test/spec_rewindable_input.rb +50 -40
  105. data/test/spec_runtime.rb +11 -10
  106. data/test/spec_sendfile.rb +30 -35
  107. data/test/spec_server.rb +78 -52
  108. data/test/spec_session_abstract_id.rb +11 -33
  109. data/test/spec_session_cookie.rb +97 -65
  110. data/test/spec_session_memcache.rb +63 -101
  111. data/test/spec_session_pool.rb +48 -84
  112. data/test/spec_show_exceptions.rb +80 -0
  113. data/test/{spec_showstatus.rb → spec_show_status.rb} +36 -35
  114. data/test/spec_static.rb +71 -32
  115. data/test/spec_tempfile_reaper.rb +11 -10
  116. data/test/spec_thin.rb +55 -50
  117. data/test/spec_urlmap.rb +79 -78
  118. data/test/spec_utils.rb +417 -345
  119. data/test/spec_version.rb +2 -8
  120. data/test/spec_webrick.rb +77 -67
  121. data/test/static/foo.html +1 -0
  122. data/test/testrequest.rb +1 -1
  123. data/test/unregistered_handler/rack/handler/unregistered.rb +1 -1
  124. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +1 -1
  125. metadata +116 -71
  126. data/KNOWN-ISSUES +0 -44
  127. data/lib/rack/backports/uri/common_18.rb +0 -56
  128. data/lib/rack/backports/uri/common_192.rb +0 -52
  129. data/lib/rack/backports/uri/common_193.rb +0 -29
  130. data/lib/rack/handler/evented_mongrel.rb +0 -8
  131. data/lib/rack/handler/mongrel.rb +0 -106
  132. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  133. data/lib/rack/showexceptions.rb +0 -387
  134. data/lib/rack/utils/okjson.rb +0 -600
  135. data/test/spec_methodoverride.rb +0 -111
  136. data/test/spec_mongrel.rb +0 -182
  137. data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
  138. data/test/spec_showexceptions.rb +0 -98
@@ -1,3 +1,4 @@
1
+ require 'minitest/autorun'
1
2
  require 'rack/etag'
2
3
  require 'rack/lint'
3
4
  require 'rack/mock'
@@ -7,101 +8,101 @@ describe Rack::ETag do
7
8
  def etag(app, *args)
8
9
  Rack::Lint.new Rack::ETag.new(app, *args)
9
10
  end
10
-
11
+
11
12
  def request
12
13
  Rack::MockRequest.env_for
13
14
  end
14
-
15
+
15
16
  def sendfile_body
16
17
  res = ['Hello World']
17
18
  def res.to_path ; "/tmp/hello.txt" ; end
18
19
  res
19
20
  end
20
21
 
21
- should "set ETag if none is set if status is 200" do
22
+ it "set ETag if none is set if status is 200" do
22
23
  app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
23
24
  response = etag(app).call(request)
24
- response[1]['ETag'].should.equal "W/\"65a8e27d8879283831b664bd8b7f0ad4\""
25
+ response[1]['ETag'].must_equal "W/\"65a8e27d8879283831b664bd8b7f0ad4\""
25
26
  end
26
27
 
27
- should "set ETag if none is set if status is 201" do
28
+ it "set ETag if none is set if status is 201" do
28
29
  app = lambda { |env| [201, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
29
30
  response = etag(app).call(request)
30
- response[1]['ETag'].should.equal "W/\"65a8e27d8879283831b664bd8b7f0ad4\""
31
+ response[1]['ETag'].must_equal "W/\"65a8e27d8879283831b664bd8b7f0ad4\""
31
32
  end
32
33
 
33
- should "set Cache-Control to 'max-age=0, private, must-revalidate' (default) if none is set" do
34
+ it "set Cache-Control to 'max-age=0, private, must-revalidate' (default) if none is set" do
34
35
  app = lambda { |env| [201, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
35
36
  response = etag(app).call(request)
36
- response[1]['Cache-Control'].should.equal 'max-age=0, private, must-revalidate'
37
+ response[1]['Cache-Control'].must_equal 'max-age=0, private, must-revalidate'
37
38
  end
38
39
 
39
- should "set Cache-Control to chosen one if none is set" do
40
+ it "set Cache-Control to chosen one if none is set" do
40
41
  app = lambda { |env| [201, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
41
42
  response = etag(app, nil, 'public').call(request)
42
- response[1]['Cache-Control'].should.equal 'public'
43
+ response[1]['Cache-Control'].must_equal 'public'
43
44
  end
44
45
 
45
- should "set a given Cache-Control even if digest could not be calculated" do
46
+ it "set a given Cache-Control even if digest could not be calculated" do
46
47
  app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, []] }
47
48
  response = etag(app, 'no-cache').call(request)
48
- response[1]['Cache-Control'].should.equal 'no-cache'
49
+ response[1]['Cache-Control'].must_equal 'no-cache'
49
50
  end
50
51
 
51
- should "not set Cache-Control if it is already set" do
52
+ it "not set Cache-Control if it is already set" do
52
53
  app = lambda { |env| [201, {'Content-Type' => 'text/plain', 'Cache-Control' => 'public'}, ["Hello, World!"]] }
53
54
  response = etag(app).call(request)
54
- response[1]['Cache-Control'].should.equal 'public'
55
+ response[1]['Cache-Control'].must_equal 'public'
55
56
  end
56
57
 
57
- should "not set Cache-Control if directive isn't present" do
58
+ it "not set Cache-Control if directive isn't present" do
58
59
  app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
59
60
  response = etag(app, nil, nil).call(request)
60
- response[1]['Cache-Control'].should.equal nil
61
+ response[1]['Cache-Control'].must_equal nil
61
62
  end
62
63
 
63
- should "not change ETag if it is already set" do
64
+ it "not change ETag if it is already set" do
64
65
  app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'ETag' => '"abc"'}, ["Hello, World!"]] }
65
66
  response = etag(app).call(request)
66
- response[1]['ETag'].should.equal "\"abc\""
67
+ response[1]['ETag'].must_equal "\"abc\""
67
68
  end
68
69
 
69
- should "not set ETag if body is empty" do
70
+ it "not set ETag if body is empty" do
70
71
  app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Last-Modified' => Time.now.httpdate}, []] }
71
72
  response = etag(app).call(request)
72
- response[1]['ETag'].should.be.nil
73
+ response[1]['ETag'].must_be_nil
73
74
  end
74
75
 
75
- should "not set ETag if Last-Modified is set" do
76
+ it "not set ETag if Last-Modified is set" do
76
77
  app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Last-Modified' => Time.now.httpdate}, ["Hello, World!"]] }
77
78
  response = etag(app).call(request)
78
- response[1]['ETag'].should.be.nil
79
+ response[1]['ETag'].must_be_nil
79
80
  end
80
81
 
81
- should "not set ETag if a sendfile_body is given" do
82
+ it "not set ETag if a sendfile_body is given" do
82
83
  app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, sendfile_body] }
83
84
  response = etag(app).call(request)
84
- response[1]['ETag'].should.be.nil
85
+ response[1]['ETag'].must_be_nil
85
86
  end
86
87
 
87
- should "not set ETag if a status is not 200 or 201" do
88
+ it "not set ETag if a status is not 200 or 201" do
88
89
  app = lambda { |env| [401, {'Content-Type' => 'text/plain'}, ['Access denied.']] }
89
90
  response = etag(app).call(request)
90
- response[1]['ETag'].should.be.nil
91
+ response[1]['ETag'].must_be_nil
91
92
  end
92
93
 
93
- should "not set ETag if no-cache is given" do
94
+ it "not set ETag if no-cache is given" do
94
95
  app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'Cache-Control' => 'no-cache, must-revalidate'}, ['Hello, World!']] }
95
96
  response = etag(app).call(request)
96
- response[1]['ETag'].should.be.nil
97
+ response[1]['ETag'].must_be_nil
97
98
  end
98
99
 
99
- should "close the original body" do
100
+ it "close the original body" do
100
101
  body = StringIO.new
101
102
  app = lambda { |env| [200, {}, body] }
102
103
  response = etag(app).call(request)
103
- body.should.not.be.closed
104
+ body.wont_be :closed?
104
105
  response[2].close
105
- body.should.be.closed
106
+ body.must_be :closed?
106
107
  end
107
108
  end
@@ -0,0 +1,133 @@
1
+ require 'helper'
2
+ require 'rack/events'
3
+
4
+ module Rack
5
+ class TestEvents < Rack::TestCase
6
+ class EventMiddleware
7
+ attr_reader :events
8
+
9
+ def initialize events
10
+ @events = events
11
+ end
12
+
13
+ def on_start req, res
14
+ events << [self, __method__]
15
+ end
16
+
17
+ def on_commit req, res
18
+ events << [self, __method__]
19
+ end
20
+
21
+ def on_send req, res
22
+ events << [self, __method__]
23
+ end
24
+
25
+ def on_finish req, res
26
+ events << [self, __method__]
27
+ end
28
+
29
+ def on_error req, res, e
30
+ events << [self, __method__]
31
+ end
32
+ end
33
+
34
+ def test_events_fire
35
+ events = []
36
+ ret = [200, {}, []]
37
+ app = lambda { |env| events << [app, :call]; ret }
38
+ se = EventMiddleware.new events
39
+ e = Events.new app, [se]
40
+ triple = e.call({})
41
+ response_body = []
42
+ triple[2].each { |x| response_body << x }
43
+ triple[2].close
44
+ triple[2] = response_body
45
+ assert_equal ret, triple
46
+ assert_equal [[se, :on_start],
47
+ [app, :call],
48
+ [se, :on_commit],
49
+ [se, :on_send],
50
+ [se, :on_finish],
51
+ ], events
52
+ end
53
+
54
+ def test_send_and_finish_are_not_run_until_body_is_sent
55
+ events = []
56
+ ret = [200, {}, []]
57
+ app = lambda { |env| events << [app, :call]; ret }
58
+ se = EventMiddleware.new events
59
+ e = Events.new app, [se]
60
+ triple = e.call({})
61
+ assert_equal [[se, :on_start],
62
+ [app, :call],
63
+ [se, :on_commit],
64
+ ], events
65
+ end
66
+
67
+ def test_send_is_called_on_each
68
+ events = []
69
+ ret = [200, {}, []]
70
+ app = lambda { |env| events << [app, :call]; ret }
71
+ se = EventMiddleware.new events
72
+ e = Events.new app, [se]
73
+ triple = e.call({})
74
+ triple[2].each { |x| }
75
+ assert_equal [[se, :on_start],
76
+ [app, :call],
77
+ [se, :on_commit],
78
+ [se, :on_send],
79
+ ], events
80
+ end
81
+
82
+ def test_finish_is_called_on_close
83
+ events = []
84
+ ret = [200, {}, []]
85
+ app = lambda { |env| events << [app, :call]; ret }
86
+ se = EventMiddleware.new events
87
+ e = Events.new app, [se]
88
+ triple = e.call({})
89
+ triple[2].each { |x| }
90
+ triple[2].close
91
+ assert_equal [[se, :on_start],
92
+ [app, :call],
93
+ [se, :on_commit],
94
+ [se, :on_send],
95
+ [se, :on_finish],
96
+ ], events
97
+ end
98
+
99
+ def test_finish_is_called_in_reverse_order
100
+ events = []
101
+ ret = [200, {}, []]
102
+ app = lambda { |env| events << [app, :call]; ret }
103
+ se1 = EventMiddleware.new events
104
+ se2 = EventMiddleware.new events
105
+ se3 = EventMiddleware.new events
106
+
107
+ e = Events.new app, [se1, se2, se3]
108
+ triple = e.call({})
109
+ triple[2].each { |x| }
110
+ triple[2].close
111
+
112
+ groups = events.group_by { |x| x.last }
113
+ assert_equal groups[:on_start].map(&:first), groups[:on_finish].map(&:first).reverse
114
+ assert_equal groups[:on_commit].map(&:first), groups[:on_finish].map(&:first)
115
+ assert_equal groups[:on_send].map(&:first), groups[:on_finish].map(&:first)
116
+ end
117
+
118
+ def test_finish_is_called_if_there_is_an_exception
119
+ events = []
120
+ ret = [200, {}, []]
121
+ app = lambda { |env| raise }
122
+ se = EventMiddleware.new events
123
+ e = Events.new app, [se]
124
+ assert_raises(RuntimeError) do
125
+ e.call({})
126
+ end
127
+ assert_equal [[se, :on_start],
128
+ [se, :on_error],
129
+ [se, :on_finish],
130
+ ], events
131
+ end
132
+ end
133
+ end
@@ -1,107 +1,85 @@
1
- begin
1
+ require 'helper'
2
+
3
+ if defined? LIGHTTPD_PID
4
+
2
5
  require File.expand_path('../testrequest', __FILE__)
3
6
  require 'rack/handler/fastcgi'
4
7
 
5
8
  describe Rack::Handler::FastCGI do
6
- extend TestRequest::Helpers
9
+ include TestRequest::Helpers
7
10
 
8
- @host = '127.0.0.1'
9
- @port = 9203
10
-
11
- if `which lighttpd` && !$?.success?
12
- raise "lighttpd not found"
11
+ before do
12
+ @host = '127.0.0.1'
13
+ @port = 9203
13
14
  end
14
15
 
15
- # Keep this first.
16
- $pid = fork {
17
- ENV['RACK_ENV'] = 'deployment'
18
- ENV['RUBYLIB'] = [
19
- File.expand_path('../../lib', __FILE__),
20
- ENV['RUBYLIB'],
21
- ].compact.join(':')
22
-
23
- Dir.chdir(File.expand_path("../cgi", __FILE__)) do
24
- exec "lighttpd -D -f lighttpd.conf"
25
- end
26
- }
27
-
28
- should "respond" do
16
+ it "respond" do
29
17
  sleep 1
30
18
  GET("/test")
31
- response.should.not.be.nil
19
+ response.wont_be :nil?
32
20
  end
33
21
 
34
- should "respond via rackup server" do
22
+ it "respond via rackup server" do
35
23
  GET("/sample_rackup.ru")
36
- status.should.equal 200
24
+ status.must_equal 200
37
25
  end
38
26
 
39
- should "be a lighttpd" do
27
+ it "be a lighttpd" do
40
28
  GET("/test.fcgi")
41
- status.should.equal 200
42
- response["SERVER_SOFTWARE"].should =~ /lighttpd/
43
- response["HTTP_VERSION"].should.equal "HTTP/1.1"
44
- response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
45
- response["SERVER_PORT"].should.equal @port.to_s
46
- response["SERVER_NAME"].should.equal @host
29
+ status.must_equal 200
30
+ response["SERVER_SOFTWARE"].must_match(/lighttpd/)
31
+ response["HTTP_VERSION"].must_equal "HTTP/1.1"
32
+ response["SERVER_PROTOCOL"].must_equal "HTTP/1.1"
33
+ response["SERVER_PORT"].must_equal @port.to_s
34
+ response["SERVER_NAME"].must_equal @host
47
35
  end
48
36
 
49
- should "have rack headers" do
37
+ it "have rack headers" do
50
38
  GET("/test.fcgi")
51
- response["rack.version"].should.equal [1,3]
52
- response["rack.multithread"].should.be.false
53
- response["rack.multiprocess"].should.be.true
54
- response["rack.run_once"].should.be.false
39
+ response["rack.version"].must_equal [1,3]
40
+ assert_equal false, response["rack.multithread"]
41
+ assert_equal true, response["rack.multiprocess"]
42
+ assert_equal false, response["rack.run_once"]
55
43
  end
56
44
 
57
- should "have CGI headers on GET" do
45
+ it "have CGI headers on GET" do
58
46
  GET("/test.fcgi")
59
- response["REQUEST_METHOD"].should.equal "GET"
60
- response["SCRIPT_NAME"].should.equal "/test.fcgi"
61
- response["REQUEST_PATH"].should.equal "/"
62
- response["PATH_INFO"].should.equal ""
63
- response["QUERY_STRING"].should.equal ""
64
- response["test.postdata"].should.equal ""
47
+ response["REQUEST_METHOD"].must_equal "GET"
48
+ response["SCRIPT_NAME"].must_equal "/test.fcgi"
49
+ response["REQUEST_PATH"].must_equal "/"
50
+ response["PATH_INFO"].must_equal ""
51
+ response["QUERY_STRING"].must_equal ""
52
+ response["test.postdata"].must_equal ""
65
53
 
66
54
  GET("/test.fcgi/foo?quux=1")
67
- response["REQUEST_METHOD"].should.equal "GET"
68
- response["SCRIPT_NAME"].should.equal "/test.fcgi"
69
- response["REQUEST_PATH"].should.equal "/"
70
- response["PATH_INFO"].should.equal "/foo"
71
- response["QUERY_STRING"].should.equal "quux=1"
55
+ response["REQUEST_METHOD"].must_equal "GET"
56
+ response["SCRIPT_NAME"].must_equal "/test.fcgi"
57
+ response["REQUEST_PATH"].must_equal "/"
58
+ response["PATH_INFO"].must_equal "/foo"
59
+ response["QUERY_STRING"].must_equal "quux=1"
72
60
  end
73
61
 
74
- should "have CGI headers on POST" do
62
+ it "have CGI headers on POST" do
75
63
  POST("/test.fcgi", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
76
- status.should.equal 200
77
- response["REQUEST_METHOD"].should.equal "POST"
78
- response["SCRIPT_NAME"].should.equal "/test.fcgi"
79
- response["REQUEST_PATH"].should.equal "/"
80
- response["QUERY_STRING"].should.equal ""
81
- response["HTTP_X_TEST_HEADER"].should.equal "42"
82
- response["test.postdata"].should.equal "rack-form-data=23"
64
+ status.must_equal 200
65
+ response["REQUEST_METHOD"].must_equal "POST"
66
+ response["SCRIPT_NAME"].must_equal "/test.fcgi"
67
+ response["REQUEST_PATH"].must_equal "/"
68
+ response["QUERY_STRING"].must_equal ""
69
+ response["HTTP_X_TEST_HEADER"].must_equal "42"
70
+ response["test.postdata"].must_equal "rack-form-data=23"
83
71
  end
84
72
 
85
- should "support HTTP auth" do
73
+ it "support HTTP auth" do
86
74
  GET("/test.fcgi", {:user => "ruth", :passwd => "secret"})
87
- response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
75
+ response["HTTP_AUTHORIZATION"].must_equal "Basic cnV0aDpzZWNyZXQ="
88
76
  end
89
77
 
90
- should "set status" do
78
+ it "set status" do
91
79
  GET("/test.fcgi?secret")
92
- status.should.equal 403
93
- response["rack.url_scheme"].should.equal "http"
94
- end
95
-
96
- # Keep this last.
97
- should "shutdown" do
98
- Process.kill 15, $pid
99
- Process.wait($pid).should.equal $pid
80
+ status.must_equal 403
81
+ response["rack.url_scheme"].must_equal "http"
100
82
  end
101
83
  end
102
84
 
103
- rescue RuntimeError
104
- $stderr.puts "Skipping Rack::Handler::FastCGI tests (lighttpd is required). Install lighttpd and try again."
105
- rescue LoadError
106
- $stderr.puts "Skipping Rack::Handler::FastCGI tests (FCGI is required). `gem install fcgi` and try again."
107
- end
85
+ end # if defined? LIGHTTPD_PID
@@ -1,3 +1,4 @@
1
+ require 'minitest/autorun'
1
2
  require 'rack/file'
2
3
  require 'rack/lint'
3
4
  require 'rack/mock'
@@ -9,213 +10,231 @@ describe Rack::File do
9
10
  Rack::Lint.new Rack::File.new(*args)
10
11
  end
11
12
 
12
- should "serve files" do
13
+ it 'serves files with + in the file name' do
14
+ Dir.mktmpdir do |dir|
15
+ File.write File.join(dir, "you+me.txt"), "hello world"
16
+ app = file(dir)
17
+ env = Rack::MockRequest.env_for("/you+me.txt")
18
+ status,_,body = app.call env
19
+
20
+ assert_equal 200, status
21
+
22
+ str = ''
23
+ body.each { |x| str << x }
24
+ assert_match "hello world", str
25
+ end
26
+ end
27
+
28
+ it "serve files" do
13
29
  res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/test")
14
30
 
15
- res.should.be.ok
16
- res.should =~ /ruby/
31
+ res.must_be :ok?
32
+ assert_match(res, /ruby/)
17
33
  end
18
34
 
19
- should "set Last-Modified header" do
35
+ it "set Last-Modified header" do
20
36
  res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/test")
21
37
 
22
38
  path = File.join(DOCROOT, "/cgi/test")
23
39
 
24
- res.should.be.ok
25
- res["Last-Modified"].should.equal File.mtime(path).httpdate
40
+ res.must_be :ok?
41
+ res["Last-Modified"].must_equal File.mtime(path).httpdate
26
42
  end
27
43
 
28
- should "return 304 if file isn't modified since last serve" do
44
+ it "return 304 if file isn't modified since last serve" do
29
45
  path = File.join(DOCROOT, "/cgi/test")
30
46
  res = Rack::MockRequest.new(file(DOCROOT)).
31
47
  get("/cgi/test", 'HTTP_IF_MODIFIED_SINCE' => File.mtime(path).httpdate)
32
48
 
33
- res.status.should.equal 304
34
- res.body.should.be.empty
49
+ res.status.must_equal 304
50
+ res.body.must_be :empty?
35
51
  end
36
52
 
37
- should "return the file if it's modified since last serve" do
53
+ it "return the file if it's modified since last serve" do
38
54
  path = File.join(DOCROOT, "/cgi/test")
39
55
  res = Rack::MockRequest.new(file(DOCROOT)).
40
56
  get("/cgi/test", 'HTTP_IF_MODIFIED_SINCE' => (File.mtime(path) - 100).httpdate)
41
57
 
42
- res.should.be.ok
58
+ res.must_be :ok?
43
59
  end
44
60
 
45
- should "serve files with URL encoded filenames" do
61
+ it "serve files with URL encoded filenames" do
46
62
  res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/%74%65%73%74") # "/cgi/test"
47
63
 
48
- res.should.be.ok
49
- res.should =~ /ruby/
64
+ res.must_be :ok?
65
+ # res.must_match(/ruby/) # nope
66
+ # (/ruby/).must_match res # This is wierd, but an oddity of minitest
67
+ # assert_match(/ruby/, res) # nope
68
+ assert_match(res, /ruby/)
50
69
  end
51
70
 
52
- should "allow safe directory traversal" do
71
+ it "allow safe directory traversal" do
53
72
  req = Rack::MockRequest.new(file(DOCROOT))
54
73
 
55
74
  res = req.get('/cgi/../cgi/test')
56
- res.should.be.successful
75
+ res.must_be :successful?
57
76
 
58
77
  res = req.get('.')
59
- res.should.be.not_found
78
+ res.must_be :not_found?
60
79
 
61
80
  res = req.get("test/..")
62
- res.should.be.not_found
81
+ res.must_be :not_found?
63
82
  end
64
83
 
65
- should "not allow unsafe directory traversal" do
84
+ it "not allow unsafe directory traversal" do
66
85
  req = Rack::MockRequest.new(file(DOCROOT))
67
86
 
68
87
  res = req.get("/../README.rdoc")
69
- res.should.be.client_error
88
+ res.must_be :client_error?
70
89
 
71
90
  res = req.get("../test/spec_file.rb")
72
- res.should.be.client_error
91
+ res.must_be :client_error?
73
92
 
74
93
  res = req.get("../README.rdoc")
75
- res.should.be.client_error
94
+ res.must_be :client_error?
76
95
 
77
- res.should.be.not_found
96
+ res.must_be :not_found?
78
97
  end
79
98
 
80
- should "allow files with .. in their name" do
99
+ it "allow files with .. in their name" do
81
100
  req = Rack::MockRequest.new(file(DOCROOT))
82
101
  res = req.get("/cgi/..test")
83
- res.should.be.not_found
102
+ res.must_be :not_found?
84
103
 
85
104
  res = req.get("/cgi/test..")
86
- res.should.be.not_found
105
+ res.must_be :not_found?
87
106
 
88
107
  res = req.get("/cgi../test..")
89
- res.should.be.not_found
108
+ res.must_be :not_found?
90
109
  end
91
110
 
92
- should "not allow unsafe directory traversal with encoded periods" do
111
+ it "not allow unsafe directory traversal with encoded periods" do
93
112
  res = Rack::MockRequest.new(file(DOCROOT)).get("/%2E%2E/README")
94
113
 
95
- res.should.be.client_error?
96
- res.should.be.not_found
114
+ res.must_be :client_error?
115
+ res.must_be :not_found?
97
116
  end
98
117
 
99
- should "allow safe directory traversal with encoded periods" do
118
+ it "allow safe directory traversal with encoded periods" do
100
119
  res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/%2E%2E/cgi/test")
101
120
 
102
- res.should.be.successful
121
+ res.must_be :successful?
103
122
  end
104
123
 
105
- should "404 if it can't find the file" do
124
+ it "404 if it can't find the file" do
106
125
  res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/blubb")
107
126
 
108
- res.should.be.not_found
127
+ res.must_be :not_found?
109
128
  end
110
129
 
111
- should "detect SystemCallErrors" do
130
+ it "detect SystemCallErrors" do
112
131
  res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi")
113
132
 
114
- res.should.be.not_found
133
+ res.must_be :not_found?
115
134
  end
116
135
 
117
- should "return bodies that respond to #to_path" do
136
+ it "return bodies that respond to #to_path" do
118
137
  env = Rack::MockRequest.env_for("/cgi/test")
119
138
  status, _, body = Rack::File.new(DOCROOT).call(env)
120
139
 
121
140
  path = File.join(DOCROOT, "/cgi/test")
122
141
 
123
- status.should.equal 200
124
- body.should.respond_to :to_path
125
- body.to_path.should.equal path
142
+ status.must_equal 200
143
+ body.must_respond_to :to_path
144
+ body.to_path.must_equal path
126
145
  end
127
146
 
128
- should "return correct byte range in body" do
147
+ it "return correct byte range in body" do
129
148
  env = Rack::MockRequest.env_for("/cgi/test")
130
149
  env["HTTP_RANGE"] = "bytes=22-33"
131
150
  res = Rack::MockResponse.new(*file(DOCROOT).call(env))
132
151
 
133
- res.status.should.equal 206
134
- res["Content-Length"].should.equal "12"
135
- res["Content-Range"].should.equal "bytes 22-33/193"
136
- res.body.should.equal "-*- ruby -*-"
152
+ res.status.must_equal 206
153
+ res["Content-Length"].must_equal "12"
154
+ res["Content-Range"].must_equal "bytes 22-33/193"
155
+ res.body.must_equal "-*- ruby -*-"
137
156
  end
138
157
 
139
- should "return error for unsatisfiable byte range" do
158
+ it "return error for unsatisfiable byte range" do
140
159
  env = Rack::MockRequest.env_for("/cgi/test")
141
160
  env["HTTP_RANGE"] = "bytes=1234-5678"
142
161
  res = Rack::MockResponse.new(*file(DOCROOT).call(env))
143
162
 
144
- res.status.should.equal 416
145
- res["Content-Range"].should.equal "bytes */193"
163
+ res.status.must_equal 416
164
+ res["Content-Range"].must_equal "bytes */193"
146
165
  end
147
166
 
148
- should "support custom http headers" do
167
+ it "support custom http headers" do
149
168
  env = Rack::MockRequest.env_for("/cgi/test")
150
169
  status, heads, _ = file(DOCROOT, 'Cache-Control' => 'public, max-age=38',
151
170
  'Access-Control-Allow-Origin' => '*').call(env)
152
171
 
153
- status.should.equal 200
154
- heads['Cache-Control'].should.equal 'public, max-age=38'
155
- heads['Access-Control-Allow-Origin'].should.equal '*'
172
+ status.must_equal 200
173
+ heads['Cache-Control'].must_equal 'public, max-age=38'
174
+ heads['Access-Control-Allow-Origin'].must_equal '*'
156
175
  end
157
176
 
158
- should "support not add custom http headers if none are supplied" do
177
+ it "support not add custom http headers if none are supplied" do
159
178
  env = Rack::MockRequest.env_for("/cgi/test")
160
179
  status, heads, _ = file(DOCROOT).call(env)
161
180
 
162
- status.should.equal 200
163
- heads['Cache-Control'].should.equal nil
164
- heads['Access-Control-Allow-Origin'].should.equal nil
181
+ status.must_equal 200
182
+ heads['Cache-Control'].must_equal nil
183
+ heads['Access-Control-Allow-Origin'].must_equal nil
165
184
  end
166
185
 
167
- should "only support GET, HEAD, and OPTIONS requests" do
186
+ it "only support GET, HEAD, and OPTIONS requests" do
168
187
  req = Rack::MockRequest.new(file(DOCROOT))
169
188
 
170
189
  forbidden = %w[post put patch delete]
171
190
  forbidden.each do |method|
172
191
  res = req.send(method, "/cgi/test")
173
- res.should.be.client_error
174
- res.should.be.method_not_allowed
175
- res.headers['Allow'].split(/, */).sort.should == %w(GET HEAD OPTIONS)
192
+ res.must_be :client_error?
193
+ res.must_be :method_not_allowed?
194
+ res.headers['Allow'].split(/, */).sort.must_equal %w(GET HEAD OPTIONS)
176
195
  end
177
196
 
178
197
  allowed = %w[get head options]
179
198
  allowed.each do |method|
180
199
  res = req.send(method, "/cgi/test")
181
- res.should.be.successful
200
+ res.must_be :successful?
182
201
  end
183
202
  end
184
203
 
185
- should "set Allow correctly for OPTIONS requests" do
204
+ it "set Allow correctly for OPTIONS requests" do
186
205
  req = Rack::MockRequest.new(file(DOCROOT))
187
206
  res = req.options('/cgi/test')
188
- res.should.be.successful
189
- res.headers['Allow'].should.not.equal nil
190
- res.headers['Allow'].split(/, */).sort.should == %w(GET HEAD OPTIONS)
207
+ res.must_be :successful?
208
+ res.headers['Allow'].wont_equal nil
209
+ res.headers['Allow'].split(/, */).sort.must_equal %w(GET HEAD OPTIONS)
191
210
  end
192
211
 
193
- should "set Content-Length correctly for HEAD requests" do
212
+ it "set Content-Length correctly for HEAD requests" do
194
213
  req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT)))
195
214
  res = req.head "/cgi/test"
196
- res.should.be.successful
197
- res['Content-Length'].should.equal "193"
215
+ res.must_be :successful?
216
+ res['Content-Length'].must_equal "193"
198
217
  end
199
218
 
200
- should "default to a mime type of text/plain" do
219
+ it "default to a mime type of text/plain" do
201
220
  req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT)))
202
221
  res = req.get "/cgi/test"
203
- res.should.be.successful
204
- res['Content-Type'].should.equal "text/plain"
222
+ res.must_be :successful?
223
+ res['Content-Type'].must_equal "text/plain"
205
224
  end
206
225
 
207
- should "allow the default mime type to be set" do
226
+ it "allow the default mime type to be set" do
208
227
  req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT, nil, 'application/octet-stream')))
209
228
  res = req.get "/cgi/test"
210
- res.should.be.successful
211
- res['Content-Type'].should.equal "application/octet-stream"
229
+ res.must_be :successful?
230
+ res['Content-Type'].must_equal "application/octet-stream"
212
231
  end
213
232
 
214
- should "not set Content-Type if the mime type is not set" do
233
+ it "not set Content-Type if the mime type is not set" do
215
234
  req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT, nil, nil)))
216
235
  res = req.get "/cgi/test"
217
- res.should.be.successful
218
- res['Content-Type'].should.equal nil
236
+ res.must_be :successful?
237
+ res['Content-Type'].must_equal nil
219
238
  end
220
239
 
221
240
  end