{"record":{"id":"2873e2a371f77259","repo":"shadow1ng/fscan","slug":"s-w-webscan-request-send-error","errorCode":null,"errorMessage":"%s: %w (webscan_request_send_error)","messagePattern":"(.+?): %w \\(webscan_request_send_error\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"webscan/lib/poc_executor.go","lineNumber":804,"sourceCode":"\tnewRequest, err := http.NewRequestWithContext(oReq.Context(), rule.Method, reqURL, strings.NewReader(rule.Body))\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"%s: %w\", i18n.GetText(\"webscan_http_request_error\"), err)\n\t}\n\tdefer func() { newRequest = nil }()\n\n\t// 设置请求头\n\tnewRequest.Header = oReq.Header.Clone()\n\tfor key, value := range rule.Headers {\n\t\tnewRequest.Header.Set(key, value)\n\t}\n\n\t// 发送请求\n\tresp, err := DoRequest(newRequest, rule.FollowRedirects, session)\n\tif err != nil {\n\t\tif isTransportError(err) {\n\t\t\treturn false, nil\n\t\t}\n\t\treturn false, fmt.Errorf(\"%s: %w\", i18n.GetText(\"webscan_request_send_error\"), err)\n\t}\n\n\t// 更新响应到变量映射\n\tvariableMap[\"response\"] = resp\n\n\t// 执行搜索规则\n\tif rule.Search != \"\" {\n\t\tsearchContent := GetHeader(resp.Headers) + string(resp.Body)\n\t\tresult := doSearch(rule.Search, searchContent)\n\n\t\tif len(result) > 0 {\n\t\t\t// 将搜索结果添加到变量映射\n\t\t\tfor key, value := range result {\n\t\t\t\tvariableMap[key] = value\n\t\t\t}\n\t\t} else {\n\t\t\treturn false, nil\n\t\t}","sourceCodeStart":786,"sourceCodeEnd":822,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/webscan/lib/poc_executor.go#L786-L822","documentation":"clustersend wraps any error from DoRequest that is NOT a transport error with the localized 'request send error' message (transport errors are silently treated as a failed probe instead). So this error means the HTTP request was constructed and attempted, but the client refused/failed to send it for a non-transport reason — e.g. context deadline/cancellation, invalid configuration of the request at send time, or client-level rejection.","triggerScenarios":"DoRequest(newRequest, rule.FollowRedirects, session) returns an error where isTransportError(err) is false — typically context deadline exceeded (the shared oReq context timed out), context canceled (scan aborted), or a non-transport client failure.","commonSituations":"Scanning a slow host that exceeds the session/context timeout during brute-force mode; user cancels the scan mid-run and the shared context is canceled; a request with both body and conflicting settings rejected by the client transport configuration.","solutions":["Inspect the wrapped cause: \"context deadline exceeded\" means raise the timeout on the context passed to the scan; \"context canceled\" means the scan was aborted upstream.","If the target is legitimately slow, increase the session timeout or exclude the target.","If you expect network failures to be skipped, verify isTransportError recognizes them — a custom wrapped error may be misclassified as non-transport and surfaced here.","Retry the scan to distinguish transient conditions from deterministic request rejection."],"exampleFix":"// before\nctx := context.Background()\nsend := DoRequest(...) // webscan_request_send_error: context deadline exceeded\n// after\nctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\ndefer cancel()\nsend := DoRequest(...)","handlingStrategy":"try-catch","validationCode":"if _, ok := oReq.Context().Deadline(); !ok {\n    var cancel context.CancelFunc\n    oReq = oReq.WithContext(context.WithTimeout(oReq.Context(), 30*time.Second))\n    defer cancel()\n}","typeGuard":null,"tryCatchPattern":"resp, err := DoRequest(newRequest, rule.FollowRedirects, session)\nif err != nil {\n    if isTransportError(err) {\n        return false, nil // expected for unreachable hosts\n    }\n    if errors.Is(err, context.DeadlineExceeded) {\n        log.Printf(\"target %s timed out, raising timeout\", newRequest.URL)\n        return false, nil\n    }\n    if errors.Is(err, context.Canceled) {\n        return false, err // scan aborted, propagate\n    }\n    return false, fmt.Errorf(\"%s: %w\", i18n.GetText(\"webscan_request_send_error\"), err)\n}","preventionTips":["Set an explicit timeout on the context passed into the scan large enough for slow targets","Distinguish context.Canceled (user abort) from DeadlineExceeded (raise timeout)","Ensure isTransportError covers all wrapped transport error types so failures are skipped, not surfaced","Monitor scan cancellation so canceled contexts are not misreported as request-send errors"],"tags":["go","webscan","http","timeout","context"],"backgroundTag":"request-timeout","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}