Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add OPTIONS support to File and MockRequest.

Also update the specs for same.

RFC 2616, section 9.2 specifies OPTIONS requests.  Not much effort to
support it for this case; there's already an ALLOWED_VERBS cosntant in
Rack::File, and the spec describes the body of the request as optional.
  • Loading branch information...
commit 3ea1174a4cbcde0def63b945b7efed2161c04850 1 parent 1f47a44
Pete pete authored
Showing with 26 additions and 13 deletions.
  1. +8 −4 lib/rack/file.rb
  2. +7 −6 lib/rack/mock.rb
  3. +11 −3 test/spec_file.rb
12 lib/rack/file.rb
View
@@ -13,7 +13,8 @@ module Rack
class File
SEPS = Regexp.union(*[::File::SEPARATOR, ::File::ALT_SEPARATOR].compact)
- ALLOWED_VERBS = %w[GET HEAD]
+ ALLOWED_VERBS = %w[GET HEAD OPTIONS]
+ ALLOW_HEADER = ALLOWED_VERBS.join(', ')
attr_accessor :root
attr_accessor :path
@@ -35,7 +36,7 @@ def call(env)
def _call(env)
unless ALLOWED_VERBS.include? env["REQUEST_METHOD"]
- return fail(405, "Method Not Allowed")
+ return fail(405, "Method Not Allowed", {'Allow' => ALLOW_HEADER})
end
path_info = Utils.unescape(env["PATH_INFO"])
@@ -64,6 +65,9 @@ def _call(env)
end
def serving(env)
+ if env["REQUEST_METHOD"] == "OPTIONS"
+ return [200, {'Allow' => ALLOW_HEADER, 'Content-Length' => 0}, []]
+ end
last_modified = F.mtime(@path).httpdate
return [304, {}, []] if env['HTTP_IF_MODIFIED_SINCE'] == last_modified
@@ -121,7 +125,7 @@ def each
private
- def fail(status, body)
+ def fail(status, body, headers = {})
body += "\n"
[
status,
@@ -129,7 +133,7 @@ def fail(status, body)
"Content-Type" => "text/plain",
"Content-Length" => body.size.to_s,
"X-Cascade" => "pass"
- },
+ }.merge!(headers),
[body]
]
end
13 lib/rack/mock.rb
View
@@ -53,12 +53,13 @@ def initialize(app)
@app = app
end
- def get(uri, opts={}) request("GET", uri, opts) end
- def post(uri, opts={}) request("POST", uri, opts) end
- def put(uri, opts={}) request("PUT", uri, opts) end
- def patch(uri, opts={}) request("PATCH", uri, opts) end
- def delete(uri, opts={}) request("DELETE", uri, opts) end
- def head(uri, opts={}) request("HEAD", uri, opts) end
+ def get(uri, opts={}) request("GET", uri, opts) end
+ def post(uri, opts={}) request("POST", uri, opts) end
+ def put(uri, opts={}) request("PUT", uri, opts) end
+ def patch(uri, opts={}) request("PATCH", uri, opts) end
+ def delete(uri, opts={}) request("DELETE", uri, opts) end
+ def head(uri, opts={}) request("HEAD", uri, opts) end
+ def options(uri, opts={}) request("OPTIONS", uri, opts) end
def request(method="GET", uri="", opts={})
env = self.class.env_for(uri, opts.merge(:method => method))
14 test/spec_file.rb
View
@@ -164,24 +164,32 @@ def file(*args)
heads['Access-Control-Allow-Origin'].should.equal nil
end
- should "only support GET and HEAD requests" do
+ should "only support GET, HEAD, and OPTIONS requests" do
req = Rack::MockRequest.new(file(DOCROOT))
forbidden = %w[post put patch delete]
forbidden.each do |method|
-
res = req.send(method, "/cgi/test")
res.should.be.client_error
res.should.be.method_not_allowed
+ res.headers['Allow'].split(/, */).sort.should == %w(GET HEAD OPTIONS)
end
- allowed = %w[get head]
+ allowed = %w[get head options]
allowed.each do |method|
res = req.send(method, "/cgi/test")
res.should.be.successful
end
end
+ should "set Allow correctly for OPTIONS requests" do
+ req = Rack::MockRequest.new(file(DOCROOT))
+ res = req.options('/cgi/test')
+ res.should.be.successful
+ res.headers['Allow'].should.not.equal nil
+ res.headers['Allow'].split(/, */).sort.should == %w(GET HEAD OPTIONS)
+ 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"
Please sign in to comment.
Something went wrong with that request. Please try again.