Передавайте байты gzip с заголовками, которые их описывают
Выберите кодированную или декодированную полезную нагрузку в прокси на основе Requests, затем задайте нижестоящему ответу соответствующие content-заголовки и собственное кадрирование.
Если Requests уже распаковал тело, передача его с Content-Encoding: gzip просит следующего клиента распаковать его снова. Решите, какое представление полезной нагрузки отправляет прокси, прежде чем копировать заголовки.
| Отправленная нагрузка | Content-заголовки |
|---|---|
| Исходные кодированные байты | Сохраните применимую кодировку и точную длину нагрузки |
| Декодированные байты | Удалите декодированную кодировку; удалите или пересчитайте соответствующую длину |
Для кодированных байтов нагрузки этот фрагмент читает необработанный поток urllib3 без декодирования content:
with requests.get(url, stream=True, timeout=(5, 30)) as upstream:
upstream.raise_for_status()
for block in upstream.raw.stream(65536, decode_content=False):
downstream.write(block)downstream — это существующий вывод ответа. Его статус и заголовки уже должны следовать выбранной политике; этот фрагмент не реализует полноценный прокси-сервер.
Кадрирование передачи отделено от content-кодирования gzip. Библиотека HTTP выше по потоку уже обработала кадрирование, включая удаление фрагментов, поэтому не копируйте Transfer-Encoding вслепую. Нижестоящий сервер кадрирует собственный ответ, даже когда нагрузка остаётся закодированной gzip.
response.text с последующим кодированием UTF-8 также меняет представление и не может сохранить произвольные двоичные данные. Закрывайте или потребляйте вышестоящий ответ на каждом пути и обрабатывайте ошибки HTTP согласно контракту прокси: этот пример выбрасывает их вместо передачи.