How do I process compressed HTTP responses in Go?

In Go, processing compressed HTTP responses typically involves sending an HTTP request with an Accept-Encoding header and then handling the compressed response body correctly. Here's how you can process compressed HTTP responses in Go:

  1. Set the Accept-Encoding header: When making an HTTP request, set the Accept-Encoding header to indicate that your client can handle compressed responses. The most common compression schemes are gzip and deflate.

  2. Read the Content-Encoding response header: Once you receive the response, check the Content-Encoding header to determine what type of compression, if any, was applied.

  3. Decompress the response body: Based on the Content-Encoding, use the appropriate decompression method to process the response body.

Here is a sample code snippet that demonstrates how to process compressed HTTP responses in Go:

package main

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

func main() {
    url := "http://example.com" // Replace with the actual URL

    // Create a new HTTP request
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error creating request: %v\n", err)
        return
    }

    // Add Accept-Encoding header to request gzip (and/or deflate)
    req.Header.Add("Accept-Encoding", "gzip, deflate")

    // Perform the request
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error performing request: %v\n", err)
        return
    }
    defer resp.Body.Close()

    // Check what encoding was returned
    encoding := resp.Header.Get("Content-Encoding")

    // Create a reader based on the encoding
    var reader io.ReadCloser
    switch {
    case strings.Contains(encoding, "gzip"):
        reader, err = gzip.NewReader(resp.Body)
        if err != nil {
            fmt.Fprintf(os.Stderr, "Error creating GZIP reader: %v\n", err)
            return
        }
        defer reader.Close()
    case strings.Contains(encoding, "deflate"):
        // Implement deflate decompression if necessary
        // ...
    default:
        reader = resp.Body
    }

    // Read from the decompressed stream
    body, err := io.ReadAll(reader)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error reading response body: %v\n", err)
        return
    }

    // Use the decompressed response body
    fmt.Println(string(body))
}

In this example:

  • We create a new http.Request object and explicitly add an Accept-Encoding header to it.
  • We send the request using an http.Client.
  • We check the Content-Encoding header of the response to determine if the response is compressed.
  • If the response is compressed with gzip, we create a gzip.Reader to decompress the response body. If it's deflate or another encoding, you would need to implement the appropriate decompression logic.
  • Finally, we read the decompressed response body and print it out.

Note that if you don't require manual control over the Accept-Encoding header and the compression handling, the Go http package can automatically handle gzip compressed responses if you use http.Get or http.DefaultClient.Do. It will check the Content-Encoding header and automatically decompress the response if it's gzip-encoded. However, this automatic decompression only works for gzip and not for other encodings like deflate.

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon