WSGI Помощники
Следующие классы и функции предназначены для упрощения работы со спецификацией WSGI или работы на уровне WSGI. Все функциональные возможности этого модуля доступны на уровне высокоуровневых Объектов запроса/ответа.
Помощники итераторов/потоков
Эти классы и функции упрощают работу с итератором приложения WSGI и входным потоком.
-
class werkzeug.wsgi.ClosingIterator(iterable, callbacks=None) -
Спецификация WSGI требует, чтобы все промежуточные ПО и шлюзы обрабатывали обратный вызов
closeитерируемого объекта, возвращаемого приложением. Поскольку полезно добавить ещё один закрывающий действие к возвращаемому итерируемому объекту, а добавление пользовательского итерируемого объекта - это скучная задача, этот класс может быть использован для этого:return ClosingIterator(app(environ, start_response), [cleanup_session, cleanup_locals])Если существует только одна функция закрытия, её можно передать вместо списка.
Итератор закрытия не нужен, если приложение использует объекты ответа и завершает обработку, если ответ уже начат:
try: return response(environ, start_response) finally: cleanup_session() cleanup_locals()- Параметры:
-
- iterable (t.Iterable[bytes]) –
- callbacks (None | (t.Callable[[], None] | t.Iterable[t.Callable[[], None]])) –
-
class werkzeug.wsgi.FileWrapper(file, buffer_size=8192) -
Этот класс может использоваться для преобразования объекта типа
fileв итерируемый объект. Он выдает блокиbuffer_sizeдо тех пор, пока файл не будет полностью прочитан.Вы не должны использовать этот класс напрямую, а скорее использовать функцию
wrap_file(), которая использует поддержку файлового оборачивателя сервера WSGI, если она доступна.Журнал изменений
Введено в версии 0.5.
Если вы используете этот объект вместе с
Response, вам нужно использовать режимdirect_passthrough.
-
class werkzeug.wsgi.LimitedStream(stream, limit, is_max=False) -
Оборачивает поток, чтобы он не читал больше заданного предела. Это используется для ограничения
wsgi.inputзначением заголовкаContent-LengthилиRequest.max_content_length.При попытке чтения после достижения предела вызывается
on_exhausted(). При достижении максимального предела это вызываетRequestEntityTooLarge.Если чтение из потока возвращает ноль байтов или вызывает ошибку, вызывается
on_disconnect(), который вызываетClientDisconnected. Когда предел является максимальным и было прочитано ноль байтов, ошибка не возникает, так как это может быть конец потока.Если предел достигнут до того, как основной поток будет исчерпан (например, файл слишком большой или поток бесконечный), оставшееся содержимое потока нельзя безопасно прочитать. В зависимости от того, как сервер обрабатывает это, клиенты могут показать ошибку «разрыв соединения» вместо отображения ответа 413.
- Параметры:
-
- stream (t.IO[bytes]) – Поток для чтения. Должен быть читаемым двоичным объектом IO.
-
limit (int) – Предел в байтах, после которого чтение прекращается. Должен быть либо значением заголовка
Content-Length, либоrequest.max_content_length. -
is_max (bool) – Является ли данный предел
limitмаксимальным значением, а не значением заголовкаContent-Length. Это изменяет способ обработки событий исчерпания и разрыва соединения.
Изменено в версии 2.3: Обработка исчерпания
max_content_lengthотличается отContent-Length.Изменено в версии 2.3: Реализует
io.RawIOBaseвместоio.IOBase.-
exhaust() -
Исчерпать поток, читая до тех пор, пока не будет достигнут предел или клиент не прервет соединение, возвращая оставшиеся данные.
Изменено в версии 2.3: Возвращает оставшиеся данные.
Журнал изменений
Изменено в версии 2.2.3: Обработка случая, когда обернутый поток возвращает меньше байтов, чем запрошено.
- Тип возвращаемого значения:
-
property is_exhausted: bool -
Является ли текущая позиция потока достигла предела.
-
on_disconnect(error=None) -
Вызывается, когда попытка чтения получает ноль байтов до того, как был достигнут предел. Это указывает на то, что клиент прервал соединение до отправки всего тела запроса.
По умолчанию, поведение - вызов
ClientDisconnected, за исключением случая, когда предел максимальный, и не было вызвано никаких ошибок.Изменено в версии 2.3: Добавлен параметр
error. Ничего не делать, если предел является максимальным и не было вызвано никаких ошибок.Изменено в версии 2.3: Любое возвращаемое значение игнорируется.
- Параметры:
-
error (Исключение | None) –
- Тип возвращаемого значения:
-
None
-
on_exhausted() -
Вызывается при попытке чтения после достижения предела.
По умолчанию, поведение - ничего не делать, за исключением случая, когда предел максимальный, в котором случае вызывается
RequestEntityTooLarge.Изменено в версии 2.3: Вызывает
RequestEntityTooLargeесли предел максимальный.Изменено в версии 2.3: Любое возвращаемое значение игнорируется.
- Тип возвращаемого значения:
-
None
-
readable() -
Возвращает, открыт ли объект для чтения.
Если False, read() вызовет OSError.
- Тип возвращаемого значения:
-
readall() -
Чтение до EOF, используя несколько вызовов read().
- Тип возвращаемого значения:
-
tell() -
Возвращает текущую позицию потока.
Журнал изменений
Введено в версии 0.9.
- Тип возвращаемого значения:
-
werkzeug.wsgi.make_line_iter(stream, limit=None, buffer_size=10240, cap_at_buffer=False) -
Безопасно итерируется по входному потоку, строка за строкой. Если входной поток не является
LimitedStream, параметрlimitявляется обязательным.Это использует метод
read()потока внутри, в отличие от методаreadline(), который небезопасен и может использоваться только с нарушением спецификации WSGI. Та же проблема относится к функции__iter__входного потока, которая вызываетreadline()без аргументов.Если вам нужна обработка построчно, настоятельно рекомендуется использовать эту вспомогательную функцию для итерации по входному потоку.
Устарело начиная с версии 2.3: Будет удалено в Werkzeug 3.0.
Журнал изменений
Добавлена в версии 0.11: Добавлена поддержка параметра
cap_at_buffer.Добавлена в версии 0.9: Добавлена поддержка итераторов в качестве входного потока.
Изменено в версии 0.8: Теперь эта функция гарантирует, что предел был достигнут.
- Параметры:
-
- stream (Iterable[bytes] | IO[bytes]) – поток или итерируемый объект для итерирования.
-
limit (int | None) – предел в байтах для потока. (Обычно длина содержимого. Не требуется, если
streamявляетсяLimitedStream. - buffer_size (int) – необязательный размер буфера.
- cap_at_buffer (bool) – если установлено, куски разделяются, если они длиннее размера буфера. Внутренне реализовано так, что размер буфера может быть исчерпан в два раза.
- Тип возвращаемого значения:
-
werkzeug.wsgi.make_chunk_iter(stream, separator, limit=None, buffer_size=10240, cap_at_buffer=False) -
Работает как
make_line_iter(), но принимает разделитель, который разделяет куски. Если вам нужна обработка на основе новой строки, вы должны использоватьmake_line_iter(), так как он поддерживает произвольные маркеры новой строки.Устарело начиная с версии 2.3: Будет удалено в Werkzeug 3.0.
Журнал изменений
Изменено в версии 0.11: Добавлена поддержка параметра
cap_at_buffer.Изменено в версии 0.9: Добавлена поддержка итераторов в качестве входного потока.
Добавлена в версии 0.8.
- Параметры:
-
- stream (Iterable[bytes] | IO[bytes]) – поток или итерируемый объект для итерирования.
- separator (bytes) – разделитель, который разделяет куски.
-
limit (int | None) – предел в байтах для потока. (Обычно длина содержимого. Не требуется, если
streamуже ограничен). - buffer_size (int) – необязательный размер буфера.
- cap_at_buffer (bool) – если установлено, куски разделяются, если они длиннее размера буфера. Внутренне реализовано так, что размер буфера может быть исчерпан в два раза.
- Тип возвращаемого значения:
-
werkzeug.wsgi.wrap_file(environ, file, buffer_size=8192) -
Оборачивает файл. Это использует оболочку файла сервера WSGI, если она доступна, или же общую оболочку
FileWrapper.Журнал изменений
Добавлена в версии 0.5.
Если используется оболочка файла сервера WSGI, важно не итерироваться по ней внутри приложения, а передавать её без изменений. Если вы хотите передать оболочку файла внутри объекта ответа, вы должны установить
Response.direct_passthroughвTrue.Дополнительную информацию об оболочках файлов можно найти в PEP 333.
Environ Helpers
Эти функции работают с окружением WSGI. Они извлекают полезную информацию или выполняют общие преобразования:
-
werkzeug.wsgi.get_host(environ, trusted_hosts=None) -
Возвращает хост для заданного окружения WSGI.
Заголовок
Hostпредпочтительнее, затемSERVER_NAME, если он не задан. Возвращаемый хост будет содержать порт только если он отличается от стандартного порта для протокола.Можно проверить, является ли хост доверенным, используя
host_is_trusted(), и выброситьSecurityError, если он не доверен.- Parameters:
-
- environ (WSGIEnvironment) – Словарь окружения WSGI.
- trusted_hosts (t.Iterable[str] | None) – Список доверенных имен хостов.
- Returns:
-
Хост, с портом при необходимости.
- Raises:
-
SecurityError – Если хост не доверен.
- Return type:
-
werkzeug.wsgi.get_content_length(environ) -
Возвращает значение заголовка
Content-Lengthкак целое число. Если заголовок не задан или заголовокTransfer-Encodingchunked, возвращаетсяNoneдля обозначения запроса потокового типа. Если значение не является целым числом или отрицательным, возвращается 0.- Parameters:
-
environ (WSGIEnvironment) – Окружение WSGI для получения длины содержимого.
- Return type:
-
int | None
Changelog
New in version 0.9.
-
werkzeug.wsgi.get_input_stream(environ, safe_fallback=True, max_content_length=None) -
Возвращает поток WSGI, обернутый так, чтобы его можно было безопасно читать, не выходя за пределы значения заголовка
Content-Lengthилиmax_content_length.Если
Content-Lengthпревышаетmax_content_length, генерируется ошибкаRequestEntityTooLarge`413 Content Too Large.Если сервер WSGI устанавливает
environ["wsgi.input_terminated"], это указывает, что сервер отвечает за завершение потока, поэтому его можно безопасно читать непосредственно. Например, сервер, знающий, как безопасно обрабатывать запросы с чанками, установит это.Если
max_content_lengthзадано, оно может быть применено к потокам, еслиwsgi.input_terminatedзадано. В противном случае возвращается пустой поток, если пользователь явно не отключил этот безопасный резервный вариант.Если предел достигается до того, как базовый поток исчерпан (например, файл слишком большой или поток бесконечный), оставшееся содержимое потока нельзя безопасно прочитать. В зависимости от того, как сервер обрабатывает это, клиенты могут показать ошибку «разрыв соединения» вместо того, чтобы увидеть ответ 413.
- Parameters:
-
- environ (WSGIEnvironment) – Окружение WSGI, содержащее поток.
-
safe_fallback (bool) – Возвращает пустой поток, когда
Content-Lengthне задано. Отключение этого позволяет бесконечные потоки, что может представлять риск атаки типа «отказ в обслуживании». - max_content_length (int | None) – Максимальная длина, которую значения content-length или потоковых запросов не должны превышать.
- Return type:
-
t.IO[bytes]
Изменено в версии 2.3.2:
max_content_lengthприменяется только к потоковым запросам, если сервер устанавливаетwsgi.input_terminated.Изменено в версии 2.3: Проверяется
max_content_lengthи генерируется ошибка, если оно превышено.Changelog
New in version 0.9.
-
werkzeug.wsgi.get_current_url(environ, root_only=False, strip_querystring=False, host_only=False, trusted_hosts=None) -
Воссоздает URL запроса из частей в окружении WSGI.
URL — это IRI, а не URI, поэтому он может содержать символы Юникода. Используйте
iri_to_uri()для преобразования его в ASCII.- Parameters:
-
- environ (WSGIEnvironment) – Окружение WSGI для получения частей URL.
- root_only (bool) – Построить только корневой путь, не включать оставшийся путь или строку запроса.
- strip_querystring (bool) – Не включать строку запроса.
- host_only (bool) – Построить только схему и хост.
- trusted_hosts (t.Iterable[str] | None) – Список доверенных имен хостов для проверки хоста.
- Return type:
-
werkzeug.wsgi.host_is_trusted(hostname, trusted_list) -
Проверяет, соответствует ли хост списку доверенных имён.
- Parameters:
- Return type:
Changelog
New in version 0.9.
Convenience Helpers
-
werkzeug.wsgi.responder(f) -
Отмечает функцию как обработчик ответа. Примените её к функции, и она автоматически вызовет возвращаемое значение как приложение WSGI.
Пример:
@responder def application(environ, start_response): return Response('Hello World!')- Parameters:
-
f (t.Callable[..., WSGIApplication]) –
- Return type:
-
WSGIApplication
-
werkzeug.testapp.test_app(req) -
Простой тестовый пример, который отображает окружение. Вы можете использовать его для проверки корректной работы Werkzeug:
>>> from werkzeug.serving import run_simple >>> from werkzeug.testapp import test_app >>> run_simple('localhost', 3000, test_app) * Running on http://localhost:3000/Приложение отображает важную информацию из окружения WSGI, интерпретатора Python и установленных библиотек.
Байты, строки и кодировки
Значения в HTTP-запросах поступают в виде байтов, представляющих (или закодированных в) ASCII. Спецификация WSGI (PEP 3333) решила всегда использовать тип str для представления значений. Для этого исходные байты декодируются с помощью кодировки ISO-8859-1, чтобы получить строку.
Строки в среде WSGI ограничены кодовыми точками ISO-8859-1. Если строка, считанная из среды, может содержать символы за пределами этой кодировки, её необходимо сначала декодировать в байты как ISO-8859-1, а затем закодировать в строку с использованием соответствующей кодировки (обычно UTF-8). Обратное делается при записи в среду. Это известно как «танцы с кодировкой WSGI».
Werkzeug предоставляет функции для автоматической обработки этого, чтобы вам не приходилось знать внутренние механизмы. Используйте функции на этой странице, а также EnvironHeaders(), чтобы читать данные из среды WSGI.
Приложения должны избегать ручного создания или изменения среды WSGI, если не позаботятся о правильном кодировании или декодировании. Все интерфейсы высокого уровня в Werkzeug будут применять кодирование и декодирование по мере необходимости.
Необработанный URI запроса и кодировка пути
PATH_INFO в среде — это значение пути после декодирования процентов. Например, необработанный путь /hello%2fworld будет отображаться от сервера WSGI в Werkzeug как /hello/world. Это теряет информацию о том, что слеш был исходным символом, а не разделителем путей.
Спецификация WSGI (PEP 3333) не предоставляет способ получить исходное значение, поэтому невозможно маршрутизировать некоторые типы данных в пути. Самый совместимый способ обойти это — отправить проблемные данные в строке запроса, а не в пути.
Однако многие серверы WSGI добавляют нестандартный ключ среды с необработанным путем. Для соответствия этому поведению тестовый клиент и сервер разработки Werkzeug добавят необработанное значение как в ключ REQUEST_URI, так и в RAW_URI. Если вы хотите маршрутизировать на основе этого значения, вы можете использовать middleware для замены PATH_INFO в среде перед тем, как она достигнет приложения. Однако помните, что эти ключи нестандартные и не гарантируются.
© 2007–2022 Pallets
Licensed under the BSD 3-clause License.
https://werkzeug.palletsprojects.com/en/2.3.x/wsgi/