HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall_forms/buyercall/buyercall/lib/http_method_override_middleware.py
from werkzeug.urls import url_decode


class HTTPMethodOverrideMiddleware(object):
    """
    Allow us to route requests with modern HTTP verbs because browsers only
    currently support GET and POST. This is useful if you want to create a
    proper restful API.

    Source: http://flask.pocoo.org/docs/1.1.x/patterns/methodoverrides/

    Modified to also accept a query string __method__ as a source of truth:
      <form action="?__method__=DELETE">
    """
    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 = self._detect_method(
            environ.get('QUERY_STRING', ''),
            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'
        print(environ, start_response)
        return self.app(environ, start_response)

    def _detect_method(self, query_string, method_override):
        """
        Determine the true method by investigating both the query string
        and the http method override header.

        :param query_string: Query string
        :type query_string: str
        :param method_override: Method override header
        :type method_override: str
        :return: str
        """
        if '__method__' in query_string:
            args = url_decode(query_string)
            method = args.get('__method__').upper()
        else:
            method = method_override.upper()

        return method