rack 1.6.11 → 2.2.0

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 (190) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +675 -0
  3. data/CONTRIBUTING.md +136 -0
  4. data/{COPYING → MIT-LICENSE} +4 -2
  5. data/README.rdoc +157 -163
  6. data/Rakefile +38 -32
  7. data/{SPEC → SPEC.rdoc} +41 -13
  8. data/bin/rackup +1 -0
  9. data/contrib/rack_logo.svg +164 -111
  10. data/example/lobster.ru +2 -0
  11. data/example/protectedlobster.rb +4 -2
  12. data/example/protectedlobster.ru +3 -1
  13. data/lib/rack/auth/abstract/handler.rb +3 -1
  14. data/lib/rack/auth/abstract/request.rb +6 -2
  15. data/lib/rack/auth/basic.rb +7 -4
  16. data/lib/rack/auth/digest/md5.rb +13 -11
  17. data/lib/rack/auth/digest/nonce.rb +6 -3
  18. data/lib/rack/auth/digest/params.rb +5 -4
  19. data/lib/rack/auth/digest/request.rb +6 -4
  20. data/lib/rack/body_proxy.rb +21 -15
  21. data/lib/rack/builder.rb +119 -26
  22. data/lib/rack/cascade.rb +28 -12
  23. data/lib/rack/chunked.rb +70 -22
  24. data/lib/rack/common_logger.rb +80 -0
  25. data/lib/rack/{conditionalget.rb → conditional_get.rb} +20 -16
  26. data/lib/rack/config.rb +2 -0
  27. data/lib/rack/content_length.rb +9 -8
  28. data/lib/rack/content_type.rb +5 -4
  29. data/lib/rack/core_ext/regexp.rb +14 -0
  30. data/lib/rack/deflater.rb +60 -70
  31. data/lib/rack/directory.rb +117 -85
  32. data/lib/rack/etag.rb +9 -7
  33. data/lib/rack/events.rb +153 -0
  34. data/lib/rack/file.rb +4 -149
  35. data/lib/rack/files.rb +218 -0
  36. data/lib/rack/handler/cgi.rb +17 -19
  37. data/lib/rack/handler/fastcgi.rb +17 -18
  38. data/lib/rack/handler/lsws.rb +14 -14
  39. data/lib/rack/handler/scgi.rb +22 -21
  40. data/lib/rack/handler/thin.rb +20 -11
  41. data/lib/rack/handler/webrick.rb +39 -32
  42. data/lib/rack/handler.rb +9 -26
  43. data/lib/rack/head.rb +16 -18
  44. data/lib/rack/lint.rb +110 -64
  45. data/lib/rack/lobster.rb +10 -10
  46. data/lib/rack/lock.rb +17 -11
  47. data/lib/rack/logger.rb +4 -2
  48. data/lib/rack/media_type.rb +43 -0
  49. data/lib/rack/{methodoverride.rb → method_override.rb} +10 -8
  50. data/lib/rack/mime.rb +27 -6
  51. data/lib/rack/mock.rb +124 -65
  52. data/lib/rack/multipart/generator.rb +20 -16
  53. data/lib/rack/multipart/parser.rb +273 -162
  54. data/lib/rack/multipart/uploaded_file.rb +15 -8
  55. data/lib/rack/multipart.rb +39 -8
  56. data/lib/rack/{nulllogger.rb → null_logger.rb} +3 -1
  57. data/lib/rack/query_parser.rb +217 -0
  58. data/lib/rack/recursive.rb +11 -9
  59. data/lib/rack/reloader.rb +8 -4
  60. data/lib/rack/request.rb +543 -305
  61. data/lib/rack/response.rb +244 -88
  62. data/lib/rack/rewindable_input.rb +5 -15
  63. data/lib/rack/runtime.rb +12 -18
  64. data/lib/rack/sendfile.rb +17 -15
  65. data/lib/rack/server.rb +125 -47
  66. data/lib/rack/session/abstract/id.rb +216 -93
  67. data/lib/rack/session/cookie.rb +47 -31
  68. data/lib/rack/session/memcache.rb +4 -87
  69. data/lib/rack/session/pool.rb +26 -17
  70. data/lib/rack/show_exceptions.rb +390 -0
  71. data/lib/rack/{showstatus.rb → show_status.rb} +8 -8
  72. data/lib/rack/static.rb +48 -11
  73. data/lib/rack/tempfile_reaper.rb +3 -3
  74. data/lib/rack/urlmap.rb +26 -19
  75. data/lib/rack/utils.rb +208 -294
  76. data/lib/rack/version.rb +29 -0
  77. data/lib/rack.rb +76 -33
  78. data/rack.gemspec +43 -30
  79. metadata +62 -183
  80. data/HISTORY.md +0 -375
  81. data/KNOWN-ISSUES +0 -44
  82. data/lib/rack/backports/uri/common_18.rb +0 -56
  83. data/lib/rack/backports/uri/common_192.rb +0 -52
  84. data/lib/rack/backports/uri/common_193.rb +0 -29
  85. data/lib/rack/commonlogger.rb +0 -72
  86. data/lib/rack/handler/evented_mongrel.rb +0 -8
  87. data/lib/rack/handler/mongrel.rb +0 -106
  88. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  89. data/lib/rack/showexceptions.rb +0 -387
  90. data/lib/rack/utils/okjson.rb +0 -600
  91. data/test/builder/anything.rb +0 -5
  92. data/test/builder/comment.ru +0 -4
  93. data/test/builder/end.ru +0 -5
  94. data/test/builder/line.ru +0 -1
  95. data/test/builder/options.ru +0 -2
  96. data/test/cgi/assets/folder/test.js +0 -1
  97. data/test/cgi/assets/fonts/font.eot +0 -1
  98. data/test/cgi/assets/images/image.png +0 -1
  99. data/test/cgi/assets/index.html +0 -1
  100. data/test/cgi/assets/javascripts/app.js +0 -1
  101. data/test/cgi/assets/stylesheets/app.css +0 -1
  102. data/test/cgi/lighttpd.conf +0 -26
  103. data/test/cgi/rackup_stub.rb +0 -6
  104. data/test/cgi/sample_rackup.ru +0 -5
  105. data/test/cgi/test +0 -9
  106. data/test/cgi/test+directory/test+file +0 -1
  107. data/test/cgi/test.fcgi +0 -8
  108. data/test/cgi/test.ru +0 -5
  109. data/test/gemloader.rb +0 -10
  110. data/test/multipart/bad_robots +0 -259
  111. data/test/multipart/binary +0 -0
  112. data/test/multipart/content_type_and_no_filename +0 -6
  113. data/test/multipart/empty +0 -10
  114. data/test/multipart/fail_16384_nofile +0 -814
  115. data/test/multipart/file1.txt +0 -1
  116. data/test/multipart/filename_and_modification_param +0 -7
  117. data/test/multipart/filename_and_no_name +0 -6
  118. data/test/multipart/filename_with_escaped_quotes +0 -6
  119. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  120. data/test/multipart/filename_with_null_byte +0 -7
  121. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  122. data/test/multipart/filename_with_unescaped_percentages +0 -6
  123. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  124. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  125. data/test/multipart/filename_with_unescaped_quotes +0 -6
  126. data/test/multipart/ie +0 -6
  127. data/test/multipart/invalid_character +0 -6
  128. data/test/multipart/mixed_files +0 -21
  129. data/test/multipart/nested +0 -10
  130. data/test/multipart/none +0 -9
  131. data/test/multipart/semicolon +0 -6
  132. data/test/multipart/text +0 -15
  133. data/test/multipart/three_files_three_fields +0 -31
  134. data/test/multipart/webkit +0 -32
  135. data/test/rackup/config.ru +0 -31
  136. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  137. data/test/spec_auth_basic.rb +0 -81
  138. data/test/spec_auth_digest.rb +0 -259
  139. data/test/spec_body_proxy.rb +0 -85
  140. data/test/spec_builder.rb +0 -223
  141. data/test/spec_cascade.rb +0 -61
  142. data/test/spec_cgi.rb +0 -102
  143. data/test/spec_chunked.rb +0 -101
  144. data/test/spec_commonlogger.rb +0 -93
  145. data/test/spec_conditionalget.rb +0 -102
  146. data/test/spec_config.rb +0 -22
  147. data/test/spec_content_length.rb +0 -85
  148. data/test/spec_content_type.rb +0 -45
  149. data/test/spec_deflater.rb +0 -339
  150. data/test/spec_directory.rb +0 -88
  151. data/test/spec_etag.rb +0 -107
  152. data/test/spec_fastcgi.rb +0 -107
  153. data/test/spec_file.rb +0 -221
  154. data/test/spec_handler.rb +0 -72
  155. data/test/spec_head.rb +0 -45
  156. data/test/spec_lint.rb +0 -550
  157. data/test/spec_lobster.rb +0 -58
  158. data/test/spec_lock.rb +0 -164
  159. data/test/spec_logger.rb +0 -23
  160. data/test/spec_methodoverride.rb +0 -111
  161. data/test/spec_mime.rb +0 -51
  162. data/test/spec_mock.rb +0 -297
  163. data/test/spec_mongrel.rb +0 -182
  164. data/test/spec_multipart.rb +0 -600
  165. data/test/spec_nulllogger.rb +0 -20
  166. data/test/spec_recursive.rb +0 -72
  167. data/test/spec_request.rb +0 -1232
  168. data/test/spec_response.rb +0 -407
  169. data/test/spec_rewindable_input.rb +0 -118
  170. data/test/spec_runtime.rb +0 -49
  171. data/test/spec_sendfile.rb +0 -130
  172. data/test/spec_server.rb +0 -167
  173. data/test/spec_session_abstract_id.rb +0 -53
  174. data/test/spec_session_cookie.rb +0 -410
  175. data/test/spec_session_memcache.rb +0 -321
  176. data/test/spec_session_pool.rb +0 -209
  177. data/test/spec_showexceptions.rb +0 -98
  178. data/test/spec_showstatus.rb +0 -103
  179. data/test/spec_static.rb +0 -145
  180. data/test/spec_tempfile_reaper.rb +0 -63
  181. data/test/spec_thin.rb +0 -91
  182. data/test/spec_urlmap.rb +0 -236
  183. data/test/spec_utils.rb +0 -647
  184. data/test/spec_version.rb +0 -17
  185. data/test/spec_webrick.rb +0 -184
  186. data/test/static/another/index.html +0 -1
  187. data/test/static/index.html +0 -1
  188. data/test/testrequest.rb +0 -78
  189. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  190. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,103 +0,0 @@
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
data/test/spec_static.rb DELETED
@@ -1,145 +0,0 @@
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
@@ -1,63 +0,0 @@
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
data/test/spec_thin.rb DELETED
@@ -1,91 +0,0 @@
1
- begin
2
- require 'rack/handler/thin'
3
- require File.expand_path('../testrequest', __FILE__)
4
- require 'timeout'
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
16
- end
17
- end
18
-
19
- Thread.pass until @server && @server.running?
20
-
21
- should "respond" do
22
- GET("/")
23
- response.should.not.be.nil
24
- end
25
-
26
- should "be a Thin" do
27
- GET("/")
28
- status.should.equal 200
29
- response["SERVER_SOFTWARE"].should =~ /thin/
30
- response["HTTP_VERSION"].should.equal "HTTP/1.1"
31
- response["SERVER_PROTOCOL"].should.equal "HTTP/1.1"
32
- response["SERVER_PORT"].should.equal "9204"
33
- response["SERVER_NAME"].should.equal "127.0.0.1"
34
- end
35
-
36
- should "have rack headers" do
37
- GET("/")
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
42
- end
43
-
44
- should "have CGI headers on GET" do
45
- GET("/")
46
- response["REQUEST_METHOD"].should.equal "GET"
47
- response["REQUEST_PATH"].should.equal "/"
48
- response["PATH_INFO"].should.be.equal "/"
49
- response["QUERY_STRING"].should.equal ""
50
- response["test.postdata"].should.equal ""
51
-
52
- GET("/test/foo?quux=1")
53
- response["REQUEST_METHOD"].should.equal "GET"
54
- response["REQUEST_PATH"].should.equal "/test/foo"
55
- response["PATH_INFO"].should.equal "/test/foo"
56
- response["QUERY_STRING"].should.equal "quux=1"
57
- end
58
-
59
- should "have CGI headers on POST" do
60
- POST("/", {"rack-form-data" => "23"}, {'X-test-header' => '42'})
61
- status.should.equal 200
62
- response["REQUEST_METHOD"].should.equal "POST"
63
- response["REQUEST_PATH"].should.equal "/"
64
- response["QUERY_STRING"].should.equal ""
65
- response["HTTP_X_TEST_HEADER"].should.equal "42"
66
- response["test.postdata"].should.equal "rack-form-data=23"
67
- end
68
-
69
- should "support HTTP auth" do
70
- GET("/test", {:user => "ruth", :passwd => "secret"})
71
- response["HTTP_AUTHORIZATION"].should.equal "Basic cnV0aDpzZWNyZXQ="
72
- end
73
-
74
- should "set status" do
75
- GET("/test?secret")
76
- status.should.equal 403
77
- response["rack.url_scheme"].should.equal "http"
78
- end
79
-
80
- should "set tag for server" do
81
- @server.tag.should.equal 'tag'
82
- end
83
-
84
- @server.stop!
85
- @thread.kill
86
-
87
- end
88
-
89
- rescue LoadError
90
- $stderr.puts "Skipping Rack::Handler::Thin tests (Thin is required). `gem install thin` and try again."
91
- end
data/test/spec_urlmap.rb DELETED
@@ -1,236 +0,0 @@
1
- require 'rack/urlmap'
2
- require 'rack/mock'
3
-
4
- describe Rack::URLMap do
5
- it "dispatches paths correctly" do
6
- app = lambda { |env|
7
- [200, {
8
- 'X-ScriptName' => env['SCRIPT_NAME'],
9
- 'X-PathInfo' => env['PATH_INFO'],
10
- 'Content-Type' => 'text/plain'
11
- }, [""]]
12
- }
13
- map = Rack::Lint.new(Rack::URLMap.new({
14
- 'http://foo.org/bar' => app,
15
- '/foo' => app,
16
- '/foo/bar' => app
17
- }))
18
-
19
- res = Rack::MockRequest.new(map).get("/")
20
- res.should.be.not_found
21
-
22
- res = Rack::MockRequest.new(map).get("/qux")
23
- res.should.be.not_found
24
-
25
- res = Rack::MockRequest.new(map).get("/foo")
26
- res.should.be.ok
27
- res["X-ScriptName"].should.equal "/foo"
28
- res["X-PathInfo"].should.equal ""
29
-
30
- res = Rack::MockRequest.new(map).get("/foo/")
31
- res.should.be.ok
32
- res["X-ScriptName"].should.equal "/foo"
33
- res["X-PathInfo"].should.equal "/"
34
-
35
- res = Rack::MockRequest.new(map).get("/foo/bar")
36
- res.should.be.ok
37
- res["X-ScriptName"].should.equal "/foo/bar"
38
- res["X-PathInfo"].should.equal ""
39
-
40
- res = Rack::MockRequest.new(map).get("/foo/bar/")
41
- res.should.be.ok
42
- res["X-ScriptName"].should.equal "/foo/bar"
43
- res["X-PathInfo"].should.equal "/"
44
-
45
- res = Rack::MockRequest.new(map).get("/foo///bar//quux")
46
- res.status.should.equal 200
47
- res.should.be.ok
48
- res["X-ScriptName"].should.equal "/foo/bar"
49
- res["X-PathInfo"].should.equal "//quux"
50
-
51
- res = Rack::MockRequest.new(map).get("/foo/quux", "SCRIPT_NAME" => "/bleh")
52
- res.should.be.ok
53
- res["X-ScriptName"].should.equal "/bleh/foo"
54
- res["X-PathInfo"].should.equal "/quux"
55
-
56
- res = Rack::MockRequest.new(map).get("/bar", 'HTTP_HOST' => 'foo.org')
57
- res.should.be.ok
58
- res["X-ScriptName"].should.equal "/bar"
59
- res["X-PathInfo"].should.be.empty
60
-
61
- res = Rack::MockRequest.new(map).get("/bar/", 'HTTP_HOST' => 'foo.org')
62
- res.should.be.ok
63
- res["X-ScriptName"].should.equal "/bar"
64
- res["X-PathInfo"].should.equal '/'
65
- end
66
-
67
-
68
- it "dispatches hosts correctly" do
69
- map = Rack::Lint.new(Rack::URLMap.new("http://foo.org/" => lambda { |env|
70
- [200,
71
- { "Content-Type" => "text/plain",
72
- "X-Position" => "foo.org",
73
- "X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
74
- }, [""]]},
75
- "http://subdomain.foo.org/" => lambda { |env|
76
- [200,
77
- { "Content-Type" => "text/plain",
78
- "X-Position" => "subdomain.foo.org",
79
- "X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
80
- }, [""]]},
81
- "http://bar.org/" => lambda { |env|
82
- [200,
83
- { "Content-Type" => "text/plain",
84
- "X-Position" => "bar.org",
85
- "X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
86
- }, [""]]},
87
- "/" => lambda { |env|
88
- [200,
89
- { "Content-Type" => "text/plain",
90
- "X-Position" => "default.org",
91
- "X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
92
- }, [""]]}
93
- ))
94
-
95
- res = Rack::MockRequest.new(map).get("/")
96
- res.should.be.ok
97
- res["X-Position"].should.equal "default.org"
98
-
99
- res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "bar.org")
100
- res.should.be.ok
101
- res["X-Position"].should.equal "bar.org"
102
-
103
- res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "foo.org")
104
- res.should.be.ok
105
- res["X-Position"].should.equal "foo.org"
106
-
107
- res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "subdomain.foo.org", "SERVER_NAME" => "foo.org")
108
- res.should.be.ok
109
- res["X-Position"].should.equal "subdomain.foo.org"
110
-
111
- res = Rack::MockRequest.new(map).get("http://foo.org/")
112
- res.should.be.ok
113
- res["X-Position"].should.equal "foo.org"
114
-
115
- res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "example.org")
116
- res.should.be.ok
117
- res["X-Position"].should.equal "default.org"
118
-
119
- res = Rack::MockRequest.new(map).get("/",
120
- "HTTP_HOST" => "example.org:9292",
121
- "SERVER_PORT" => "9292")
122
- res.should.be.ok
123
- res["X-Position"].should.equal "default.org"
124
- end
125
-
126
- should "be nestable" do
127
- map = Rack::Lint.new(Rack::URLMap.new("/foo" =>
128
- Rack::URLMap.new("/bar" =>
129
- Rack::URLMap.new("/quux" => lambda { |env|
130
- [200,
131
- { "Content-Type" => "text/plain",
132
- "X-Position" => "/foo/bar/quux",
133
- "X-PathInfo" => env["PATH_INFO"],
134
- "X-ScriptName" => env["SCRIPT_NAME"],
135
- }, [""]]}
136
- ))))
137
-
138
- res = Rack::MockRequest.new(map).get("/foo/bar")
139
- res.should.be.not_found
140
-
141
- res = Rack::MockRequest.new(map).get("/foo/bar/quux")
142
- res.should.be.ok
143
- res["X-Position"].should.equal "/foo/bar/quux"
144
- res["X-PathInfo"].should.equal ""
145
- res["X-ScriptName"].should.equal "/foo/bar/quux"
146
- end
147
-
148
- should "route root apps correctly" do
149
- map = Rack::Lint.new(Rack::URLMap.new("/" => lambda { |env|
150
- [200,
151
- { "Content-Type" => "text/plain",
152
- "X-Position" => "root",
153
- "X-PathInfo" => env["PATH_INFO"],
154
- "X-ScriptName" => env["SCRIPT_NAME"]
155
- }, [""]]},
156
- "/foo" => lambda { |env|
157
- [200,
158
- { "Content-Type" => "text/plain",
159
- "X-Position" => "foo",
160
- "X-PathInfo" => env["PATH_INFO"],
161
- "X-ScriptName" => env["SCRIPT_NAME"]
162
- }, [""]]}
163
- ))
164
-
165
- res = Rack::MockRequest.new(map).get("/foo/bar")
166
- res.should.be.ok
167
- res["X-Position"].should.equal "foo"
168
- res["X-PathInfo"].should.equal "/bar"
169
- res["X-ScriptName"].should.equal "/foo"
170
-
171
- res = Rack::MockRequest.new(map).get("/foo")
172
- res.should.be.ok
173
- res["X-Position"].should.equal "foo"
174
- res["X-PathInfo"].should.equal ""
175
- res["X-ScriptName"].should.equal "/foo"
176
-
177
- res = Rack::MockRequest.new(map).get("/bar")
178
- res.should.be.ok
179
- res["X-Position"].should.equal "root"
180
- res["X-PathInfo"].should.equal "/bar"
181
- res["X-ScriptName"].should.equal ""
182
-
183
- res = Rack::MockRequest.new(map).get("")
184
- res.should.be.ok
185
- res["X-Position"].should.equal "root"
186
- res["X-PathInfo"].should.equal "/"
187
- res["X-ScriptName"].should.equal ""
188
- end
189
-
190
- should "not squeeze slashes" do
191
- map = Rack::Lint.new(Rack::URLMap.new("/" => lambda { |env|
192
- [200,
193
- { "Content-Type" => "text/plain",
194
- "X-Position" => "root",
195
- "X-PathInfo" => env["PATH_INFO"],
196
- "X-ScriptName" => env["SCRIPT_NAME"]
197
- }, [""]]},
198
- "/foo" => lambda { |env|
199
- [200,
200
- { "Content-Type" => "text/plain",
201
- "X-Position" => "foo",
202
- "X-PathInfo" => env["PATH_INFO"],
203
- "X-ScriptName" => env["SCRIPT_NAME"]
204
- }, [""]]}
205
- ))
206
-
207
- res = Rack::MockRequest.new(map).get("/http://example.org/bar")
208
- res.should.be.ok
209
- res["X-Position"].should.equal "root"
210
- res["X-PathInfo"].should.equal "/http://example.org/bar"
211
- res["X-ScriptName"].should.equal ""
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
236
- end