Отправка сжатых gzip данных через сокет TCP в Python

Я создаю HTTP-сервер в Python без каких-либо HTTP-библиотек в учебных целях. Прямо сейчас он может нормально обслуживать статические файлы.

То, как я работаю с файлом, осуществляется с помощью этого фрагмента кода:

with open(self.filename, 'rb') as f:
    src = f.read()
socket.sendall(src)

Однако я хочу немного оптимизировать его производительность, отправляя сжатые данные вместо несжатых. Я знаю, что мой браузер (Chrome) принимает сжатые данные, потому что это говорит мне в шапке

Accept-Encoding: gzip, deflate, sdch

Итак, я изменил свой код на это

with open(self.filename, 'rb') as f:
    src = zlib.compress(f.read())
socket.sendall(src)

Но это просто выводит мусор. Что я делаю неправильно?

1 ответ

Решение

В библиотеке zlib реализован алгоритм сжатия с раздувом (RFC 1951). Существует две инкапсуляции для сжатия при сжатии: zlib (RFC 1950) и gzip (RFC 1952). Они отличаются только типом заголовка и трейлера, которые они предоставляют вокруг сжатых данных с раздувкой.

zlib.compress предоставляет только необработанные данные выкачивания без заголовка и трейлера. Чтобы получить их, вам нужно использовать объект сжатия. Для gzip это выглядит так:

z = zlib.compressobj(-1,zlib.DEFLATED,31)
gzip_compressed_data = z.compress(data) + z.flush()

Важной частью здесь является 31 в качестве третьего аргумента compressobj, Это определяет формат GZIP, который затем может быть использован с Content-Encoding: gzip,

Другие вопросы по тегам