Что может быть обманчиво, так это то, что сжатый размер может быть значительно меньше допустимого (размер, который вы можете или хотите обработать). В вашем примере ввод составляет около 1 МБ, а несжатый размер - около 1 ГБ.
При чтении несжатых данных следует остановиться после достижения разумного предела. Чтобы легко сделать это, вы можете использовать io.LimitReader()
, где вы можете указать максимальное количество байтов, которые вы хотите прочитать. Да, вам нужно обернуть поток в разархивированном виде , а не исходный сжатый поток.
Это пример того, как это будет выглядеть:
limited := io.LimitReader(fz, 2http.MaxBytesReader()
1024)
s, err := ioutil.ReadAll(limited)
Приведенный выше пример ограничивает читаемые данные до 2 МБ. Что происходит, когда разархивированные данные больше, чем это? io.Reader
, возвращаемый io.LimitReader()
(что, кстати, io.LimitedReader
) сообщит io.EOF
. Это защищает ваш сервер от атаки, но, возможно, не лучший способ справиться с этим.
Поскольку вы упомянули, что это API для отдыха, лучшим решением будет аналогичное *1024*. Это оборачивает переданный читатель для чтения до заданного предела, и, если он достигнут, он возвращает ошибку, а также отправляет ошибку обратно клиенту HTTP, а также закрывает базовое устройство чтения. Если поведение по умолчанию http.MaxBytesReader()
вам не подходит, проверьте его источники, скопируйте и измените его, это относительно просто. Настройте его под свои нужды.
Также обратите внимание, что вы не должны читать все (несжатые данные) в память. Вы можете передать «ограниченный читатель» на json.NewDecoder()
, который будет считывать данные с данного читателя при декодировании входного JSON. Конечно, если переданный ограниченный читатель сообщает об ошибке, декодирование завершится неудачей.