fish2018/pansou · error
不支持的请求方法
Error message
不支持的请求方法: %s
What it means
requestWithChallengeRetry only supports GET and POST for its cloudscraper-backed retry loop; any other HTTP method reaches the default branch and is rejected. This is a deliberate capability limit of the challenge-retry wrapper.
Solutions
- Use GET or POST for requests routed through the challenge-retry wrapper.
- Extend the switch with a scraper.Do(...) case for other verbs if you control the code.
- Route non-GET/POST requests through a plain HTTP client outside the challenge logic if the endpoint doesn't need anti-bot handling.
Example fix
// before client.Do(req) // method=PUT hits default branch // after req.Method = http.MethodPost // or add a case for PUT backed by scraper resp, err = scraper.Post(requestURL, contentType, strings.NewReader(requestBody))
Defensive patterns
Strategy: validation
Validate before calling
if method != http.MethodGet && method != http.MethodPost { return fmt.Errorf("challenge-retry path supports only GET/POST, got %s", method) } Try / catch
if err != nil { if strings.Contains(err.Error(), "不支持的请求方法") { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) } } Prevention
- Restrict callers to GET/POST for this code path
- Normalize verbs (e.g. PUT-with-body) to POST upstream
- Document the supported method surface
- Return 405 semantics to end users
When it happens
Trigger: Calling the plugin's request path (requestWithChallengeRetry) with method set to e.g. http.MethodPut, DELETE, PATCH, or HEAD.
Common situations: Caller code generating dynamic HTTP methods (REST clients) passed through the plugin, or upstream code changed from GET/POST to another verb.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/535e3a7b7990d0f4.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/gying/gying.go:1919
return nil
}
func (p *GyingPlugin) requestWithChallengeRetry(scraper *cloudscraper.Scraper, method, requestURL, contentType, requestBody string) ([]byte, int, http.Header, error) {
for attempt := 0; attempt < 2; attempt++ {
var (
resp *http.Response
err error
)
switch method {
case http.MethodGet:
// Use cloudscraper for GET as well as POST so the challenge page,
// verification request, and retry share the same browser-like headers.
resp, err = scraper.Get(requestURL)
case http.MethodPost:
resp, err = scraper.Post(requestURL, contentType, strings.NewReader(requestBody))
default:
return nil, 0, nil, fmt.Errorf("不支持的请求方法: %s", method)
}
if err != nil {
return nil, 0, nil, err
}
statusCode := resp.StatusCode
headers := resp.Header.Clone()
body, readErr := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if readErr != nil {
return nil, statusCode, headers, readErr
}
if DebugLog {
fmt.Printf("[Gying] requestWithChallengeRetry: method=%s attempt=%d status=%d url=%s bodyLen=%d challenge=%v loginShell=%v\n",
method, attempt+1, statusCode, requestURL, len(body), isBotChallengePage(body), isLoginShell(body))
}
View on GitHub (pinned to beaa561337)