Если 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 согласно контракту прокси: этот пример выбрасывает их вместо передачи.

Похожие статьи