| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 | 
							- require 'rack/file'
 
- require 'rack/mock'
 
- describe Rack::File do
 
-   DOCROOT = File.expand_path(File.dirname(__FILE__)) unless defined? DOCROOT
 
-   should "serve files" do
 
-     res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
 
-       get("/cgi/test")
 
-     res.should.be.ok
 
-     res.should =~ /ruby/
 
-   end
 
-   should "set Last-Modified header" do
 
-     res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
 
-       get("/cgi/test")
 
-     path = File.join(DOCROOT, "/cgi/test")
 
-     res.should.be.ok
 
-     res["Last-Modified"].should.equal File.mtime(path).httpdate
 
-   end
 
-   should "return 304 if file isn't modified since last serve" do
 
-     path = File.join(DOCROOT, "/cgi/test")
 
-     res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
 
-       get("/cgi/test", 'HTTP_IF_MODIFIED_SINCE' => File.mtime(path).httpdate)
 
-     res.status.should.equal 304
 
-     res.body.should.be.empty
 
-   end
 
-   should "return the file if it's modified since last serve" do
 
-     path = File.join(DOCROOT, "/cgi/test")
 
-     res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
 
-       get("/cgi/test", 'HTTP_IF_MODIFIED_SINCE' => (File.mtime(path) - 100).httpdate)
 
-     res.should.be.ok
 
-   end
 
-   should "serve files with URL encoded filenames" do
 
-     res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
 
-       get("/cgi/%74%65%73%74") # "/cgi/test"
 
-     res.should.be.ok
 
-     res.should =~ /ruby/
 
-   end
 
-   should "allow safe directory traversal" do
 
-     req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT)))
 
-     res = req.get('/cgi/../cgi/test')
 
-     res.should.be.successful
 
-     res = req.get('.')
 
-     res.should.be.not_found
 
-     res = req.get("test/..")
 
-     res.should.be.not_found
 
-   end
 
-   should "not allow unsafe directory traversal" do
 
-     req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT)))
 
-     res = req.get("/../README")
 
-     res.should.be.client_error
 
-     res = req.get("../test")
 
-     res.should.be.client_error
 
-     res = req.get("..")
 
-     res.should.be.client_error
 
-     res.should.be.not_found
 
-   end
 
-   should "allow files with .. in their name" do
 
-     req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT)))
 
-     res = req.get("/cgi/..test")
 
-     res.should.be.not_found
 
-     res = req.get("/cgi/test..")
 
-     res.should.be.not_found
 
-     res = req.get("/cgi../test..")
 
-     res.should.be.not_found
 
-   end
 
-   should "not allow unsafe directory traversal with encoded periods" do
 
-     res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
 
-       get("/%2E%2E/README")
 
-     res.should.be.client_error?
 
-     res.should.be.not_found
 
-   end
 
-   should "allow safe directory traversal with encoded periods" do
 
-     res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
 
-       get("/cgi/%2E%2E/cgi/test")
 
-     res.should.be.successful
 
-   end
 
-   should "404 if it can't find the file" do
 
-     res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
 
-       get("/cgi/blubb")
 
-     res.should.be.not_found
 
-   end
 
-   should "detect SystemCallErrors" do
 
-     res = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT))).
 
-       get("/cgi")
 
-     res.should.be.not_found
 
-   end
 
-   should "return bodies that respond to #to_path" do
 
-     env = Rack::MockRequest.env_for("/cgi/test")
 
-     status, _, body = Rack::File.new(DOCROOT).call(env)
 
-     path = File.join(DOCROOT, "/cgi/test")
 
-     status.should.equal 200
 
-     body.should.respond_to :to_path
 
-     body.to_path.should.equal path
 
-   end
 
-   should "return correct byte range in body" do
 
-     env = Rack::MockRequest.env_for("/cgi/test")
 
-     env["HTTP_RANGE"] = "bytes=22-33"
 
-     res = Rack::MockResponse.new(*Rack::File.new(DOCROOT).call(env))
 
-     res.status.should.equal 206
 
-     res["Content-Length"].should.equal "12"
 
-     res["Content-Range"].should.equal "bytes 22-33/193"
 
-     res.body.should.equal "-*- ruby -*-"
 
-   end
 
-   should "return error for unsatisfiable byte range" do
 
-     env = Rack::MockRequest.env_for("/cgi/test")
 
-     env["HTTP_RANGE"] = "bytes=1234-5678"
 
-     res = Rack::MockResponse.new(*Rack::File.new(DOCROOT).call(env))
 
-     res.status.should.equal 416
 
-     res["Content-Range"].should.equal "bytes */193"
 
-   end
 
-   should "support cache control options" do
 
-     env = Rack::MockRequest.env_for("/cgi/test")
 
-     status, heads, _ = Rack::File.new(DOCROOT, 'public, max-age=38').call(env)
 
-     status.should.equal 200
 
-     heads['Cache-Control'].should.equal 'public, max-age=38'
 
-   end
 
-   should "only support GET and HEAD requests" do
 
-     req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT)))
 
-     forbidden = %w[post put delete]
 
-     forbidden.each do |method|
 
-       res = req.send(method, "/cgi/test")
 
-       res.should.be.client_error
 
-       res.should.be.method_not_allowed
 
-     end
 
-     allowed = %w[get head]
 
-     allowed.each do |method|
 
-       res = req.send(method, "/cgi/test")
 
-       res.should.be.successful
 
-     end
 
-   end
 
-   should "set Content-Length correctly for HEAD requests" do
 
-     req = Rack::MockRequest.new(Rack::Lint.new(Rack::File.new(DOCROOT)))
 
-     res = req.head "/cgi/test"
 
-     res.should.be.successful
 
-     res['Content-Length'].should.equal "193"
 
-   end
 
- end
 
 
  |