将DumpResponse写入文件后如何进行Gzip解压缩?
httputil.DumpResponse Hey there! Let's break down why your example.com.txt file has gibberish after the response headers and how to fix it.
The Root Problem
When you call httputil.DumpResponse(response, true) with a response that has Content-Encoding: gzip, the function writes the raw compressed bytes of the response body directly into the dump. Those compressed bytes look like gibberish when opened as plain text—you need to first decompress the body before dumping it to the file.
Step-by-Step Solution
Here's how to modify your code to decompress the gzipped body, update the response headers to reflect the uncompressed content, and then dump the full readable response:
package main import ( "bytes" "compress/gzip" "io" "log" "net/http" "net/http/httputil" "os" "strings" ) func main() { // Assume 'response' is your existing http.Response object // ... (your code to fetch the response goes here) // Backup the original body and ensure it's closed later originalBody := response.Body defer originalBody.Close() // Set up a reader that handles gzip decompression if needed var contentReader io.Reader = originalBody contentEncoding := response.Header.Get("Content-Encoding") if strings.Contains(strings.ToLower(contentEncoding), "gzip") { // Create a gzip reader to decompress the body gzReader, err := gzip.NewReader(originalBody) if err != nil { log.Fatalf("Failed to create gzip reader: %v", err) } defer gzReader.Close() contentReader = gzReader // Update response headers to reflect uncompressed content response.Header.Del("Content-Encoding") response.Header.Del("Content-Length") // Original length is no longer valid } // Read the uncompressed content uncompressedBody, err := io.ReadAll(contentReader) if err != nil { log.Fatalf("Failed to read response body: %v", err) } // Replace the response body with the uncompressed content (so DumpResponse can read it) response.Body = io.NopCloser(bytes.NewBuffer(uncompressedBody)) // Now dump the updated response (with uncompressed body) dump, err := httputil.DumpResponse(response, true) if err != nil { log.Fatalf("Failed to dump response: %v", err) } // Write the readable dump to file err = os.WriteFile(response.Request.Host+".txt", dump, 0644) if err != nil { log.Fatalf("Failed to write file: %v", err) } }
Key Details Explained
- Backup the Original Body: HTTP response bodies can only be read once, so we save the original to avoid losing data.
- Check for Gzip Encoding: We look for
gzipin theContent-Encodingheader (case-insensitive, since some servers might sendGZIP). - Update Headers: We remove
Content-Encoding(since the content is now uncompressed) andContent-Length(the original length applies to compressed data, not the plaintext). - Replace the Response Body: We wrap the uncompressed bytes in an
io.NopCloserto satisfy thehttp.Response.Bodyinterface, soDumpResponsecan read it properly.
This way, your output file will have the full readable response—headers followed by plaintext content instead of gibberish.
内容的提问来源于stack exchange,提问作者Rudziankoŭ

