fish2018/pansou · error

响应超过 字节

Error message

响应超过 %d 字节

What it means

requestJSON enforces a 1 MiB (maxResponseSize = 1<<20) cap on any response body by reading at most maxResponseSize+1 bytes via io.LimitReader; if more data is available, the response is assumed abnormal (e.g. an HTML error page, wrong endpoint, or a response bomb) and this error is returned instead of buffering unbounded memory.

Solutions

  1. Log the response's Content-Type and first bytes (via a small debug read) to see what oversized payload the server actually returned.
  2. Verify p.apiBaseURL points at the real Yingso API (default https://ysapi.yingso.fun) and that no proxy/redirect is substituting a different server.
  3. Retry after a short delay — if the Yingso API was briefly serving HTML error pages, the error is transient.
  4. If legitimate API responses have grown beyond 1 MiB, raise the maxResponseSize constant (yingso.go:30) deliberately, accepting the memory tradeoff.
  5. Check for CDN/WAF interception (challenge pages) and add matching headers or bypass the interceptor.

Example fix

// before
maxResponseSize = 1 << 20
// after
// raise cap only if legitimate responses exceed 1 MiB
maxResponseSize = 4 << 20
Defensive patterns

Strategy: validation

Validate before calling

// preflight: ensure endpoint is reachable and returns small JSON, not a huge page
resp, err := client.Head(apiBaseURL + "/test")
if err == nil {
	if cl := resp.Header.Get("Content-Length"); cl != "" {
		if n, _ := strconv.Atoi(cl); n > 1<<20 {
			log.Println("endpoint returns oversized responses; check apiBaseURL/proxy")
		}
	}
}

Try / catch

config, err := p.fetchConfig(ctx, client)
if err != nil {
	if strings.Contains(err.Error(), "响应超过") {
		// oversized/intercepted response: likely proxy/WAF or wrong endpoint
		return nil, fmt.Errorf("yingso returned abnormal oversized body; check network/proxy: %w", err)
	}
	return nil, err
}

Prevention

When it happens

Trigger: Any call through requestJSON — fetchConfig (/test), search (/search), resolveItem (/getKey) — where the Yingso server (or an intercepting proxy/CDN/WAF) returns a body larger than 1,048,576 bytes, such as a large HTML block/captcha page, a compressed-response mishap, or a compromised/misconfigured apiBaseURL pointing at the wrong server.

Common situations: The API is down and a load balancer returns a huge HTML error page; a captive portal or corporate proxy intercepts HTTPS and returns a large page; apiBaseURL was overridden to a debug/development endpoint that returns bulk data; the endpoint was redirected to something unexpected.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/6adedf4cd822cc7c. Report an issue: GitHub.

Appendix: source

Thrown at plugin/yingso/yingso.go:313

	req.Header.Set("Origin", websiteURL)
	req.Header.Set("Referer", websiteURL+"/")
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36")
	if payload != nil {
		req.Header.Set("Content-Type", "application/json")
	}

	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(io.LimitReader(resp.Body, maxResponseSize+1))
	if err != nil {
		return err
	}
	if len(data) > maxResponseSize {
		return fmt.Errorf("响应超过 %d 字节", maxResponseSize)
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("HTTP %d: %s", resp.StatusCode, strings.TrimSpace(string(data)))
	}
	if err := jsonutil.Unmarshal(data, target); err != nil {
		return fmt.Errorf("解析响应失败: %w", err)
	}
	return nil
}

func encryptPayload(payload interface{}, config apiConfig) (encryptedPayload, error) {
	no, err := randomToken(24)
	if err != nil {
		return encryptedPayload{}, err
	}
	if config.Start < 0 || config.End <= config.Start || config.End > len(no) {
		return encryptedPayload{}, fmt.Errorf("无效的加密区间 %d:%d", config.Start, config.End)
	}

View on GitHub (pinned to beaa561337)