Skip to content

Commit

Permalink
Add additional HTTP request methods from the following RFCs:
Browse files Browse the repository at this point in the history
* Hypertext Transfer Protocol -- HTTP/1.1
  http://www.ietf.org/rfc/rfc2616.txt)

* HTTP Extensions for Distributed Authoring -- WEBDAV
  http://www.ietf.org/rfc/rfc2518.txt

* Versioning Extensions to WebDAV
  http://www.ietf.org/rfc/rfc3253.txt

* Ordered Collections Protocol (WebDAV)
  http://www.ietf.org/rfc/rfc3648.txt

* Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol
  http://www.ietf.org/rfc/rfc3744.txt

* Web Distributed Authoring and Versioning (WebDAV) SEARCH
  http://www.ietf.org/rfc/rfc5323.txt

* PATCH Method for HTTP
  http://www.ietf.org/rfc/rfc5789.txt

[#2809 state:resolved] [#5895 state:resolved]
  • Loading branch information
pixeltrix committed Nov 2, 2010
1 parent 18b6aa6 commit d446392
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
21 changes: 19 additions & 2 deletions actionpack/lib/action_dispatch/http/request.rb
Expand Up @@ -4,6 +4,7 @@

require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/string/access'
require 'active_support/inflector'
require 'action_dispatch/http/headers'

module ActionDispatch
Expand Down Expand Up @@ -44,8 +45,24 @@ def key?(key)
@env.key?(key)
end

HTTP_METHODS = %w(get head put post delete options)
HTTP_METHOD_LOOKUP = HTTP_METHODS.inject({}) { |h, m| h[m] = h[m.upcase] = m.to_sym; h }
# List of HTTP request methods from the following RFCs:
# Hypertext Transfer Protocol -- HTTP/1.1 (http://www.ietf.org/rfc/rfc2616.txt)
# HTTP Extensions for Distributed Authoring -- WEBDAV (http://www.ietf.org/rfc/rfc2518.txt)
# Versioning Extensions to WebDAV (http://www.ietf.org/rfc/rfc3253.txt)
# Ordered Collections Protocol (WebDAV) (http://www.ietf.org/rfc/rfc3648.txt)
# Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol (http://www.ietf.org/rfc/rfc3744.txt)
# Web Distributed Authoring and Versioning (WebDAV) SEARCH (http://www.ietf.org/rfc/rfc5323.txt)
# PATCH Method for HTTP (http://www.ietf.org/rfc/rfc5789.txt)
RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
RFC3253 = %w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY)
RFC3648 = %w(ORDERPATCH)
RFC3744 = %w(ACL)
RFC5323 = %w(SEARCH)
RFC5789 = %w(PATCH)

HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789
HTTP_METHOD_LOOKUP = Hash.new { |h, m| h[m] = m.underscore.to_sym if HTTP_METHODS.include?(m) }

# Returns the HTTP \method that the application should see.
# In the case where the \method was overridden by a middleware
Expand Down
5 changes: 3 additions & 2 deletions actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1,6 +1,7 @@
require 'erb'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/object/blank'
require 'active_support/inflector'

module ActionDispatch
module Routing
Expand Down Expand Up @@ -186,8 +187,8 @@ def constraints

def request_method_condition
if via = @options[:via]
via = Array(via).map { |m| m.to_s.upcase }
{ :request_method => Regexp.union(*via) }
via = Array(via).map { |m| m.to_s.dasherize.upcase }
{ :request_method => %r[^#{via.join('|')}$] }
else
{ }
end
Expand Down
31 changes: 31 additions & 0 deletions actionpack/test/dispatch/routing_test.rb
Expand Up @@ -2255,3 +2255,34 @@ def test_default_scope
end
end

class TestHttpMethods < ActionDispatch::IntegrationTest
RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
RFC3253 = %w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY)
RFC3648 = %w(ORDERPATCH)
RFC3744 = %w(ACL)
RFC5323 = %w(SEARCH)
RFC5789 = %w(PATCH)

def simple_app(response)
lambda { |env| [ 200, { 'Content-Type' => 'text/plain' }, [response] ] }
end

setup do
s = self
@app = ActionDispatch::Routing::RouteSet.new

@app.draw do
(RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789).each do |method|
match '/' => s.simple_app(method), :via => method.underscore.to_sym
end
end
end

(RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789).each do |method|
test "request method #{method.underscore} can be matched" do
get '/', nil, 'REQUEST_METHOD' => method
assert_equal method, @response.body
end
end
end

7 comments on commit d446392

@dmathieu
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice.

@yob
Copy link

@yob yob commented on d446392 Nov 2, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, handy. Does this mean no more 500s when bots CONNECT to my site?

@pixeltrix
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't do for that particular reason but it should now give a routing error with a 404 status if you've specified a request method in your route.

@feldpost
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome. Any chance we could apply this to 2-3-stable?

@sikachu
Copy link
Member

@sikachu sikachu commented on d446392 Nov 2, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No support for RFC2324 – HTCPCP/1.0 ?

I'm a sad panda :(

@pixeltrix
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sikachu read the comments here on why that's probably a bad idea: http://github.com/rails/rails/commit/22af62cf486721ee2e45bb720c42ac2f4121faf4 :)

@sikachu
Copy link
Member

@sikachu sikachu commented on d446392 Nov 3, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pixeltrix oops ... yeah, adding that would definitely be a bad idea :D

Please sign in to comment.