Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading gzipped HTTP response in Go

Tags:

go

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 ?

like image 396
Jérôme R Avatar asked Oct 29 '12 22:10

Jérôme R


People also ask

How do I know if a response is gzipped?

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.

Can browser read gzip?

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.

What is gzip http compression?

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.

What is gzipped data?

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.


2 Answers

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.

like image 185
Stephen Weinberg Avatar answered Oct 22 '22 08:10

Stephen Weinberg


net/http#Transport handles gzip compressed responses. You don't have to do anything special.

Take a look at the DisableCompression option, here.

like image 34
simonmenke Avatar answered Oct 22 '22 08:10

simonmenke