Skip to content

Commit

Permalink
Made HTTP method override proc-based and pluggable. [#364]
Browse files Browse the repository at this point in the history
Changed the check for specific params to procs that execute
in the request scope, allowing checks for method overrides to
be based on params, headers -- or pretty much anything in the
request. Also changed the name of the array that stores these
checks from browser_method_workarounds to the more accurate
and descriptive http_method_overrides.

Signed-off-by: Michael D. Ivey <ivey@gweezlebur.com>
 (I changed this to yield the controller to the block, instead of
  using instance_eval, as it seemed cleaner and was significantly
  faster.  See benchmark attachment on ticket #364 --ivey)

[#364 state:resolved]
  • Loading branch information
mde authored and ivey committed Jun 11, 2008
1 parent 75f7102 commit e779245
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 20 deletions.
6 changes: 5 additions & 1 deletion lib/merb-core/bootloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,11 @@ def run
# Setup some useful defaults
class Merb::BootLoader::Defaults < Merb::BootLoader
def self.run
Merb::Request.browser_method_workarounds << "_method"
Merb::Request.http_method_overrides.concat([
proc { |c| c.params[:_method] },
proc { |c| c.params[:fb_sig_request_method] },
proc { |c| c.env['HTTP_X_HTTP_METHOD_OVERRIDE'] }
])
end
end

Expand Down
33 changes: 14 additions & 19 deletions lib/merb-core/dispatch/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ class Request
self.parse_json_params = true
self.parse_xml_params = true

# Most web browsers can't send PUT or DELETE requests
# Any Strings stored in this array will be used as paramaters
# to find the real method. Common examples are _method and
# fb_sig_request_method
cattr_accessor :browser_method_workarounds
self.browser_method_workarounds = []
# Flash, and some older browsers can't use arbitrary
# request methods -- i.e., are limited to GET/POST.
# These user-agents can make POST requests in combination
# with these overrides to participate fully in REST
# Common examples are _method or fb_sig_request_method
# in the params, or an X-HTTP-Method-Override header
cattr_accessor :http_method_overrides
self.http_method_overrides = []

# Initial the request object.
#
Expand All @@ -38,27 +40,20 @@ def initialize(rack_env)
# Symbol:: The name of the request method, e.g. :get.
#
# ==== Notes
# If the method is post, then the params specified in
# browser_method_workarounds will be checked for the masquerading method.
# The first matching workaround wins.
# If the method is post, then the blocks specified in
# http_method_overrides will be checked for the masquerading method.
# The block will get the controller yielded to it. The first matching workaround wins.
# To disable this behavior, set http_method_overrides = []
def method
@method ||= begin
request_method = @env['REQUEST_METHOD'].downcase.to_sym
case request_method
when :get, :head, :put, :delete
request_method
when :post
if self.class.parse_multipart_params
p = body_and_query_params.merge(multipart_params)
else
p = body_and_query_params
end
m = nil
self.class.browser_method_workarounds.each do |workaround|
if p.include?(workaround.to_s)
m = p[workaround.to_s]
break
end
self.class.http_method_overrides.each do |o|
m ||= o.call(self); break if m
end
m.downcase! if m
METHODS.include?(m) ? m.to_sym : :post
Expand Down

0 comments on commit e779245

Please sign in to comment.