rack 1.6.11 → 2.1.4

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 (187) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +77 -0
  3. data/{COPYING → MIT-LICENSE} +4 -2
  4. data/README.rdoc +89 -139
  5. data/Rakefile +27 -28
  6. data/SPEC +6 -7
  7. data/bin/rackup +1 -0
  8. data/contrib/rack_logo.svg +164 -111
  9. data/example/lobster.ru +2 -0
  10. data/example/protectedlobster.rb +4 -2
  11. data/example/protectedlobster.ru +3 -1
  12. data/lib/rack/auth/abstract/handler.rb +3 -1
  13. data/lib/rack/auth/abstract/request.rb +7 -1
  14. data/lib/rack/auth/basic.rb +4 -1
  15. data/lib/rack/auth/digest/md5.rb +9 -7
  16. data/lib/rack/auth/digest/nonce.rb +6 -3
  17. data/lib/rack/auth/digest/params.rb +5 -4
  18. data/lib/rack/auth/digest/request.rb +3 -1
  19. data/lib/rack/body_proxy.rb +11 -9
  20. data/lib/rack/builder.rb +42 -18
  21. data/lib/rack/cascade.rb +6 -5
  22. data/lib/rack/chunked.rb +33 -10
  23. data/lib/rack/{commonlogger.rb → common_logger.rb} +11 -10
  24. data/lib/rack/{conditionalget.rb → conditional_get.rb} +3 -1
  25. data/lib/rack/config.rb +2 -0
  26. data/lib/rack/content_length.rb +5 -3
  27. data/lib/rack/content_type.rb +3 -1
  28. data/lib/rack/core_ext/regexp.rb +14 -0
  29. data/lib/rack/deflater.rb +33 -53
  30. data/lib/rack/directory.rb +75 -60
  31. data/lib/rack/etag.rb +8 -5
  32. data/lib/rack/events.rb +156 -0
  33. data/lib/rack/file.rb +4 -149
  34. data/lib/rack/files.rb +178 -0
  35. data/lib/rack/handler/cgi.rb +18 -17
  36. data/lib/rack/handler/fastcgi.rb +17 -16
  37. data/lib/rack/handler/lsws.rb +14 -12
  38. data/lib/rack/handler/scgi.rb +22 -19
  39. data/lib/rack/handler/thin.rb +6 -1
  40. data/lib/rack/handler/webrick.rb +28 -28
  41. data/lib/rack/handler.rb +9 -26
  42. data/lib/rack/head.rb +17 -17
  43. data/lib/rack/lint.rb +54 -51
  44. data/lib/rack/lobster.rb +8 -6
  45. data/lib/rack/lock.rb +17 -10
  46. data/lib/rack/logger.rb +4 -2
  47. data/lib/rack/media_type.rb +43 -0
  48. data/lib/rack/{methodoverride.rb → method_override.rb} +10 -8
  49. data/lib/rack/mime.rb +27 -6
  50. data/lib/rack/mock.rb +101 -60
  51. data/lib/rack/multipart/generator.rb +11 -12
  52. data/lib/rack/multipart/parser.rb +280 -161
  53. data/lib/rack/multipart/uploaded_file.rb +3 -2
  54. data/lib/rack/multipart.rb +39 -8
  55. data/lib/rack/{nulllogger.rb → null_logger.rb} +3 -1
  56. data/lib/rack/query_parser.rb +218 -0
  57. data/lib/rack/recursive.rb +11 -9
  58. data/lib/rack/reloader.rb +10 -4
  59. data/lib/rack/request.rb +447 -305
  60. data/lib/rack/response.rb +196 -83
  61. data/lib/rack/rewindable_input.rb +5 -14
  62. data/lib/rack/runtime.rb +12 -18
  63. data/lib/rack/sendfile.rb +19 -14
  64. data/lib/rack/server.rb +118 -41
  65. data/lib/rack/session/abstract/id.rb +215 -94
  66. data/lib/rack/session/cookie.rb +45 -28
  67. data/lib/rack/session/memcache.rb +4 -87
  68. data/lib/rack/session/pool.rb +25 -16
  69. data/lib/rack/show_exceptions.rb +392 -0
  70. data/lib/rack/{showstatus.rb → show_status.rb} +7 -5
  71. data/lib/rack/static.rb +41 -11
  72. data/lib/rack/tempfile_reaper.rb +4 -2
  73. data/lib/rack/urlmap.rb +25 -15
  74. data/lib/rack/utils.rb +186 -272
  75. data/lib/rack.rb +76 -24
  76. data/rack.gemspec +25 -14
  77. metadata +62 -182
  78. data/HISTORY.md +0 -375
  79. data/KNOWN-ISSUES +0 -44
  80. data/lib/rack/backports/uri/common_18.rb +0 -56
  81. data/lib/rack/backports/uri/common_192.rb +0 -52
  82. data/lib/rack/backports/uri/common_193.rb +0 -29
  83. data/lib/rack/handler/evented_mongrel.rb +0 -8
  84. data/lib/rack/handler/mongrel.rb +0 -106
  85. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  86. data/lib/rack/showexceptions.rb +0 -387
  87. data/lib/rack/utils/okjson.rb +0 -600
  88. data/test/builder/anything.rb +0 -5
  89. data/test/builder/comment.ru +0 -4
  90. data/test/builder/end.ru +0 -5
  91. data/test/builder/line.ru +0 -1
  92. data/test/builder/options.ru +0 -2
  93. data/test/cgi/assets/folder/test.js +0 -1
  94. data/test/cgi/assets/fonts/font.eot +0 -1
  95. data/test/cgi/assets/images/image.png +0 -1
  96. data/test/cgi/assets/index.html +0 -1
  97. data/test/cgi/assets/javascripts/app.js +0 -1
  98. data/test/cgi/assets/stylesheets/app.css +0 -1
  99. data/test/cgi/lighttpd.conf +0 -26
  100. data/test/cgi/rackup_stub.rb +0 -6
  101. data/test/cgi/sample_rackup.ru +0 -5
  102. data/test/cgi/test +0 -9
  103. data/test/cgi/test+directory/test+file +0 -1
  104. data/test/cgi/test.fcgi +0 -8
  105. data/test/cgi/test.ru +0 -5
  106. data/test/gemloader.rb +0 -10
  107. data/test/multipart/bad_robots +0 -259
  108. data/test/multipart/binary +0 -0
  109. data/test/multipart/content_type_and_no_filename +0 -6
  110. data/test/multipart/empty +0 -10
  111. data/test/multipart/fail_16384_nofile +0 -814
  112. data/test/multipart/file1.txt +0 -1
  113. data/test/multipart/filename_and_modification_param +0 -7
  114. data/test/multipart/filename_and_no_name +0 -6
  115. data/test/multipart/filename_with_escaped_quotes +0 -6
  116. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  117. data/test/multipart/filename_with_null_byte +0 -7
  118. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  119. data/test/multipart/filename_with_unescaped_percentages +0 -6
  120. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  121. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  122. data/test/multipart/filename_with_unescaped_quotes +0 -6
  123. data/test/multipart/ie +0 -6
  124. data/test/multipart/invalid_character +0 -6
  125. data/test/multipart/mixed_files +0 -21
  126. data/test/multipart/nested +0 -10
  127. data/test/multipart/none +0 -9
  128. data/test/multipart/semicolon +0 -6
  129. data/test/multipart/text +0 -15
  130. data/test/multipart/three_files_three_fields +0 -31
  131. data/test/multipart/webkit +0 -32
  132. data/test/rackup/config.ru +0 -31
  133. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  134. data/test/spec_auth_basic.rb +0 -81
  135. data/test/spec_auth_digest.rb +0 -259
  136. data/test/spec_body_proxy.rb +0 -85
  137. data/test/spec_builder.rb +0 -223
  138. data/test/spec_cascade.rb +0 -61
  139. data/test/spec_cgi.rb +0 -102
  140. data/test/spec_chunked.rb +0 -101
  141. data/test/spec_commonlogger.rb +0 -93
  142. data/test/spec_conditionalget.rb +0 -102
  143. data/test/spec_config.rb +0 -22
  144. data/test/spec_content_length.rb +0 -85
  145. data/test/spec_content_type.rb +0 -45
  146. data/test/spec_deflater.rb +0 -339
  147. data/test/spec_directory.rb +0 -88
  148. data/test/spec_etag.rb +0 -107
  149. data/test/spec_fastcgi.rb +0 -107
  150. data/test/spec_file.rb +0 -221
  151. data/test/spec_handler.rb +0 -72
  152. data/test/spec_head.rb +0 -45
  153. data/test/spec_lint.rb +0 -550
  154. data/test/spec_lobster.rb +0 -58
  155. data/test/spec_lock.rb +0 -164
  156. data/test/spec_logger.rb +0 -23
  157. data/test/spec_methodoverride.rb +0 -111
  158. data/test/spec_mime.rb +0 -51
  159. data/test/spec_mock.rb +0 -297
  160. data/test/spec_mongrel.rb +0 -182
  161. data/test/spec_multipart.rb +0 -600
  162. data/test/spec_nulllogger.rb +0 -20
  163. data/test/spec_recursive.rb +0 -72
  164. data/test/spec_request.rb +0 -1232
  165. data/test/spec_response.rb +0 -407
  166. data/test/spec_rewindable_input.rb +0 -118
  167. data/test/spec_runtime.rb +0 -49
  168. data/test/spec_sendfile.rb +0 -130
  169. data/test/spec_server.rb +0 -167
  170. data/test/spec_session_abstract_id.rb +0 -53
  171. data/test/spec_session_cookie.rb +0 -410
  172. data/test/spec_session_memcache.rb +0 -321
  173. data/test/spec_session_pool.rb +0 -209
  174. data/test/spec_showexceptions.rb +0 -98
  175. data/test/spec_showstatus.rb +0 -103
  176. data/test/spec_static.rb +0 -145
  177. data/test/spec_tempfile_reaper.rb +0 -63
  178. data/test/spec_thin.rb +0 -91
  179. data/test/spec_urlmap.rb +0 -236
  180. data/test/spec_utils.rb +0 -647
  181. data/test/spec_version.rb +0 -17
  182. data/test/spec_webrick.rb +0 -184
  183. data/test/static/another/index.html +0 -1
  184. data/test/static/index.html +0 -1
  185. data/test/testrequest.rb +0 -78
  186. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  187. 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