Class: Rackful::MethodOverride

Inherits:
Object
  • Object
show all
Defined in:
lib/rackful/middleware/methodoverride.rb

Overview

Middleware that provides method spoofing, like Rack::MethodOverride.

If you use this middleware, then clients are allowed to spoof an HTTP method by specifying a _method=... request parameter, for example http://example.com/some_resource?_method=DELETE.

This can be useful if you want to perform PUT and DELETE requests from within a browser, of when you want to perform a GET requests with (too) many parameters, exceeding the maximum URI length in your client or server. In that case, you can put the parameters in a POST body, like this:

POST /some_resource HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 123456789

param_1=hello&param_2=world&param_3=...

Caveats:

  • this middleware won’t work well together with Digest Authentication.

  • When a POST request is converted to a GET request, the entire request body is loaded into memory, which creates an attack surface for DoS-attacks. Hence, the maximum request body size is limited (see POST_TO_GET_REQUEST_BODY_MAX_SIZE and #initialize). You should choose this limit carefully, and/or include this middleware after your security middlewares.

Improvements over Rack::MethodOverride (v1.5.2):

  • Rack::MethodOverride requires the original method to be POST. We allow the following overrides (ORIGINAL_METHODOVERRIDE_WITH):

    • GETDELETE, HEAD and OPTIONS

    • POSTGET, PATCH and PUT

  • Rack::MethodOverride doesn’t touch env['QUERY_STRING']. We remove parameter _method if it was handled (but still leave it there if it wasn’t handled for some reason).

  • Rackful::MethodOverride is documented ;-)

Examples:

Using this middleware

require 'rackful/middleware/method_override'
use Rackful::MethodOverride

Constant Summary

METHOD_OVERRIDE_PARAM_KEY =
'_method'.freeze
POST_TO_GET_REQUEST_BODY_MAX_SIZE =
1024 * 1024
ALLOWED_OVERRIDES =
{
  'GET'.freeze  => [ 'DELETE', 'HEAD',  'OPTIONS' ].to_set.freeze,
  'POST'.freeze => [ 'PATCH', 'PUT'     ].to_set.freeze
}.freeze

Instance Method Summary (collapse)

Constructor Details

- (MethodOverride) initialize(app, options = {})

Constructor.

Parameters:

  • app (#call)
  • options (Hash{Symbol => Mixed}) (defaults to: {})

    Configuration options. The following options are supported: * :max_size the maximum size (in bytes) of the request body of a POST request that is converted to a GET request.



67
68
69
70
# File 'lib/rackful/middleware/methodoverride.rb', line 67

def initialize( app, options = {} )
  @app = app
  @max_size = options[:max_size]
end

Instance Method Details

- (void) call(env)



73
74
75
76
# File 'lib/rackful/middleware/methodoverride.rb', line 73

def call env
  before_call env
  @app.call env
end