Как я могу переопределить методы HTTP для PUT и DELETE в модуле Flask?

Мне трудно попытаться изменить объект запроса Flask до того, как произойдет маршрутизация.

Мой модуль API (а не все мое приложение Flask) зависит от подделки операций PUT и DELETE путем отправки специального заголовка. Мне нужно проверить содержимое заголовка «-Method» и соответствующим образом изменить объект запроса Flask, прежде чем Flask выполнит маршрутизацию.

Это короткий, pythonic, явный код, с которым я хотел бы работать:

@api.before_request
def method_scrubbing():
    if request.headers.has_key('-Method'):
        method = request.headers['-Method'].upper()
        tagalog.log("in before_request, -Method = {}".format(method), 'force')
        if method not in ['PUT', 'DELETE']:
            raise ApiMethodException(method)
        else:
            request.method = method

... но я получаю сообщение об ошибке "свойство только для чтения" от werkzeug: http://drktd.com/74yk

Я видел пост Армина на http://flask.pocoo.org/snippets/38/ но это, кажется, для всего приложения (не для модуля).


person Kyle Wild    schedule 26.05.2011    source источник


Ответы (1)


Werkzeug предполагает, что запрос модифицируется только в промежуточном программном обеспечении WSGI или до того, как Werkzeug получит доступ к данным. Причина в том, что таким образом Werkzeug не должен отслеживать среду WSGI, чтобы увидеть, не придется ли аннулировать кэши или изменить поведение.

Однако в этом конкретном случае вы можете добиться успеха, если тщательно измените базовую среду WSGI:

request.environ['REQUEST_METHOD'] = 'something'

После этого request.method должно показать "что-то" и поведение должно измениться на синтаксический анализ формы. Я не пробовал это и не знаю, будет ли это работать. Лично я бы написал промежуточное программное обеспечение, которое переписывает все приложение или, возможно, выполняет какое-то простое сопоставление префикса URL для такого поведения.

person Armin Ronacher    schedule 26.05.2011
comment
Не совсем работает. Если я сделаю это, как вы сказали, и установлю request.environ['REQUEST_METHOD'] на 'PUT', request.method действительно сразу после этого покажет значение как 'PUT'. Тем не менее, запрос по-прежнему перенаправляется туда, куда он все равно пошел бы (в данном случае, на маршрут, украшенный @api.route('/isoSpace/<player_id>/tile/<tile_id>', methods=['POST'])). Внутри этой функции request.method снова выглядит как 'POST'. - person Kyle Wild; 27.05.2011
comment
Есть ли способ сделать промежуточное ПО применимым только к одному модулю? - person Kyle Wild; 27.05.2011
comment
Нет, так как промежуточное ПО работает на уровне WSGI. Однако вы можете позволить промежуточному программному обеспечению выполнять некоторые базовые проверки пути. - person Armin Ronacher; 27.05.2011