package checker import ( "fmt" "io" "net/http" "time" ) // sharedHTTPClient is reused across sources so connection pooling and // keep-alives kick in. Per-call deadlines are expressed via // context.WithTimeout on the request context, not on the client. var sharedHTTPClient = &http.Client{Timeout: 60 * time.Second} // httpDo executes req on the shared client, reads up to maxBytes from // the response body, and returns the body, the HTTP status code and any // error. Status-code semantics differ per API (404 means "unknown" on // VirusTotal, body-level fields drive URLhaus, …) so the caller decides // how to interpret status; this helper only handles the boilerplate // common to every JSON-ish source. func httpDo(req *http.Request, maxBytes int64) (body []byte, status int, err error) { resp, err := sharedHTTPClient.Do(req) if err != nil { return nil, 0, err } defer resp.Body.Close() body, err = io.ReadAll(io.LimitReader(resp.Body, maxBytes)) if err != nil { return nil, resp.StatusCode, fmt.Errorf("read body: %w", err) } return body, resp.StatusCode, nil }