rack 1.4.7 → 2.1.4

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 (183) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +77 -0
  3. data/{COPYING → MIT-LICENSE} +4 -2
  4. data/README.rdoc +122 -456
  5. data/Rakefile +32 -31
  6. data/SPEC +119 -29
  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 +7 -5
  13. data/lib/rack/auth/abstract/request.rb +8 -6
  14. data/lib/rack/auth/basic.rb +5 -2
  15. data/lib/rack/auth/digest/md5.rb +10 -8
  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 +4 -2
  19. data/lib/rack/body_proxy.rb +11 -9
  20. data/lib/rack/builder.rb +63 -20
  21. data/lib/rack/cascade.rb +10 -9
  22. data/lib/rack/chunked.rb +45 -11
  23. data/lib/rack/{commonlogger.rb → common_logger.rb} +24 -15
  24. data/lib/rack/{conditionalget.rb → conditional_get.rb} +20 -6
  25. data/lib/rack/config.rb +7 -0
  26. data/lib/rack/content_length.rb +12 -6
  27. data/lib/rack/content_type.rb +4 -2
  28. data/lib/rack/core_ext/regexp.rb +14 -0
  29. data/lib/rack/deflater.rb +73 -42
  30. data/lib/rack/directory.rb +77 -56
  31. data/lib/rack/etag.rb +25 -13
  32. data/lib/rack/events.rb +156 -0
  33. data/lib/rack/file.rb +4 -143
  34. data/lib/rack/files.rb +178 -0
  35. data/lib/rack/handler/cgi.rb +18 -17
  36. data/lib/rack/handler/fastcgi.rb +21 -17
  37. data/lib/rack/handler/lsws.rb +14 -12
  38. data/lib/rack/handler/scgi.rb +27 -21
  39. data/lib/rack/handler/thin.rb +19 -5
  40. data/lib/rack/handler/webrick.rb +66 -24
  41. data/lib/rack/handler.rb +29 -19
  42. data/lib/rack/head.rb +21 -14
  43. data/lib/rack/lint.rb +259 -65
  44. data/lib/rack/lobster.rb +17 -10
  45. data/lib/rack/lock.rb +19 -10
  46. data/lib/rack/logger.rb +4 -2
  47. data/lib/rack/media_type.rb +43 -0
  48. data/lib/rack/method_override.rb +52 -0
  49. data/lib/rack/mime.rb +43 -6
  50. data/lib/rack/mock.rb +109 -44
  51. data/lib/rack/multipart/generator.rb +11 -12
  52. data/lib/rack/multipart/parser.rb +302 -115
  53. data/lib/rack/multipart/uploaded_file.rb +4 -3
  54. data/lib/rack/multipart.rb +40 -9
  55. data/lib/rack/null_logger.rb +39 -0
  56. data/lib/rack/query_parser.rb +218 -0
  57. data/lib/rack/recursive.rb +14 -11
  58. data/lib/rack/reloader.rb +12 -5
  59. data/lib/rack/request.rb +484 -270
  60. data/lib/rack/response.rb +196 -77
  61. data/lib/rack/rewindable_input.rb +5 -14
  62. data/lib/rack/runtime.rb +13 -6
  63. data/lib/rack/sendfile.rb +44 -20
  64. data/lib/rack/server.rb +175 -61
  65. data/lib/rack/session/abstract/id.rb +276 -133
  66. data/lib/rack/session/cookie.rb +75 -40
  67. data/lib/rack/session/memcache.rb +4 -87
  68. data/lib/rack/session/pool.rb +24 -18
  69. data/lib/rack/show_exceptions.rb +392 -0
  70. data/lib/rack/{showstatus.rb → show_status.rb} +11 -9
  71. data/lib/rack/static.rb +65 -38
  72. data/lib/rack/tempfile_reaper.rb +24 -0
  73. data/lib/rack/urlmap.rb +40 -15
  74. data/lib/rack/utils.rb +316 -285
  75. data/lib/rack.rb +78 -23
  76. data/rack.gemspec +26 -19
  77. metadata +44 -209
  78. data/KNOWN-ISSUES +0 -30
  79. data/lib/rack/backports/uri/common_18.rb +0 -56
  80. data/lib/rack/backports/uri/common_192.rb +0 -52
  81. data/lib/rack/backports/uri/common_193.rb +0 -29
  82. data/lib/rack/handler/evented_mongrel.rb +0 -8
  83. data/lib/rack/handler/mongrel.rb +0 -100
  84. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  85. data/lib/rack/methodoverride.rb +0 -33
  86. data/lib/rack/nulllogger.rb +0 -18
  87. data/lib/rack/showexceptions.rb +0 -378
  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/lighttpd.errors +0 -1
  101. data/test/cgi/rackup_stub.rb +0 -6
  102. data/test/cgi/sample_rackup.ru +0 -5
  103. data/test/cgi/test +0 -9
  104. data/test/cgi/test+directory/test+file +0 -1
  105. data/test/cgi/test.fcgi +0 -8
  106. data/test/cgi/test.ru +0 -5
  107. data/test/gemloader.rb +0 -10
  108. data/test/multipart/bad_robots +0 -259
  109. data/test/multipart/binary +0 -0
  110. data/test/multipart/content_type_and_no_filename +0 -6
  111. data/test/multipart/empty +0 -10
  112. data/test/multipart/fail_16384_nofile +0 -814
  113. data/test/multipart/file1.txt +0 -1
  114. data/test/multipart/filename_and_modification_param +0 -7
  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_percent_escaped_quotes +0 -6
  118. data/test/multipart/filename_with_unescaped_percentages +0 -6
  119. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  120. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  121. data/test/multipart/filename_with_unescaped_quotes +0 -6
  122. data/test/multipart/ie +0 -6
  123. data/test/multipart/mixed_files +0 -21
  124. data/test/multipart/nested +0 -10
  125. data/test/multipart/none +0 -9
  126. data/test/multipart/semicolon +0 -6
  127. data/test/multipart/text +0 -15
  128. data/test/multipart/three_files_three_fields +0 -31
  129. data/test/multipart/webkit +0 -32
  130. data/test/rackup/config.ru +0 -31
  131. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  132. data/test/spec_auth.rb +0 -57
  133. data/test/spec_auth_basic.rb +0 -81
  134. data/test/spec_auth_digest.rb +0 -259
  135. data/test/spec_body_proxy.rb +0 -69
  136. data/test/spec_builder.rb +0 -207
  137. data/test/spec_cascade.rb +0 -61
  138. data/test/spec_cgi.rb +0 -102
  139. data/test/spec_chunked.rb +0 -87
  140. data/test/spec_commonlogger.rb +0 -57
  141. data/test/spec_conditionalget.rb +0 -102
  142. data/test/spec_config.rb +0 -22
  143. data/test/spec_content_length.rb +0 -86
  144. data/test/spec_content_type.rb +0 -45
  145. data/test/spec_deflater.rb +0 -187
  146. data/test/spec_directory.rb +0 -88
  147. data/test/spec_etag.rb +0 -98
  148. data/test/spec_fastcgi.rb +0 -107
  149. data/test/spec_file.rb +0 -200
  150. data/test/spec_handler.rb +0 -59
  151. data/test/spec_head.rb +0 -48
  152. data/test/spec_lint.rb +0 -515
  153. data/test/spec_lobster.rb +0 -58
  154. data/test/spec_lock.rb +0 -167
  155. data/test/spec_logger.rb +0 -23
  156. data/test/spec_methodoverride.rb +0 -72
  157. data/test/spec_mock.rb +0 -269
  158. data/test/spec_mongrel.rb +0 -182
  159. data/test/spec_multipart.rb +0 -479
  160. data/test/spec_nulllogger.rb +0 -23
  161. data/test/spec_recursive.rb +0 -72
  162. data/test/spec_request.rb +0 -955
  163. data/test/spec_response.rb +0 -313
  164. data/test/spec_rewindable_input.rb +0 -118
  165. data/test/spec_runtime.rb +0 -49
  166. data/test/spec_sendfile.rb +0 -90
  167. data/test/spec_server.rb +0 -121
  168. data/test/spec_session_abstract_id.rb +0 -43
  169. data/test/spec_session_cookie.rb +0 -361
  170. data/test/spec_session_memcache.rb +0 -321
  171. data/test/spec_session_pool.rb +0 -209
  172. data/test/spec_showexceptions.rb +0 -92
  173. data/test/spec_showstatus.rb +0 -84
  174. data/test/spec_static.rb +0 -145
  175. data/test/spec_thin.rb +0 -86
  176. data/test/spec_urlmap.rb +0 -213
  177. data/test/spec_utils.rb +0 -554
  178. data/test/spec_webrick.rb +0 -143
  179. data/test/static/another/index.html +0 -1
  180. data/test/static/index.html +0 -1
  181. data/test/testrequest.rb +0 -78
  182. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  183. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -1,84 +0,0 @@
1
- require 'rack/showstatus'
2
- require 'rack/lint'
3
- require 'rack/mock'
4
-
5
- describe Rack::ShowStatus do
6
- def show_status(app)
7
- Rack::Lint.new Rack::ShowStatus.new(app)
8
- end
9
-
10
- should "provide a default status message" do
11
- req = Rack::MockRequest.new(
12
- show_status(lambda{|env|
13
- [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
14
- }))
15
-
16
- res = req.get("/", :lint => true)
17
- res.should.be.not_found
18
- res.should.be.not.empty
19
-
20
- res["Content-Type"].should.equal("text/html")
21
- res.should =~ /404/
22
- res.should =~ /Not Found/
23
- end
24
-
25
- should "let the app provide additional information" do
26
- req = Rack::MockRequest.new(
27
- show_status(
28
- lambda{|env|
29
- env["rack.showstatus.detail"] = "gone too meta."
30
- [404, {"Content-Type" => "text/plain", "Content-Length" => "0"}, []]
31
- }))
32
-
33
- res = req.get("/", :lint => true)
34
- res.should.be.not_found
35
- res.should.be.not.empty
36
-
37
- res["Content-Type"].should.equal("text/html")
38
- res.should =~ /404/
39
- res.should =~ /Not Found/
40
- res.should =~ /too meta/
41
- end
42
-
43
- should "not replace existing messages" do
44
- req = Rack::MockRequest.new(
45
- show_status(
46
- lambda{|env|
47
- [404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]]
48
- }))
49
-
50
- res = req.get("/", :lint => true)
51
- res.should.be.not_found
52
-
53
- res.body.should == "foo!"
54
- end
55
-
56
- should "pass on original headers" do
57
- headers = {"WWW-Authenticate" => "Basic blah"}
58
-
59
- req = Rack::MockRequest.new(
60
- show_status(lambda{|env| [401, headers, []] }))
61
- res = req.get("/", :lint => true)
62
-
63
- res["WWW-Authenticate"].should.equal("Basic blah")
64
- end
65
-
66
- should "replace existing messages if there is detail" do
67
- req = Rack::MockRequest.new(
68
- show_status(
69
- lambda{|env|
70
- env["rack.showstatus.detail"] = "gone too meta."
71
- [404, {"Content-Type" => "text/plain", "Content-Length" => "4"}, ["foo!"]]
72
- }))
73
-
74
- res = req.get("/", :lint => true)
75
- res.should.be.not_found
76
- res.should.be.not.empty
77
-
78
- res["Content-Type"].should.equal("text/html")
79
- res["Content-Length"].should.not.equal("4")
80
- res.should =~ /404/
81
- res.should =~ /too meta/
82
- res.body.should.not =~ /foo/
83
- end
84
- 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
data/test/spec_thin.rb DELETED
@@ -1,86 +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) 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
- @server.stop!
81
- @thread.kill
82
- end
83
-
84
- rescue LoadError
85
- $stderr.puts "Skipping Rack::Handler::Thin tests (Thin is required). `gem install thin` and try again."
86
- end
data/test/spec_urlmap.rb DELETED
@@ -1,213 +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 "default.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
- end