rack 1.1.6 → 1.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +1 -1
  3. data/HISTORY.md +375 -0
  4. data/KNOWN-ISSUES +23 -0
  5. data/README.rdoc +312 -0
  6. data/Rakefile +124 -0
  7. data/SPEC +125 -32
  8. data/contrib/rack.png +0 -0
  9. data/contrib/rack.svg +150 -0
  10. data/contrib/rack_logo.svg +1 -1
  11. data/contrib/rdoc.css +412 -0
  12. data/example/protectedlobster.rb +1 -1
  13. data/lib/rack/auth/abstract/handler.rb +4 -4
  14. data/lib/rack/auth/abstract/request.rb +7 -5
  15. data/lib/rack/auth/basic.rb +1 -1
  16. data/lib/rack/auth/digest/md5.rb +7 -3
  17. data/lib/rack/auth/digest/nonce.rb +1 -1
  18. data/lib/rack/auth/digest/params.rb +7 -9
  19. data/lib/rack/auth/digest/request.rb +10 -9
  20. data/lib/rack/backports/uri/common_18.rb +56 -0
  21. data/lib/rack/backports/uri/common_192.rb +52 -0
  22. data/lib/rack/backports/uri/common_193.rb +29 -0
  23. data/lib/rack/body_proxy.rb +39 -0
  24. data/lib/rack/builder.rb +106 -22
  25. data/lib/rack/cascade.rb +17 -6
  26. data/lib/rack/chunked.rb +44 -24
  27. data/lib/rack/commonlogger.rb +36 -13
  28. data/lib/rack/conditionalget.rb +49 -17
  29. data/lib/rack/config.rb +5 -0
  30. data/lib/rack/content_length.rb +14 -6
  31. data/lib/rack/content_type.rb +7 -1
  32. data/lib/rack/deflater.rb +73 -15
  33. data/lib/rack/directory.rb +18 -8
  34. data/lib/rack/etag.rb +59 -9
  35. data/lib/rack/file.rb +106 -44
  36. data/lib/rack/handler/cgi.rb +11 -11
  37. data/lib/rack/handler/fastcgi.rb +18 -6
  38. data/lib/rack/handler/lsws.rb +2 -4
  39. data/lib/rack/handler/mongrel.rb +22 -6
  40. data/lib/rack/handler/scgi.rb +16 -8
  41. data/lib/rack/handler/thin.rb +19 -4
  42. data/lib/rack/handler/webrick.rb +72 -19
  43. data/lib/rack/handler.rb +47 -14
  44. data/lib/rack/head.rb +10 -2
  45. data/lib/rack/lint.rb +260 -75
  46. data/lib/rack/lobster.rb +13 -8
  47. data/lib/rack/lock.rb +13 -3
  48. data/lib/rack/logger.rb +0 -2
  49. data/lib/rack/methodoverride.rb +27 -8
  50. data/lib/rack/mime.rb +625 -167
  51. data/lib/rack/mock.rb +78 -53
  52. data/lib/rack/multipart/generator.rb +93 -0
  53. data/lib/rack/multipart/parser.rb +253 -0
  54. data/lib/rack/multipart/uploaded_file.rb +34 -0
  55. data/lib/rack/multipart.rb +34 -0
  56. data/lib/rack/nulllogger.rb +21 -2
  57. data/lib/rack/recursive.rb +10 -5
  58. data/lib/rack/reloader.rb +3 -2
  59. data/lib/rack/request.rb +201 -74
  60. data/lib/rack/response.rb +41 -28
  61. data/lib/rack/rewindable_input.rb +15 -11
  62. data/lib/rack/runtime.rb +16 -3
  63. data/lib/rack/sendfile.rb +47 -29
  64. data/lib/rack/server.rb +223 -47
  65. data/lib/rack/session/abstract/id.rb +289 -30
  66. data/lib/rack/session/cookie.rb +133 -44
  67. data/lib/rack/session/memcache.rb +30 -56
  68. data/lib/rack/session/pool.rb +19 -43
  69. data/lib/rack/showexceptions.rb +53 -15
  70. data/lib/rack/showstatus.rb +14 -7
  71. data/lib/rack/static.rb +124 -12
  72. data/lib/rack/tempfile_reaper.rb +22 -0
  73. data/lib/rack/urlmap.rb +49 -15
  74. data/lib/rack/utils/okjson.rb +600 -0
  75. data/lib/rack/utils.rb +363 -361
  76. data/lib/rack.rb +17 -23
  77. data/rack.gemspec +11 -20
  78. data/test/builder/anything.rb +5 -0
  79. data/test/builder/comment.ru +4 -0
  80. data/test/builder/end.ru +5 -0
  81. data/test/builder/line.ru +1 -0
  82. data/test/builder/options.ru +2 -0
  83. data/test/cgi/assets/folder/test.js +1 -0
  84. data/test/cgi/assets/fonts/font.eot +1 -0
  85. data/test/cgi/assets/images/image.png +1 -0
  86. data/test/cgi/assets/index.html +1 -0
  87. data/test/cgi/assets/javascripts/app.js +1 -0
  88. data/test/cgi/assets/stylesheets/app.css +1 -0
  89. data/test/cgi/lighttpd.conf +26 -0
  90. data/test/cgi/rackup_stub.rb +6 -0
  91. data/test/cgi/sample_rackup.ru +5 -0
  92. data/test/cgi/test +9 -0
  93. data/test/cgi/test+directory/test+file +1 -0
  94. data/test/cgi/test.fcgi +8 -0
  95. data/test/cgi/test.ru +5 -0
  96. data/test/gemloader.rb +10 -0
  97. data/test/multipart/bad_robots +259 -0
  98. data/test/multipart/binary +0 -0
  99. data/test/multipart/content_type_and_no_filename +6 -0
  100. data/test/multipart/empty +10 -0
  101. data/test/multipart/fail_16384_nofile +814 -0
  102. data/test/multipart/file1.txt +1 -0
  103. data/test/multipart/filename_and_modification_param +7 -0
  104. data/test/multipart/filename_and_no_name +6 -0
  105. data/test/multipart/filename_with_escaped_quotes +6 -0
  106. data/test/multipart/filename_with_escaped_quotes_and_modification_param +7 -0
  107. data/test/multipart/filename_with_null_byte +7 -0
  108. data/test/multipart/filename_with_percent_escaped_quotes +6 -0
  109. data/test/multipart/filename_with_unescaped_percentages +6 -0
  110. data/test/multipart/filename_with_unescaped_percentages2 +6 -0
  111. data/test/multipart/filename_with_unescaped_percentages3 +6 -0
  112. data/test/multipart/filename_with_unescaped_quotes +6 -0
  113. data/test/multipart/ie +6 -0
  114. data/test/multipart/invalid_character +6 -0
  115. data/test/multipart/mixed_files +21 -0
  116. data/test/multipart/nested +10 -0
  117. data/test/multipart/none +9 -0
  118. data/test/multipart/semicolon +6 -0
  119. data/test/multipart/text +15 -0
  120. data/test/multipart/three_files_three_fields +31 -0
  121. data/test/multipart/webkit +32 -0
  122. data/test/rackup/config.ru +31 -0
  123. data/test/registering_handler/rack/handler/registering_myself.rb +8 -0
  124. data/test/{spec_rack_auth_basic.rb → spec_auth_basic.rb} +23 -15
  125. data/test/{spec_rack_auth_digest.rb → spec_auth_digest.rb} +56 -29
  126. data/test/spec_body_proxy.rb +85 -0
  127. data/test/spec_builder.rb +223 -0
  128. data/test/{spec_rack_cascade.rb → spec_cascade.rb} +28 -15
  129. data/test/{spec_rack_cgi.rb → spec_cgi.rb} +44 -31
  130. data/test/spec_chunked.rb +101 -0
  131. data/test/spec_commonlogger.rb +93 -0
  132. data/test/spec_conditionalget.rb +102 -0
  133. data/test/{spec_rack_config.rb → spec_config.rb} +6 -8
  134. data/test/spec_content_length.rb +85 -0
  135. data/test/spec_content_type.rb +45 -0
  136. data/test/spec_deflater.rb +339 -0
  137. data/test/{spec_rack_directory.rb → spec_directory.rb} +37 -10
  138. data/test/spec_etag.rb +107 -0
  139. data/test/{spec_rack_fastcgi.rb → spec_fastcgi.rb} +47 -29
  140. data/test/spec_file.rb +221 -0
  141. data/test/spec_handler.rb +72 -0
  142. data/test/spec_head.rb +45 -0
  143. data/test/{spec_rack_lint.rb → spec_lint.rb} +82 -60
  144. data/test/spec_lobster.rb +58 -0
  145. data/test/spec_lock.rb +164 -0
  146. data/test/spec_logger.rb +23 -0
  147. data/test/spec_methodoverride.rb +95 -0
  148. data/test/spec_mime.rb +51 -0
  149. data/test/{spec_rack_mock.rb → spec_mock.rb} +92 -38
  150. data/test/{spec_rack_mongrel.rb → spec_mongrel.rb} +46 -53
  151. data/test/spec_multipart.rb +600 -0
  152. data/test/spec_nulllogger.rb +20 -0
  153. data/test/spec_recursive.rb +72 -0
  154. data/test/spec_request.rb +1227 -0
  155. data/test/spec_response.rb +407 -0
  156. data/test/spec_rewindable_input.rb +118 -0
  157. data/test/spec_runtime.rb +49 -0
  158. data/test/spec_sendfile.rb +130 -0
  159. data/test/spec_server.rb +167 -0
  160. data/test/spec_session_abstract_id.rb +53 -0
  161. data/test/spec_session_cookie.rb +410 -0
  162. data/test/{spec_rack_session_memcache.rb → spec_session_memcache.rb} +119 -71
  163. data/test/{spec_rack_session_pool.rb → spec_session_pool.rb} +106 -69
  164. data/test/spec_showexceptions.rb +85 -0
  165. data/test/spec_showstatus.rb +103 -0
  166. data/test/spec_static.rb +145 -0
  167. data/test/spec_tempfile_reaper.rb +63 -0
  168. data/test/{spec_rack_thin.rb → spec_thin.rb} +35 -35
  169. data/test/{spec_rack_urlmap.rb → spec_urlmap.rb} +40 -19
  170. data/test/spec_utils.rb +647 -0
  171. data/test/spec_version.rb +17 -0
  172. data/test/spec_webrick.rb +184 -0
  173. data/test/static/another/index.html +1 -0
  174. data/test/static/index.html +1 -0
  175. data/test/testrequest.rb +78 -0
  176. data/test/unregistered_handler/rack/handler/unregistered.rb +7 -0
  177. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +7 -0
  178. metadata +220 -239
  179. data/RDOX +0 -0
  180. data/README +0 -592
  181. data/lib/rack/adapter/camping.rb +0 -22
  182. data/test/spec_auth.rb +0 -57
  183. data/test/spec_rack_builder.rb +0 -84
  184. data/test/spec_rack_camping.rb +0 -55
  185. data/test/spec_rack_chunked.rb +0 -62
  186. data/test/spec_rack_commonlogger.rb +0 -61
  187. data/test/spec_rack_conditionalget.rb +0 -41
  188. data/test/spec_rack_content_length.rb +0 -43
  189. data/test/spec_rack_content_type.rb +0 -30
  190. data/test/spec_rack_deflater.rb +0 -127
  191. data/test/spec_rack_etag.rb +0 -17
  192. data/test/spec_rack_file.rb +0 -75
  193. data/test/spec_rack_handler.rb +0 -43
  194. data/test/spec_rack_head.rb +0 -30
  195. data/test/spec_rack_lobster.rb +0 -45
  196. data/test/spec_rack_lock.rb +0 -38
  197. data/test/spec_rack_logger.rb +0 -21
  198. data/test/spec_rack_methodoverride.rb +0 -60
  199. data/test/spec_rack_nulllogger.rb +0 -13
  200. data/test/spec_rack_recursive.rb +0 -77
  201. data/test/spec_rack_request.rb +0 -594
  202. data/test/spec_rack_response.rb +0 -221
  203. data/test/spec_rack_rewindable_input.rb +0 -118
  204. data/test/spec_rack_runtime.rb +0 -35
  205. data/test/spec_rack_sendfile.rb +0 -86
  206. data/test/spec_rack_session_cookie.rb +0 -92
  207. data/test/spec_rack_showexceptions.rb +0 -21
  208. data/test/spec_rack_showstatus.rb +0 -72
  209. data/test/spec_rack_static.rb +0 -37
  210. data/test/spec_rack_utils.rb +0 -557
  211. data/test/spec_rack_webrick.rb +0 -130
  212. data/test/spec_rackup.rb +0 -164
@@ -0,0 +1,103 @@
1
+ require 'rack/showstatus'
2
+ require 'rack/lint'
3
+ require 'rack/mock'
4
+ require 'rack/utils'
5
+
6
+ describe Rack::ShowStatus do
7
+ def show_status(app)
8
+ Rack::Lint.new Rack::ShowStatus.new(app)
9
+ end
10
+
11
+ should "provide a default status message" do
12
+ req = Rack::MockRequest.new(
13
+ show_status(lambda{|env|
14
+ [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
15
+ }))
16
+
17
+ res = req.get("/", :lint => true)
18
+ res.should.be.not_found
19
+ res.should.be.not.empty
20
+
21
+ res["Content-Type"].should.equal("text/html")
22
+ res.should =~ /404/
23
+ res.should =~ /Not Found/
24
+ end
25
+
26
+ should "let the app provide additional information" do
27
+ req = Rack::MockRequest.new(
28
+ show_status(
29
+ lambda{|env|
30
+ env["rack.showstatus.detail"] = "gone too meta."
31
+ [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
32
+ }))
33
+
34
+ res = req.get("/", :lint => true)
35
+ res.should.be.not_found
36
+ res.should.be.not.empty
37
+
38
+ res["Content-Type"].should.equal("text/html")
39
+ res.should =~ /404/
40
+ res.should =~ /Not Found/
41
+ res.should =~ /too meta/
42
+ end
43
+
44
+ should "escape error" do
45
+ detail = "<script>alert('hi \"')</script>"
46
+ req = Rack::MockRequest.new(
47
+ show_status(
48
+ lambda{|env|
49
+ env["rack.showstatus.detail"] = detail
50
+ [500, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
51
+ }))
52
+
53
+ res = req.get("/", :lint => true)
54
+ res.should.be.not.empty
55
+
56
+ res["Content-Type"].should.equal("text/html")
57
+ res.should =~ /500/
58
+ res.should.not.include detail
59
+ res.body.should.include Rack::Utils.escape_html(detail)
60
+ end
61
+
62
+ should "not replace existing messages" do
63
+ req = Rack::MockRequest.new(
64
+ show_status(
65
+ lambda{|env|
66
+ [404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]]
67
+ }))
68
+
69
+ res = req.get("/", :lint => true)
70
+ res.should.be.not_found
71
+
72
+ res.body.should == "foo!"
73
+ end
74
+
75
+ should "pass on original headers" do
76
+ headers = {"WWW-Authenticate" => "Basic blah"}
77
+
78
+ req = Rack::MockRequest.new(
79
+ show_status(lambda{|env| [401, headers, []] }))
80
+ res = req.get("/", :lint => true)
81
+
82
+ res["WWW-Authenticate"].should.equal("Basic blah")
83
+ end
84
+
85
+ should "replace existing messages if there is detail" do
86
+ req = Rack::MockRequest.new(
87
+ show_status(
88
+ lambda{|env|
89
+ env["rack.showstatus.detail"] = "gone too meta."
90
+ [404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]]
91
+ }))
92
+
93
+ res = req.get("/", :lint => true)
94
+ res.should.be.not_found
95
+ res.should.be.not.empty
96
+
97
+ res["Content-Type"].should.equal("text/html")
98
+ res["Content-Length"].should.not.equal("4")
99
+ res.should =~ /404/
100
+ res.should =~ /too meta/
101
+ res.body.should.not =~ /foo/
102
+ end
103
+ end
@@ -0,0 +1,145 @@
1
+ require 'rack/static'
2
+ require 'rack/lint'
3
+ require 'rack/mock'
4
+
5
+ class DummyApp
6
+ def call(env)
7
+ [200, {"Content-Type" => "text/plain"}, ["Hello World"]]
8
+ end
9
+ end
10
+
11
+ describe Rack::Static do
12
+ def static(app, *args)
13
+ Rack::Lint.new Rack::Static.new(app, *args)
14
+ end
15
+
16
+ root = File.expand_path(File.dirname(__FILE__))
17
+
18
+ OPTIONS = {:urls => ["/cgi"], :root => root}
19
+ STATIC_OPTIONS = {:urls => [""], :root => "#{root}/static", :index => 'index.html'}
20
+ HASH_OPTIONS = {:urls => {"/cgi/sekret" => 'cgi/test'}, :root => root}
21
+
22
+ @request = Rack::MockRequest.new(static(DummyApp.new, OPTIONS))
23
+ @static_request = Rack::MockRequest.new(static(DummyApp.new, STATIC_OPTIONS))
24
+ @hash_request = Rack::MockRequest.new(static(DummyApp.new, HASH_OPTIONS))
25
+
26
+ it "serves files" do
27
+ res = @request.get("/cgi/test")
28
+ res.should.be.ok
29
+ res.body.should =~ /ruby/
30
+ end
31
+
32
+ it "404s if url root is known but it can't find the file" do
33
+ res = @request.get("/cgi/foo")
34
+ res.should.be.not_found
35
+ end
36
+
37
+ it "calls down the chain if url root is not known" do
38
+ res = @request.get("/something/else")
39
+ res.should.be.ok
40
+ res.body.should == "Hello World"
41
+ end
42
+
43
+ it "calls index file when requesting root in the given folder" do
44
+ res = @static_request.get("/")
45
+ res.should.be.ok
46
+ res.body.should =~ /index!/
47
+
48
+ res = @static_request.get("/other/")
49
+ res.should.be.not_found
50
+
51
+ res = @static_request.get("/another/")
52
+ res.should.be.ok
53
+ res.body.should =~ /another index!/
54
+ end
55
+
56
+ it "doesn't call index file if :index option was omitted" do
57
+ res = @request.get("/")
58
+ res.body.should == "Hello World"
59
+ end
60
+
61
+ it "serves hidden files" do
62
+ res = @hash_request.get("/cgi/sekret")
63
+ res.should.be.ok
64
+ res.body.should =~ /ruby/
65
+ end
66
+
67
+ it "calls down the chain if the URI is not specified" do
68
+ res = @hash_request.get("/something/else")
69
+ res.should.be.ok
70
+ res.body.should == "Hello World"
71
+ end
72
+
73
+ it "supports serving fixed cache-control (legacy option)" do
74
+ opts = OPTIONS.merge(:cache_control => 'public')
75
+ request = Rack::MockRequest.new(static(DummyApp.new, opts))
76
+ res = request.get("/cgi/test")
77
+ res.should.be.ok
78
+ res.headers['Cache-Control'].should == 'public'
79
+ end
80
+
81
+ HEADER_OPTIONS = {:urls => ["/cgi"], :root => root, :header_rules => [
82
+ [:all, {'Cache-Control' => 'public, max-age=100'}],
83
+ [:fonts, {'Cache-Control' => 'public, max-age=200'}],
84
+ [%w(png jpg), {'Cache-Control' => 'public, max-age=300'}],
85
+ ['/cgi/assets/folder/', {'Cache-Control' => 'public, max-age=400'}],
86
+ ['cgi/assets/javascripts', {'Cache-Control' => 'public, max-age=500'}],
87
+ [/\.(css|erb)\z/, {'Cache-Control' => 'public, max-age=600'}]
88
+ ]}
89
+ @header_request = Rack::MockRequest.new(static(DummyApp.new, HEADER_OPTIONS))
90
+
91
+ it "supports header rule :all" do
92
+ # Headers for all files via :all shortcut
93
+ res = @header_request.get('/cgi/assets/index.html')
94
+ res.should.be.ok
95
+ res.headers['Cache-Control'].should == 'public, max-age=100'
96
+ end
97
+
98
+ it "supports header rule :fonts" do
99
+ # Headers for web fonts via :fonts shortcut
100
+ res = @header_request.get('/cgi/assets/fonts/font.eot')
101
+ res.should.be.ok
102
+ res.headers['Cache-Control'].should == 'public, max-age=200'
103
+ end
104
+
105
+ it "supports file extension header rules provided as an Array" do
106
+ # Headers for file extensions via array
107
+ res = @header_request.get('/cgi/assets/images/image.png')
108
+ res.should.be.ok
109
+ res.headers['Cache-Control'].should == 'public, max-age=300'
110
+ end
111
+
112
+ it "supports folder rules provided as a String" do
113
+ # Headers for files in folder via string
114
+ res = @header_request.get('/cgi/assets/folder/test.js')
115
+ res.should.be.ok
116
+ res.headers['Cache-Control'].should == 'public, max-age=400'
117
+ end
118
+
119
+ it "supports folder header rules provided as a String not starting with a slash" do
120
+ res = @header_request.get('/cgi/assets/javascripts/app.js')
121
+ res.should.be.ok
122
+ res.headers['Cache-Control'].should == 'public, max-age=500'
123
+ end
124
+
125
+ it "supports flexible header rules provided as Regexp" do
126
+ # Flexible Headers via Regexp
127
+ res = @header_request.get('/cgi/assets/stylesheets/app.css')
128
+ res.should.be.ok
129
+ res.headers['Cache-Control'].should == 'public, max-age=600'
130
+ end
131
+
132
+ it "prioritizes header rules over fixed cache-control setting (legacy option)" do
133
+ opts = OPTIONS.merge(
134
+ :cache_control => 'public, max-age=24',
135
+ :header_rules => [
136
+ [:all, {'Cache-Control' => 'public, max-age=42'}]
137
+ ])
138
+
139
+ request = Rack::MockRequest.new(static(DummyApp.new, opts))
140
+ res = request.get("/cgi/test")
141
+ res.should.be.ok
142
+ res.headers['Cache-Control'].should == 'public, max-age=42'
143
+ end
144
+
145
+ end
@@ -0,0 +1,63 @@
1
+ require 'rack/tempfile_reaper'
2
+ require 'rack/lint'
3
+ require 'rack/mock'
4
+
5
+ describe Rack::TempfileReaper do
6
+ class MockTempfile
7
+ attr_reader :closed
8
+
9
+ def initialize
10
+ @closed = false
11
+ end
12
+
13
+ def close!
14
+ @closed = true
15
+ end
16
+ end
17
+
18
+ before do
19
+ @env = Rack::MockRequest.env_for
20
+ end
21
+
22
+ def call(app)
23
+ Rack::Lint.new(Rack::TempfileReaper.new(app)).call(@env)
24
+ end
25
+
26
+ should 'do nothing (i.e. not bomb out) without env[rack.tempfiles]' do
27
+ app = lambda { |_| [200, {}, ['Hello, World!']] }
28
+ response = call(app)
29
+ response[2].close
30
+ response[0].should.equal(200)
31
+ end
32
+
33
+ should 'close env[rack.tempfiles] when body is closed' do
34
+ tempfile1, tempfile2 = MockTempfile.new, MockTempfile.new
35
+ @env['rack.tempfiles'] = [ tempfile1, tempfile2 ]
36
+ app = lambda { |_| [200, {}, ['Hello, World!']] }
37
+ call(app)[2].close
38
+ tempfile1.closed.should.equal true
39
+ tempfile2.closed.should.equal true
40
+ end
41
+
42
+ should 'initialize env[rack.tempfiles] when not already present' do
43
+ tempfile = MockTempfile.new
44
+ app = lambda do |env|
45
+ env['rack.tempfiles'] << tempfile
46
+ [200, {}, ['Hello, World!']]
47
+ end
48
+ call(app)[2].close
49
+ tempfile.closed.should.equal true
50
+ end
51
+
52
+ should 'append env[rack.tempfiles] when already present' do
53
+ tempfile1, tempfile2 = MockTempfile.new, MockTempfile.new
54
+ @env['rack.tempfiles'] = [ tempfile1 ]
55
+ app = lambda do |env|
56
+ env['rack.tempfiles'] << tempfile2
57
+ [200, {}, ['Hello, World!']]
58
+ end
59
+ call(app)[2].close
60
+ tempfile1.closed.should.equal true
61
+ tempfile2.closed.should.equal true
62
+ end
63
+ end
@@ -1,50 +1,47 @@
1
- require 'test/spec'
2
-
3
1
  begin
4
2
  require 'rack/handler/thin'
5
- require 'testrequest'
3
+ require File.expand_path('../testrequest', __FILE__)
6
4
  require 'timeout'
7
-
8
- context "Rack::Handler::Thin" do
9
- include TestRequest::Helpers
10
-
11
- setup do
12
- @app = Rack::Lint.new(TestRequest.new)
13
- @server = nil
14
- Thin::Logging.silent = true
15
- @thread = Thread.new do
16
- Rack::Handler::Thin.run(@app, :Host => @host='0.0.0.0', :Port => @port=9204) do |server|
17
- @server = server
18
- end
5
+
6
+ describe Rack::Handler::Thin do
7
+ extend TestRequest::Helpers
8
+
9
+ @app = Rack::Lint.new(TestRequest.new)
10
+ @server = nil
11
+ Thin::Logging.silent = true
12
+
13
+ @thread = Thread.new do
14
+ Rack::Handler::Thin.run(@app, :Host => @host='127.0.0.1', :Port => @port=9204, :tag => "tag") do |server|
15
+ @server = server
19
16
  end
20
- Thread.pass until @server && @server.running?
21
17
  end
22
18
 
23
- specify "should respond" do
24
- lambda {
25
- GET("/")
26
- }.should.not.raise
19
+ Thread.pass until @server && @server.running?
20
+
21
+ should "respond" do
22
+ GET("/")
23
+ response.should.not.be.nil
27
24
  end
28
25
 
29
- specify "should be a Thin" do
26
+ should "be a Thin" do
30
27
  GET("/")
31
- status.should.be 200
28
+ status.should.equal 200
32
29
  response["SERVER_SOFTWARE"].should =~ /thin/
33
30
  response["HTTP_VERSION"].should.equal "HTTP/1.1"
34
31
  response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
35
32
  response["SERVER_PORT"].should.equal "9204"
36
- response["SERVER_NAME"].should.equal "0.0.0.0"
33
+ response["SERVER_NAME"].should.equal "127.0.0.1"
37
34
  end
38
35
 
39
- specify "should have rack headers" do
36
+ should "have rack headers" do
40
37
  GET("/")
41
- response["rack.version"].should.equal [0,3]
42
- response["rack.multithread"].should.be false
43
- response["rack.multiprocess"].should.be false
44
- response["rack.run_once"].should.be false
38
+ response["rack.version"].should.equal [1,0]
39
+ response["rack.multithread"].should.equal false
40
+ response["rack.multiprocess"].should.equal false
41
+ response["rack.run_once"].should.equal false
45
42
  end
46
43
 
47
- specify "should have CGI headers on GET" do
44
+ should "have CGI headers on GET" do
48
45
  GET("/")
49
46
  response["REQUEST_METHOD"].should.equal "GET"
50
47
  response["REQUEST_PATH"].should.equal "/"
@@ -59,7 +56,7 @@ context "Rack::Handler::Thin" do
59
56
  response["QUERY_STRING"].should.equal "quux=1"
60
57
  end
61
58
 
62
- specify "should have CGI headers on POST" do
59
+ should "have CGI headers on POST" do
63
60
  POST("/", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
64
61
  status.should.equal 200
65
62
  response["REQUEST_METHOD"].should.equal "POST"
@@ -69,21 +66,24 @@ context "Rack::Handler::Thin" do
69
66
  response["test.postdata"].should.equal "rack-form-data=23"
70
67
  end
71
68
 
72
- specify "should support HTTP auth" do
69
+ should "support HTTP auth" do
73
70
  GET("/test", {:user => "ruth", :passwd => "secret"})
74
71
  response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
75
72
  end
76
73
 
77
- specify "should set status" do
74
+ should "set status" do
78
75
  GET("/test?secret")
79
76
  status.should.equal 403
80
77
  response["rack.url_scheme"].should.equal "http"
81
78
  end
82
79
 
83
- teardown do
84
- @server.stop!
85
- @thread.kill
80
+ should "set tag for server" do
81
+ @server.tag.should.equal 'tag'
86
82
  end
83
+
84
+ @server.stop!
85
+ @thread.kill
86
+
87
87
  end
88
88
 
89
89
  rescue LoadError
@@ -1,10 +1,8 @@
1
- require 'test/spec'
2
-
3
1
  require 'rack/urlmap'
4
2
  require 'rack/mock'
5
3
 
6
- context "Rack::URLMap" do
7
- specify "dispatches paths correctly" do
4
+ describe Rack::URLMap do
5
+ it "dispatches paths correctly" do
8
6
  app = lambda { |env|
9
7
  [200, {
10
8
  'X-ScriptName' => env['SCRIPT_NAME'],
@@ -12,11 +10,11 @@ context "Rack::URLMap" do
12
10
  'Content-Type' => 'text/plain'
13
11
  }, [""]]
14
12
  }
15
- map = Rack::URLMap.new({
13
+ map = Rack::Lint.new(Rack::URLMap.new({
16
14
  'http://foo.org/bar' => app,
17
15
  '/foo' => app,
18
16
  '/foo/bar' => app
19
- })
17
+ }))
20
18
 
21
19
  res = Rack::MockRequest.new(map).get("/")
22
20
  res.should.be.not_found
@@ -67,8 +65,8 @@ context "Rack::URLMap" do
67
65
  end
68
66
 
69
67
 
70
- specify "dispatches hosts correctly" do
71
- map = Rack::URLMap.new("http://foo.org/" => lambda { |env|
68
+ it "dispatches hosts correctly" do
69
+ map = Rack::Lint.new(Rack::URLMap.new("http://foo.org/" => lambda { |env|
72
70
  [200,
73
71
  { "Content-Type" => "text/plain",
74
72
  "X-Position" => "foo.org",
@@ -92,7 +90,7 @@ context "Rack::URLMap" do
92
90
  "X-Position" => "default.org",
93
91
  "X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
94
92
  }, [""]]}
95
- )
93
+ ))
96
94
 
97
95
  res = Rack::MockRequest.new(map).get("/")
98
96
  res.should.be.ok
@@ -112,7 +110,7 @@ context "Rack::URLMap" do
112
110
 
113
111
  res = Rack::MockRequest.new(map).get("http://foo.org/")
114
112
  res.should.be.ok
115
- res["X-Position"].should.equal "default.org"
113
+ res["X-Position"].should.equal "foo.org"
116
114
 
117
115
  res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "example.org")
118
116
  res.should.be.ok
@@ -125,8 +123,8 @@ context "Rack::URLMap" do
125
123
  res["X-Position"].should.equal "default.org"
126
124
  end
127
125
 
128
- specify "should be nestable" do
129
- map = Rack::URLMap.new("/foo" =>
126
+ should "be nestable" do
127
+ map = Rack::Lint.new(Rack::URLMap.new("/foo" =>
130
128
  Rack::URLMap.new("/bar" =>
131
129
  Rack::URLMap.new("/quux" => lambda { |env|
132
130
  [200,
@@ -135,7 +133,7 @@ context "Rack::URLMap" do
135
133
  "X-PathInfo" => env["PATH_INFO"],
136
134
  "X-ScriptName" => env["SCRIPT_NAME"],
137
135
  }, [""]]}
138
- )))
136
+ ))))
139
137
 
140
138
  res = Rack::MockRequest.new(map).get("/foo/bar")
141
139
  res.should.be.not_found
@@ -147,8 +145,8 @@ context "Rack::URLMap" do
147
145
  res["X-ScriptName"].should.equal "/foo/bar/quux"
148
146
  end
149
147
 
150
- specify "should route root apps correctly" do
151
- map = Rack::URLMap.new("/" => lambda { |env|
148
+ should "route root apps correctly" do
149
+ map = Rack::Lint.new(Rack::URLMap.new("/" => lambda { |env|
152
150
  [200,
153
151
  { "Content-Type" => "text/plain",
154
152
  "X-Position" => "root",
@@ -162,7 +160,7 @@ context "Rack::URLMap" do
162
160
  "X-PathInfo" => env["PATH_INFO"],
163
161
  "X-ScriptName" => env["SCRIPT_NAME"]
164
162
  }, [""]]}
165
- )
163
+ ))
166
164
 
167
165
  res = Rack::MockRequest.new(map).get("/foo/bar")
168
166
  res.should.be.ok
@@ -189,8 +187,8 @@ context "Rack::URLMap" do
189
187
  res["X-ScriptName"].should.equal ""
190
188
  end
191
189
 
192
- specify "should not squeeze slashes" do
193
- map = Rack::URLMap.new("/" => lambda { |env|
190
+ should "not squeeze slashes" do
191
+ map = Rack::Lint.new(Rack::URLMap.new("/" => lambda { |env|
194
192
  [200,
195
193
  { "Content-Type" => "text/plain",
196
194
  "X-Position" => "root",
@@ -204,7 +202,7 @@ context "Rack::URLMap" do
204
202
  "X-PathInfo" => env["PATH_INFO"],
205
203
  "X-ScriptName" => env["SCRIPT_NAME"]
206
204
  }, [""]]}
207
- )
205
+ ))
208
206
 
209
207
  res = Rack::MockRequest.new(map).get("/http://example.org/bar")
210
208
  res.should.be.ok
@@ -212,4 +210,27 @@ context "Rack::URLMap" do
212
210
  res["X-PathInfo"].should.equal "/http://example.org/bar"
213
211
  res["X-ScriptName"].should.equal ""
214
212
  end
213
+
214
+ should "not be case sensitive with hosts" do
215
+ map = Rack::Lint.new(Rack::URLMap.new("http://example.org/" => lambda { |env|
216
+ [200,
217
+ { "Content-Type" => "text/plain",
218
+ "X-Position" => "root",
219
+ "X-PathInfo" => env["PATH_INFO"],
220
+ "X-ScriptName" => env["SCRIPT_NAME"]
221
+ }, [""]]}
222
+ ))
223
+
224
+ res = Rack::MockRequest.new(map).get("http://example.org/")
225
+ res.should.be.ok
226
+ res["X-Position"].should.equal "root"
227
+ res["X-PathInfo"].should.equal "/"
228
+ res["X-ScriptName"].should.equal ""
229
+
230
+ res = Rack::MockRequest.new(map).get("http://EXAMPLE.ORG/")
231
+ res.should.be.ok
232
+ res["X-Position"].should.equal "root"
233
+ res["X-PathInfo"].should.equal "/"
234
+ res["X-ScriptName"].should.equal ""
235
+ end
215
236
  end