Отправка сжатых 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
,