{"record":{"id":"62c3b4ede0542c70","repo":"fish2018/pansou","slug":"gzip-reader-w","errorCode":null,"errorMessage":"创建gzip reader失败: %w","messagePattern":"创建gzip reader失败: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/leijing/leijing.go","lineNumber":186,"sourceCode":"\t\n\treturn filteredResults, nil\n}\n\n// getResponseReader 获取响应读取器（处理gzip压缩）\nfunc (p *LeijingPlugin) getResponseReader(resp *http.Response) (io.Reader, error) {\n\tvar reader io.Reader = resp.Body\n\t\n\t// 检查Content-Encoding\n\tcontentEncoding := resp.Header.Get(\"Content-Encoding\")\n\tif p.debugMode {\n\t\tlog.Printf(\"[Leijing] Content-Encoding: %s\", contentEncoding)\n\t}\n\t\n\t// 如果是gzip压缩，手动解压\n\tif contentEncoding == \"gzip\" {\n\t\tgzReader, err := gzip.NewReader(resp.Body)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"创建gzip reader失败: %w\", err)\n\t\t}\n\t\treader = gzReader\n\t}\n\t\n\treturn reader, nil\n}\n\n// extractSearchResults 从HTML中提取搜索结果\nfunc (p *LeijingPlugin) extractSearchResults(doc *goquery.Document, keyword string) []model.SearchResult {\n\tvar results []model.SearchResult\n\t\n\t// 选择所有搜索结果项\n\tdoc.Find(\".topicItem\").Each(func(i int, s *goquery.Selection) {\n\t\t// 提取标题和详情页链接\n\t\ttitleElem := s.Find(\".title a\")\n\t\ttitle := strings.TrimSpace(titleElem.Text())\n\t\tdetailPath, _ := titleElem.Attr(\"href\")\n\t\t","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/leijing/leijing.go#L168-L204","documentation":"getResponseReader inspects Content-Encoding and, when it is gzip, wraps resp.Body in a gzip.Reader. This error means gzip.NewReader failed — the server declared gzip but the body is not valid gzip data (corrupt, already decompressed by a proxy, or empty).","triggerScenarios":"Response has Content-Encoding: gzip but gzip.NewReader(resp.Body) errors: body already decompressed by middleware/proxy that forgot to strip the header, truncated body, empty body on an error response, or server mislabeling encoding.","commonSituations":"A reverse proxy (nginx) or service mesh decompressed the body without removing Content-Encoding; a transparent proxy mangles the stream; site sends malformed gzip under load; transparently handling both compressed and plain responses.","solutions":["Log and inspect the first bytes: valid gzip starts with 0x1f 0x8b; if absent, use the raw body","Fix/avoid the proxy that decompresses without stripping Content-Encoding","Set Accept-Encoding manually and handle decompression yourself for full control","Fall back to the raw body when gzip.NewReader fails instead of aborting the search","Check for odd Content-Encoding values like \"gzip, br\" that the simple equality check mishandles"],"exampleFix":"// before\ngzReader, err := gzip.NewReader(resp.Body)\nif err != nil {\n    return nil, fmt.Errorf(\"创建gzip reader失败: %w\", err)\n}\n// after\ngzReader, err := gzip.NewReader(resp.Body)\nif err != nil {\n    // body may not actually be gzip; fall back to raw\n    if ok, _ := resp.Body.(io.Seeker); ok != nil {\n        resp.Body.Seek(0, io.SeekStart)\n    }\n    return resp.Body, nil\n}","handlingStrategy":"fallback","validationCode":"// only expect gzip when we sent Accept-Encoding: gzip and no proxy stripped it\nenc := resp.Header.Get(\"Content-Encoding\")\nmagic, _ := io.ReadAll(io.LimitReader(resp.Body, 2))\nif enc == \"gzip\" && !(len(magic) == 2 && magic[0] == 0x1f && magic[1] == 0x8b) {\n    log.Printf(\"declared gzip but body is not gzip (magic=%x)\", magic)\n}","typeGuard":"func isGzip(b []byte) bool {\n    return len(b) >= 2 && b[0] == 0x1f && b[1] == 0x8b\n}","tryCatchPattern":"reader, err := p.getResponseReader(resp)\nif err != nil {\n    if strings.Contains(err.Error(), \"创建gzip reader失败\") {\n        // fall back to treating the body as plain text\n        reader = resp.Body\n    } else {\n        return nil, err\n    }\n}","preventionTips":["Send an explicit Accept-Encoding header and decode it yourself","Fix proxies that decompress bodies without stripping Content-Encoding","Check the gzip magic bytes (0x1f 0x8b) before constructing a gzip.Reader","Handle multi-encoding values like \"gzip, br\" explicitly","Log first bytes when decompression fails for quick diagnosis"],"tags":["go","gzip","http","decompression"],"backgroundTag":"gzip-decompression-failed","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}