Merge pull request #3068 from pallets/method-override-encoding

remove encoding from method override pattern
This commit is contained in:
David Lord 2019-01-07 13:20:00 -08:00 committed by GitHub
commit d7a1b0157a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2,14 +2,14 @@ Adding HTTP Method Overrides
============================ ============================
Some HTTP proxies do not support arbitrary HTTP methods or newer HTTP 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 (such as PATCH). In that case it's possible to "proxy" HTTP
methods through another HTTP method in total violation of the protocol. 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 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 set the ``X-HTTP-Method-Override`` header. Then the method is replaced
intended HTTP method (such as ``PATCH``). with the header value before being passed to Flask.
This can easily be accomplished with an HTTP middleware:: This can be accomplished with an HTTP middleware::
class HTTPMethodOverrideMiddleware(object): class HTTPMethodOverrideMiddleware(object):
allowed_methods = frozenset([ allowed_methods = frozenset([
@ -29,13 +29,12 @@ This can easily be accomplished with an HTTP middleware::
def __call__(self, environ, start_response): def __call__(self, environ, start_response):
method = environ.get('HTTP_X_HTTP_METHOD_OVERRIDE', '').upper() method = environ.get('HTTP_X_HTTP_METHOD_OVERRIDE', '').upper()
if method in self.allowed_methods: if method in self.allowed_methods:
method = method.encode('ascii', 'replace')
environ['REQUEST_METHOD'] = method environ['REQUEST_METHOD'] = method
if method in self.bodyless_methods: if method in self.bodyless_methods:
environ['CONTENT_LENGTH'] = '0' environ['CONTENT_LENGTH'] = '0'
return self.app(environ, start_response) return self.app(environ, start_response)
To use this with Flask this is all that is necessary:: To use this with Flask, wrap the app object with the middleware::
from flask import Flask from flask import Flask