Spec-Zone.ru › Werkzeug 0.15

Работа с данными запроса

Самое важное правило разработки веб-приложений — «не доверяйте пользователю». Это особенно актуально для входящих данных запроса в потоке ввода. С WSGI это на самом деле немного сложнее, чем можно ожидать. Поэтому Werkzeug оборачивает поток запроса, чтобы избавить вас от самых распространённых проблем с ним.

Отсутствие маркера EOF в потоке ввода

Поток ввода не содержит маркера конца файла. Если вы вызовете метод read() в потоке wsgi.input, ваше приложение зависнет на серверах, которые соответствуют спецификации. На самом деле это сделано намеренно, хотя и неприятно. Werkzeug решает эту проблему, обернув поток ввода в специальный LimitedStream. Поток ввода доступен в объектах запроса как stream. Этот поток либо пустой (если данные формы были обработаны), либо ограниченный, содержащий содержимое потока ввода.

Когда Werkzeug обрабатывает данные?

Werkzeug обрабатывает входящие данные в следующих ситуациях:

  • вы обращаетесь к form, files, или stream, а метод запроса был POST или PUT.
  • если вы вызываете parse_form_data().

Эти вызовы не взаимозаменяемы. Если вы вызываете parse_form_data(), вы не должны использовать объект запроса или, по крайней мере, не атрибуты, которые запускают процесс обработки.

Это также верно, если вы считываете данные из потока wsgi.input перед обработкой.

Общее правило: оставьте поток WSGI ввода в покое. Особенно в WSGI-средствах. Используйте либо функции обработки, либо объект запроса. Не смешивайте несколько библиотек WSGI для разбора данных формы или других операций, которые работают с потоком ввода.

Как происходит обработка?

Стандартное поведение Werkzeug по обработке данных учитывает три случая:

  • тип содержимого входных данных был multipart/form-data. В этой ситуации stream будет пустым, а form будет содержать обычные данные POST / PUT, files будет содержать загруженные файлы в виде объектов FileStorage.
  • тип содержимого входных данных был application/x-www-form-urlencoded. Тогда stream будет пустым, а form будет содержать обычные данные POST / PUT и files будет пустым.
  • тип содержимого входных данных не соответствовал ни одному из них, stream указывает на LimitedStream с данными ввода для дальнейшей обработки.

Особое замечание по методу get_data: Вызов этого метода загружает все данные запроса в память. Это безопасно только в том случае, если установлен max_content_length. Также вы можете либо прочитать поток, либо вызвать get_data().

Ограничение данных запроса

Чтобы избежать атак DDOS, вы можете установить максимальную длину содержимого и размер полей запроса. Класс BaseRequest имеет два атрибута для этого: max_content_length и max_form_memory_size.

Первый можно использовать для ограничения общей длины содержимого. Например, установив его в 1024 * 1024 * 16, запрос не примет более 16 МБ переданных данных.

Поскольку некоторые данные нельзя перенести на жесткий диск (обычные данные POST), а временные файлы можно, существует второе ограничение, которое вы можете установить. max_form_memory_size ограничивает размер POST данных переданной формы. Установив его в 1024 * 1024 * 2, вы можете гарантировать, что все поля, хранящиеся в памяти, не превышают 2 МБ.

Однако это не влияет на файлы, хранящиеся в памяти, если используемый stream_factory возвращает файл в памяти.

Как расширить функциональность обработки?

Современные веб-приложения передают гораздо больше, чем данные multipart form или url-encoded. Для расширения возможностей следует создать подкласс BaseRequest или Request и добавить или расширить методы.

Уже существует миксин, обеспечивающий обработку JSON:

from werkzeug.wrappers import Request
from werkzeug.wrappers.json import JSONMixin

class JSONRequest(JSONMixin, Request):
    pass

Базовая реализация выглядит так:

from werkzeug.utils import cached_property
from werkzeug.wrappers import Request
import simplejson as json

class JSONRequest(Request):
    @cached_property
    def json(self):
        if self.mimetype == "application/json":
            return json.loads(self.data)

© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://werkzeug.palletsprojects.com/en/0.15.x/request_data/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API