From 18413ed1bf08261acf6d40f8ba65a98ae586bb29 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Sun, 7 Oct 2012 13:02:05 +0200 Subject: [PATCH] Added HTTP override middleware to docs. This fixes #582 --- docs/patterns/index.rst | 1 + docs/patterns/methodoverrides.rst | 43 +++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 docs/patterns/methodoverrides.rst diff --git a/docs/patterns/index.rst b/docs/patterns/index.rst index 964b1e17..2b1eaa9a 100644 --- a/docs/patterns/index.rst +++ b/docs/patterns/index.rst @@ -37,3 +37,4 @@ Snippet Archives `_. favicon streaming deferredcallbacks + methodoverrides diff --git a/docs/patterns/methodoverrides.rst b/docs/patterns/methodoverrides.rst new file mode 100644 index 00000000..d5c187b6 --- /dev/null +++ b/docs/patterns/methodoverrides.rst @@ -0,0 +1,43 @@ +Adding HTTP Method Overrides +============================ + +Some HTTP proxies do not support arbitrary HTTP methods or newer HTTP +methods (such as PATCH). In that case it's possible to “proxy” HTTP +methods through another HTTP method in total violation of the protocol. + +The way this works is by letting the client do an HTTP POST request and +set the ``X-HTTP-Method-Override`` header and set the value to the +intended HTTP method (such as ``PATCH``). + +This can easily be accomplished with an HTTP middleware:: + + class HTTPMethodOverrideMiddleware(object): + allowed_methods = frozenset([ + 'GET', + 'HEAD', + 'POST', + 'DELETE', + 'PUT', + 'PATCH', + 'OPTIONS' + ]) + bodyless_methods = frozenset(['GET', 'HEAD', 'OPTIONS', 'DELETE']) + + def __init__(self, app): + self.app = app + + def __call__(self, environ, start_response): + method = environ.get('HTTP_X_HTTP_METHOD_OVERRIDE', '').upper() + if method in self.allowed_methods: + method = method.encode('ascii', 'replace') + environ['REQUEST_METHOD'] = method + if method in self.bodyless_methods: + environ['CONTENT_LENGTH'] = '0' + return self.app(environ, start_response) + +To use this with Flask this is all that is necessary:: + + from flask import Flask + + app = Flask(__name__) + app.wsgi_app = HTTPMethodOverrideMiddleware(app.wsgi_app)