Подтвердить что ты не робот

Чтение HTTP-ответа gzipped в Go

Я пытаюсь прочитать HTTP-ответ gzipped с Go! но я всегда получаю следующее сообщение об ошибке:

panic: gzip: invalid header
[...] stack trace [...]

Если я запустил "curl -H" Accept-Encoding: gzip "http://foo.com/ | gunzip -" Я правильно отвечу ответ. Я также дважды проверял с помощью ngrep, и пара Accept-Encoding/Content-Encoding правильно отправлена ​​/возвращена.

Если я создам файл с каким-то фиктивным контентом и gzip его, я могу прочитать его с моего Go! Программа.

Программа, которую я использовал для тестирования:

package main

import (
    "io"
    //"os"
    "fmt"
    "compress/gzip"
    "net/http"
)

func main() {
    /* This works fine
    f, _ := os.Open("/tmp/test.gz")
    defer f.Close()
    reader, err := gzip.NewReader(f)
    */

    // This does not :/
    resp, _ := http.Get("http://foo.com/")
    defer resp.Body.Close()
    reader, err := gzip.NewReader(resp.Body)

    if err != nil { panic(err) }

    buff := make([]byte, 1024)
    for {
        n, err := reader.Read(buff)

        if err != nil && err != io.EOF {
            panic(err)
        }

        if n == 0 {
            break
        }
    }

    s := fmt.Sprintf("%s", buff)
    fmt.Println(s)
}

Я что-то пропустил?

4b9b3361

Ответ 1

EDIT: Ниже приведен пример ручной обработки сжатия. Если вы не установите заголовок, по умолчанию Transport сделает это для вас, а затем распакуется, когда вы прочитаете ответ .Body.

client := new(http.Client)

request, err := http.NewRequest("GET", "http://stackoverflow.com", nil)
request.Header.Add("Accept-Encoding", "gzip")

response, err := client.Do(request)
defer response.Body.Close()

// Check that the server actually sent compressed data
var reader io.ReadCloser
switch response.Header.Get("Content-Encoding") {
case "gzip":
    reader, err = gzip.NewReader(response.Body)
    defer reader.Close()
default:
    reader = response.Body
}

io.Copy(os.Stdout, reader) // print html to standard out

Обработка ошибок удалена для краткости. Я держал перебежчиков.

Ответ 2

net/http обрабатывает сжатые ответы. Вам не нужно ничего особенного делать.

Ответ 3

В соответствии с net/http docs (строка 110), если вы вручную установите заголовок запроса Accept-Encoding, чем gzipped-ответ не будет автоматически декомпрессирован на http.Transport. В противном случае поведение управляется транспортным DisableCompression boolean