public
Rubygem
Description: Merb Core: All you need. None you don't.
Homepage: http://www.merbivore.com
Clone URL: git://github.com/wycats/merb-core.git
Made HTTP method override proc-based and pluggable. [#364]

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]
mde (author)
Sun Jun 08 19:11:10 -0700 2008
ivey (committer)
Wed Jun 11 13:49:39 -0700 2008
commit  e7792452a120cdc582b7a1cd826e47eded459d3d
tree    a9572674bfc2546ce843a719f184432258de91ee
parent  75f71027c5f023eebb91023845f06262cb16a880
...
165
166
167
168
 
 
 
 
 
169
170
171
...
165
166
167
 
168
169
170
171
172
173
174
175
0
@@ -165,7 +165,11 @@ end
0
 # Setup some useful defaults
0
 class Merb::BootLoader::Defaults < Merb::BootLoader
0
   def self.run
0
-    Merb::Request.browser_method_workarounds << "_method"
0
+    Merb::Request.http_method_overrides.concat([
0
+      proc { |c| c.params[:_method] },
0
+      proc { |c| c.params[:fb_sig_request_method] },
0
+      proc { |c| c.env['HTTP_X_HTTP_METHOD_OVERRIDE'] }
0
+    ])
0
   end
0
 end
0
 
...
14
15
16
17
18
19
20
21
22
 
 
 
 
 
 
 
 
23
24
25
...
38
39
40
41
42
43
 
 
 
 
44
45
46
...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 
 
62
63
64
...
14
15
16
 
 
 
 
 
 
17
18
19
20
21
22
23
24
25
26
27
...
40
41
42
 
 
 
43
44
45
46
47
48
49
...
51
52
53
 
 
 
 
 
54
 
 
 
 
 
55
56
57
58
59
0
@@ -14,12 +14,14 @@ module Merb
0
     self.parse_json_params = true
0
     self.parse_xml_params = true
0
     
0
-    # Most web browsers can't send PUT or DELETE requests
0
-    # Any Strings stored in this array will be used as paramaters
0
-    # to find the real method.  Common examples are _method and
0
-    # fb_sig_request_method 
0
-    cattr_accessor :browser_method_workarounds
0
-    self.browser_method_workarounds = []
0
+    # Flash, and some older browsers can't use arbitrary
0
+    # request methods -- i.e., are limited to GET/POST.
0
+    # These user-agents can make POST requests in combination
0
+    # with these overrides to participate fully in REST
0
+    # Common examples are _method or fb_sig_request_method
0
+    # in the params, or an X-HTTP-Method-Override header
0
+    cattr_accessor :http_method_overrides
0
+    self.http_method_overrides = []
0
     
0
     # Initial the request object.
0
     #
0
@@ -38,9 +40,10 @@ module Merb
0
     # Symbol:: The name of the request method, e.g. :get.
0
     #
0
     # ==== Notes
0
-    # If the method is post, then the params specified in
0
-    # browser_method_workarounds will be checked for the masquerading method.
0
-    # The first matching workaround wins.
0
+    # If the method is post, then the blocks specified in
0
+    # http_method_overrides will be checked for the masquerading method.
0
+    # The block will get the controller yielded to it.  The first matching workaround wins.
0
+    # To disable this behavior, set http_method_overrides = []
0
     def method
0
       @method ||= begin
0
         request_method = @env['REQUEST_METHOD'].downcase.to_sym
0
@@ -48,17 +51,9 @@ module Merb
0
         when :get, :head, :put, :delete
0
           request_method
0
         when :post
0
-          if self.class.parse_multipart_params
0
-            p = body_and_query_params.merge(multipart_params)
0
-          else  
0
-            p = body_and_query_params
0
-          end
0
           m = nil
0
-          self.class.browser_method_workarounds.each do |workaround|
0
-            if p.include?(workaround.to_s)
0
-              m = p[workaround.to_s]
0
-              break
0
-            end
0
+          self.class.http_method_overrides.each do |o|
0
+            m ||= o.call(self); break if m
0
           end
0
           m.downcase! if m
0
           METHODS.include?(m) ? m.to_sym : :post

Comments