Стандартный клиент
http.Transport сам добавляет в запрос Accept-Encoding: gzip и, если сервер отвечает с Content-Encoding: gzip, клиент сам распакует ответ. Но только пока Accept-Encoding не выставлен вручную. Если клиент сам задаёт этот заголовок (случайно либо намеренно с указанием другого алгоритма типа `zstd`) логику распаковки тоже надо писать самому. Подробнее прямо описано в доке `net/http`Интересно, что на сервере симметричной автоматики нет.
http.Server сам ответы не сжимает - и это довольно логично: но стороне сервера eщё нужно решить, стоит ли вообще сжимать конкретный ответ. Все таки сжатие переносит часть стоимости с сети на cpu: сервер и клиент тратят проц на переупаковки в обмен на уменьшение объёма передаваемых по сети данных. Поэтому для тех, кому экономия на сжатии превышает доп вычисления, будет полезно обернуть хендлер небольшим миддлваром, например через klauspost/compress
func responseCompressionMiddleware(next http.Handler) http.Handler {
return gzhttp.GzipHandler(next)
}
Нейминг может запутать, потому что
gzhttp.GzipHandler умеет не только gzip, но и zstd: алгоритм выбирается по Accept-Encoding, а при одинаковом приоритете q выбирает zstd.А если передаются секреты или другая sensitive инфа, у
gzhttp можно добавить RandomJitter - оберточная функция, которая добавляет небольшой padding, размывая точный размер сжатого ответа, чтобы нарушитель не смог по небольшим изменениям размера косвенно угадывать части секретаТакже можно обернуть весь клиент
http.Transport через gzhttp.Transport и автоматическая распаковка будет распространяться уже и на zstd - тогда как стандартный http.Transport автоматически работает только с gzip. Не знаю, насколько это общеизвестная деталь, но я даже про gzip под капотом узнала только сейчас :-)#go #perf