Class: Rackful::MethodSpoofing

Inherits:
Object
  • Object
show all
Defined in:
gems/rackful-0.1.1/lib/rackful/method_spoofing.rb,
gems/rackful-0.1.1.orig/lib/rackful/method_spoofing.rb

Overview

Rack middleware that provides method spoofing.

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=...

Examples:

Using this middleware

use Rackful::MethodSpoofing

Since:

Instance Method Summary (collapse)

Constructor Details

- (MethodSpoofing) initialize(app)

A new instance of MethodSpoofing

Since:

  • 0.0.1



42
43
44
# File 'gems/rackful-0.1.1/lib/rackful/method_spoofing.rb', line 42

def initialize app
  @app = app
end

Instance Method Details

- (void) after_call(env)

Since:

  • 0.0.1



95
96
97
98
99
100
# File 'gems/rackful-0.1.1/lib/rackful/method_spoofing.rb', line 95

def after_call env
  if env.key? 'rackful.method_spoofing.input'
    env['rack.input'] = env['rackful.method_spoofing.input']
    env.delete 'rackful.method_spoofing.input'
  end
end

- (void) before_call(env)

Since:

  • 0.0.1



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'gems/rackful-0.1.1/lib/rackful/method_spoofing.rb', line 53

def before_call env
  return unless ['GET', 'POST'].include? env['REQUEST_METHOD']
  original_query_string = env['QUERY_STRING']
  new_method = nil
  env['QUERY_STRING'] = original_query_string.
    split('&', -1).
    collect { |s| s.split('=', -1) }.
    select {
      |p|
      if  /_method/i   === p[0] &&
          /\A[A-Z]+\z/ === ( method = p[1..-1].join('=').upcase ) &&
          ! new_method
        new_method = method
        false
      else
        true
      end
    }.
    collect { |p| p.join('=') }.
    join('&')
  if new_method
    if  'GET' == new_method &&
        'POST' == env['REQUEST_METHOD'] &&
        'application/x-www-form-urlencoded' == env['CONTENT_TYPE']
      unless env['QUERY_STRING'].empty
        env['QUERY_STRING'] = env['QUERY_STRING'] + '&'
      end
      begin
        env['QUERY_STRING'] = env['QUERY_STRING'] + env['rack.input'].read
        env['rack.input'].rewind
      end
      env['rackful.method_spoofing.input'] = env['rack.input']
      env.delete 'rack.input'
      env.delete 'CONTENT_TYPE'
      env.delete 'CONTENT_LENGTH' if env.key? 'CONTENT_LENGTH'
    end
    env['rackful.method_spoofing.QUERY_STRING'] ||= original_query_string
    env['rackful.method_spoofing.REQUEST_METHOD'] = env['REQUEST_METHOD']
    env['REQUEST_METHOD'] = new_method
  end
end

- (void) call(env)

Since:

  • 0.0.1



46
47
48
49
50
51
# File 'gems/rackful-0.1.1/lib/rackful/method_spoofing.rb', line 46

def call env
  before_call env
  r = @app.call env
  after_call env
  r
end