HttpMethodsMiddleware

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import re
import itertools

_HTML_TYPES = ('text/html', 'application/xhtml+xml')    

_SUPPORTED_TRANSFORMS = ['PUT', 'DELETE']

_FORM_RE = re.compile(r'((<form\W[^>]*\bmethod=(\'|"|))(%s)((\'|"|)\b[^>]*>))' % '|'.join(_SUPPORTED_TRANSFORMS), re.IGNORECASE)

_MIDDLEWARE_KEY = 'method_middleware_transform'
 
class HttpMethodsMiddleware(object):
    def process_request(self, request):
        if request.POST and request.POST.has_key(_MIDDLEWARE_KEY):
            if request.POST[_MIDDLEWARE_KEY].upper() in _SUPPORTED_TRANSFORMS:
                request.method = request.POST[_MIDDLEWARE_KEY]
        return None
           
    def process_response(self, request, response):
        if response['Content-Type'].split(';')[0] in _HTML_TYPES:
            # ensure we don't add the 'id' attribute twice (HTML validity)
            idattributes = itertools.chain(("id='" + _MIDDLEWARE_KEY + "'",), 
                                            itertools.repeat(''))
            def add_transform_field(match):
                """Returns the matched <form> tag with a modified method and
                the added <input> element"""
                return match.group(2) + "POST" + match.group(5) + \
                "<div style='display:none;'>" + \
                "<input type='hidden' " + idattributes.next() + \
                " name='" + _MIDDLEWARE_KEY + "' value='" + \
                match.group(4).upper() + "' /></div>"

            # Modify any POST forms
            response.content = _FORM_RE.sub(add_transform_field, response.content)
        return response

More like this

  1. Using class methods as views by panyam 2 years, 11 months ago
  2. RestfulView by whiteinge 4 years, 7 months ago
  3. caching parsed templates by forgems 4 years, 5 months ago
  4. RestView - class for creating a view that dispatches based on request.method by simon 3 years, 8 months ago
  5. Format transition middleware by limodou 5 years, 2 months ago

Comments

peplin (on April 20, 2011):

Be aware that this snippet as is can expose your application to CSRF attacks. Django's CSRF checks will always occur after this middleware is run, and it currently only checks POST requests.

I've made some updates for our version of this snippet here (with more comments): https://github.com/bueda/django-comrade/commit/de4d38b0c503908f11d5d73a60e3beef4735997c

#

(Forgotten your password?)