I am trying to read a gzipped HTTP response with Go! but I always get the following error message :
panic: gzip: invalid header [...] stack trace [...]
If I run "curl -H "Accept-Encoding: gzip" http://foo.com/ | gunzip -" I get the response correctly gunzipped. I also double checked with ngrep and the pair Accept-Encoding/Content-Encoding is correctly sent/returned.
If I create a file with some dummy content and gzip it, I can read it from my Go! program.
The program I used for testing:
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) }
Have I overlooked something ?
You can tell using Developer Tools (F12). Go to the Network tab, select the file you want to examine and then look at the Headers tab on the right. If you are gzipped, then you will see that in the Content-Encoding.
All modern browsers can handle a gzip encoded response. In fact, if you look at their requests, they'll have a header that says something along the lines of Accept-Encoding: gzip which is their way of saying to the server that they can handle gzipped responses.
Gzip is a file format and software application used on Unix and Unix-like systems to compress HTTP content before it's served to a client.
Gzip (GNU zip) is a free and open source algorithm for file compression. The software is overseen by the GNU project. In this context, compression is the deliberate reduction in size of data to save storage space or increase the data transfer rate.
EDIT: The following is an example of manually handling compression. If you don't set the header, the default Transport will do it for you and then decompress while you read the response.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
Error handling removed for brevity. I kept the defers.
net/http#Transport
handles gzip
compressed responses. You don't have to do anything special.
Take a look at the DisableCompression
option, here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With