Enforce Go style rules across codebase

Apply five style rules: convert iota string enums to typed
string constants, replace errors.As with errors.AsType,
merge three-group imports into two groups, fix multiline
parameter/argument formatting, and replace fmt.Sprintf URL
construction with net/url.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-05-20 11:46:39 +04:00
parent 34c25c2727
commit f5703d390b
105 changed files with 1180 additions and 940 deletions

View File

@@ -95,8 +95,7 @@ func blockingCallLLM(ctx context.Context, agent *Agent, req *llm.ChatCompletionR
// Some providers (e.g. Anthropic) require streaming for large
// max_tokens or when thinking is enabled. Fall back to streaming
// transparently when the blocking call returns ErrStreamingRequired.
var streamRequired *llm.ErrStreamingRequired
if !errors.As(err, &streamRequired) {
if _, ok := errors.AsType[*llm.ErrStreamingRequired](err); !ok {
return nil, err
}

View File

@@ -54,56 +54,70 @@ func DownloadPDFTool() agent.Tool {
"Download a PDF document from a URL and extract its text content. Use this for DPAs, SOC 2 reports, privacy policies, and other documents hosted as PDFs.",
func(ctx context.Context, p downloadPDFParams) (agent.ToolResult, error) {
if err := validatePublicURL(p.URL); err != nil {
return agent.ResultJSON(downloadPDFResult{
ErrorDetail: fmt.Sprintf("URL not allowed: %s", err),
}), nil
return agent.ResultJSON(
downloadPDFResult{
ErrorDetail: fmt.Sprintf("URL not allowed: %s", err),
},
), nil
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, p.URL, nil)
if err != nil {
return agent.ResultJSON(downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot create request: %s", err),
}), nil
return agent.ResultJSON(
downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot create request: %s", err),
},
), nil
}
resp, err := client.Do(req)
if err != nil {
return agent.ResultJSON(downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot download PDF: %s", err),
}), nil
return agent.ResultJSON(
downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot download PDF: %s", err),
},
), nil
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return agent.ResultJSON(downloadPDFResult{
ErrorDetail: fmt.Sprintf("PDF download returned status %d", resp.StatusCode),
}), nil
return agent.ResultJSON(
downloadPDFResult{
ErrorDetail: fmt.Sprintf("PDF download returned status %d", resp.StatusCode),
},
), nil
}
// Read PDF into memory (max 20MB).
body, err := io.ReadAll(io.LimitReader(resp.Body, 20*1024*1024))
if err != nil {
return agent.ResultJSON(downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot read PDF body: %s", err),
}), nil
return agent.ResultJSON(
downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot read PDF body: %s", err),
},
), nil
}
// Write to temp file for pdfcpu.
tmpDir, err := os.MkdirTemp("", "pdf-extract-*")
if err != nil {
return agent.ResultJSON(downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot create temp dir: %s", err),
}), nil
return agent.ResultJSON(
downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot create temp dir: %s", err),
},
), nil
}
defer func() { _ = os.RemoveAll(tmpDir) }()
tmpFile := filepath.Join(tmpDir, "input.pdf")
if err := os.WriteFile(tmpFile, body, 0o600); err != nil {
return agent.ResultJSON(downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot write temp file: %s", err),
}), nil
return agent.ResultJSON(
downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot write temp file: %s", err),
},
), nil
}
// Get page count.
@@ -111,24 +125,30 @@ func DownloadPDFTool() agent.Tool {
pageCount, err := api.PageCountFile(tmpFile)
if err != nil {
return agent.ResultJSON(downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot read PDF: %s", err),
}), nil
return agent.ResultJSON(
downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot read PDF: %s", err),
},
), nil
}
// Extract content to output dir.
outDir := filepath.Join(tmpDir, "out")
if err := os.MkdirAll(outDir, 0o700); err != nil {
return agent.ResultJSON(downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot create output dir: %s", err),
}), nil
return agent.ResultJSON(
downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot create output dir: %s", err),
},
), nil
}
reader := bytes.NewReader(body)
if err := api.ExtractContent(reader, outDir, "content", nil, conf); err != nil {
return agent.ResultJSON(downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot extract PDF content: %s", err),
}), nil
return agent.ResultJSON(
downloadPDFResult{
ErrorDetail: fmt.Sprintf("cannot extract PDF content: %s", err),
},
), nil
}
// Read all extracted content files.
@@ -154,10 +174,12 @@ func DownloadPDFTool() agent.Tool {
text = text[:maxTextLength] + "\n[... truncated]"
}
return agent.ResultJSON(downloadPDFResult{
Text: text,
PageCount: pageCount,
}), nil
return agent.ResultJSON(
downloadPDFResult{
Text: text,
PageCount: pageCount,
},
), nil
},
)
}

View File

@@ -19,6 +19,7 @@ import (
"context"
"fmt"
"net/http"
"net/url"
"strings"
"time"
@@ -46,37 +47,49 @@ func FetchRobotsTxtTool() agent.Tool {
"Fetch and parse the robots.txt file for a domain. Returns sitemap URLs and disallowed paths, which can reveal hidden pages the crawler might miss.",
func(ctx context.Context, p robotsParams) (agent.ToolResult, error) {
if err := validatePublicDomain(p.Domain); err != nil {
return agent.ResultJSON(robotsResult{
Found: false,
ErrorDetail: fmt.Sprintf("domain not allowed: %s", err),
}), nil
return agent.ResultJSON(
robotsResult{
Found: false,
ErrorDetail: fmt.Sprintf("domain not allowed: %s", err),
},
), nil
}
u := "https://" + p.Domain + "/robots.txt"
u := &url.URL{
Scheme: "https",
Host: p.Domain,
Path: "/robots.txt",
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
if err != nil {
return agent.ResultJSON(robotsResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot create request: %s", err),
}), nil
return agent.ResultJSON(
robotsResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot create request: %s", err),
},
), nil
}
resp, err := client.Do(req)
if err != nil {
return agent.ResultJSON(robotsResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot fetch robots.txt: %s", err),
}), nil
return agent.ResultJSON(
robotsResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot fetch robots.txt: %s", err),
},
), nil
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return agent.ResultJSON(robotsResult{
Found: false,
ErrorDetail: fmt.Sprintf("robots.txt returned status %d", resp.StatusCode),
}), nil
return agent.ResultJSON(
robotsResult{
Found: false,
ErrorDetail: fmt.Sprintf("robots.txt returned status %d", resp.StatusCode),
},
), nil
}
var result robotsResult

View File

@@ -52,35 +52,43 @@ func FetchSitemapTool() agent.Tool {
"Fetch and parse a sitemap XML file. Returns discovered URLs which can reveal pages not linked from the main navigation (trust centers, legal docs, status pages).",
func(ctx context.Context, p sitemapParams) (agent.ToolResult, error) {
if err := validatePublicURL(p.URL); err != nil {
return agent.ResultJSON(sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("URL not allowed: %s", err),
}), nil
return agent.ResultJSON(
sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("URL not allowed: %s", err),
},
), nil
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, p.URL, nil)
if err != nil {
return agent.ResultJSON(sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot create request: %s", err),
}), nil
return agent.ResultJSON(
sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot create request: %s", err),
},
), nil
}
resp, err := client.Do(req)
if err != nil {
return agent.ResultJSON(sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot fetch sitemap: %s", err),
}), nil
return agent.ResultJSON(
sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot fetch sitemap: %s", err),
},
), nil
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return agent.ResultJSON(sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("sitemap returned status %d", resp.StatusCode),
}), nil
return agent.ResultJSON(
sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("sitemap returned status %d", resp.StatusCode),
},
), nil
}
var reader io.Reader = resp.Body
@@ -88,10 +96,12 @@ func FetchSitemapTool() agent.Tool {
resp.Header.Get("Content-Encoding") == "gzip" {
gz, err := gzip.NewReader(resp.Body)
if err != nil {
return agent.ResultJSON(sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot decompress gzipped sitemap: %s", err),
}), nil
return agent.ResultJSON(
sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot decompress gzipped sitemap: %s", err),
},
), nil
}
defer func() { _ = gz.Close() }()
@@ -104,10 +114,12 @@ func FetchSitemapTool() agent.Tool {
urls, err := parseSitemapXML(reader)
if err != nil {
return agent.ResultJSON(sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot parse sitemap XML: %s", err),
}), nil
return agent.ResultJSON(
sitemapResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot parse sitemap XML: %s", err),
},
), nil
}
result := sitemapResult{

View File

@@ -80,11 +80,13 @@ func NavigateToURLTool(b *Browser) agent.Tool {
return agent.ResultError(b.classifyError(ctx, p.URL, err)), nil
}
return agent.ResultJSON(navigateResult{
Title: title,
Description: description,
FinalURL: finalURL,
}), nil
return agent.ResultJSON(
navigateResult{
Title: title,
Description: description,
FinalURL: finalURL,
},
), nil
},
)
}

View File

@@ -64,10 +64,12 @@ func DiffDocumentsTool() agent.Tool {
diff := computeDiff(linesA, linesB, labelA, labelB)
if diff.tooLarge {
return agent.ResultJSON(diffResult{
HasDifferences: true,
ErrorDetail: diff.output,
}), nil
return agent.ResultJSON(
diffResult{
HasDifferences: true,
ErrorDetail: diff.output,
},
), nil
}
result := diffResult{

View File

@@ -65,9 +65,17 @@ func CheckWaybackTool() agent.Tool {
var result waybackResult
// Check availability.
availURL := "https://archive.org/wayback/available?url=" + url.QueryEscape(p.URL)
availURL, err := url.Parse("https://archive.org/wayback/available")
if err != nil {
result.ErrorDetail = fmt.Sprintf("cannot parse Wayback Machine URL: %s", err)
return agent.ResultJSON(result), nil
}
body, err := httpGet(ctx, client, availURL)
q := availURL.Query()
q.Set("url", p.URL)
availURL.RawQuery = q.Encode()
body, err := httpGet(ctx, client, availURL.String())
if err != nil {
result.ErrorDetail = fmt.Sprintf("cannot check Wayback Machine availability: %s", err)
return agent.ResultJSON(result), nil

View File

@@ -68,9 +68,11 @@ func CheckCORSTool() agent.Tool {
"Send a CORS preflight (OPTIONS) request to a URL with a given Origin and analyze the Access-Control-* response headers, flagging wildcard origins and origin reflection.",
func(ctx context.Context, p corsParams) (agent.ToolResult, error) {
if err := netcheck.ValidatePublicURL(p.URL); err != nil {
return agent.ResultJSON(corsResult{
ErrorDetail: fmt.Sprintf("URL not allowed: %s", err),
}), nil
return agent.ResultJSON(
corsResult{
ErrorDetail: fmt.Sprintf("URL not allowed: %s", err),
},
), nil
}
client := &http.Client{
@@ -87,9 +89,11 @@ func CheckCORSTool() agent.Tool {
nil,
)
if err != nil {
return agent.ResultJSON(corsResult{
ErrorDetail: fmt.Sprintf("cannot build request: %s", err),
}), nil
return agent.ResultJSON(
corsResult{
ErrorDetail: fmt.Sprintf("cannot build request: %s", err),
},
), nil
}
req.Header.Set("Origin", p.Origin)
@@ -97,9 +101,11 @@ func CheckCORSTool() agent.Tool {
resp, err := client.Do(req)
if err != nil {
return agent.ResultJSON(corsResult{
ErrorDetail: fmt.Sprintf("cannot fetch %s: %s", p.URL, err),
}), nil
return agent.ResultJSON(
corsResult{
ErrorDetail: fmt.Sprintf("cannot fetch %s: %s", p.URL, err),
},
), nil
}
defer func() { _ = resp.Body.Close() }()

View File

@@ -81,16 +81,20 @@ func AnalyzeCSPTool() agent.Tool {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, p.URL, nil)
if err != nil {
return agent.ResultJSON(cspResult{
ErrorDetail: fmt.Sprintf("cannot create request for %s: %s", p.URL, err),
}), nil
return agent.ResultJSON(
cspResult{
ErrorDetail: fmt.Sprintf("cannot create request for %s: %s", p.URL, err),
},
), nil
}
resp, err := client.Do(req)
if err != nil {
return agent.ResultJSON(cspResult{
ErrorDetail: fmt.Sprintf("cannot fetch %s: %s", p.URL, err),
}), nil
return agent.ResultJSON(
cspResult{
ErrorDetail: fmt.Sprintf("cannot fetch %s: %s", p.URL, err),
},
), nil
}
defer func() { _ = resp.Body.Close() }()

View File

@@ -73,10 +73,12 @@ func CheckDMARCTool() agent.Tool {
},
)
if err != nil {
return agent.ResultJSON(dmarcResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot lookup DMARC record: %s", err),
}), nil
return agent.ResultJSON(
dmarcResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot lookup DMARC record: %s", err),
},
), nil
}
for _, answer := range answers {

View File

@@ -61,10 +61,12 @@ func CheckDNSSECTool() agent.Tool {
withDNSSEC(),
)
if err != nil {
return agent.ResultJSON(dnssecResult{
Enabled: false,
ErrorDetail: fmt.Sprintf("cannot query DNSKEY records: %s", err),
}), nil
return agent.ResultJSON(
dnssecResult{
Enabled: false,
ErrorDetail: fmt.Sprintf("cannot query DNSKEY records: %s", err),
},
), nil
}
var (

View File

@@ -18,6 +18,7 @@ import (
"context"
"fmt"
"net/http"
"net/url"
"strings"
"time"
@@ -79,9 +80,11 @@ func CheckSecurityHeadersTool() agent.Tool {
"Check security-related HTTP headers for a URL (HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, Cross-Origin-*-Policy). Also checks if HTTP redirects to HTTPS.",
func(ctx context.Context, p headersParams) (agent.ToolResult, error) {
if err := netcheck.ValidatePublicURL(p.URL); err != nil {
return agent.ResultJSON(headersResult{
ErrorDetail: fmt.Sprintf("URL not allowed: %s", err),
}), nil
return agent.ResultJSON(
headersResult{
ErrorDetail: fmt.Sprintf("URL not allowed: %s", err),
},
), nil
}
client := &http.Client{
@@ -94,11 +97,19 @@ func CheckSecurityHeadersTool() agent.Tool {
// First check the HTTP version to detect HTTP→HTTPS redirect.
redirectsToHTTPS := false
httpURL := p.URL
if after, ok := strings.CutPrefix(httpURL, "https://"); ok {
httpURL = "http://" + after
parsedURL, err := url.Parse(p.URL)
if err != nil {
return agent.ResultJSON(
headersResult{
ErrorDetail: fmt.Sprintf("cannot parse URL: %s", err),
},
), nil
}
httpParsed := *parsedURL
httpParsed.Scheme = "http"
httpURL := httpParsed.String()
httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, httpURL, nil)
if err == nil {
httpResp, err := client.Do(httpReq)
@@ -114,25 +125,28 @@ func CheckSecurityHeadersTool() agent.Tool {
}
// Now check the HTTPS version for the actual security headers.
httpsURL := p.URL
if after, ok := strings.CutPrefix(httpsURL, "http://"); ok {
httpsURL = "https://" + after
}
httpsParsed := *parsedURL
httpsParsed.Scheme = "https"
httpsURL := httpsParsed.String()
followClient := &http.Client{Timeout: 10 * time.Second}
httpsReq, err := http.NewRequestWithContext(ctx, http.MethodGet, httpsURL, nil)
if err != nil {
return agent.ResultJSON(headersResult{
ErrorDetail: fmt.Sprintf("cannot create request for %s: %s", httpsURL, err),
}), nil
return agent.ResultJSON(
headersResult{
ErrorDetail: fmt.Sprintf("cannot create request for %s: %s", httpsURL, err),
},
), nil
}
resp, err := followClient.Do(httpsReq)
if err != nil {
return agent.ResultJSON(headersResult{
ErrorDetail: fmt.Sprintf("cannot fetch %s: %s", httpsURL, err),
}), nil
return agent.ResultJSON(
headersResult{
ErrorDetail: fmt.Sprintf("cannot fetch %s: %s", httpsURL, err),
},
), nil
}
defer func() { _ = resp.Body.Close() }()

View File

@@ -61,34 +61,48 @@ func CheckBreachesTool() agent.Tool {
func(ctx context.Context, p hibpParams) (agent.ToolResult, error) {
client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequestWithContext(
ctx,
http.MethodGet,
"https://haveibeenpwned.com/api/v3/breaches?domain="+url.QueryEscape(p.Domain),
nil,
)
hibpURL, err := url.Parse("https://haveibeenpwned.com/api/v3/breaches")
if err != nil {
return agent.ResultJSON(hibpResult{
ErrorDetail: fmt.Sprintf("cannot create request: %s", err),
}), nil
return agent.ResultJSON(
hibpResult{
ErrorDetail: fmt.Sprintf("cannot parse HIBP URL: %s", err),
},
), nil
}
q := hibpURL.Query()
q.Set("domain", p.Domain)
hibpURL.RawQuery = q.Encode()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, hibpURL.String(), nil)
if err != nil {
return agent.ResultJSON(
hibpResult{
ErrorDetail: fmt.Sprintf("cannot create request: %s", err),
},
), nil
}
req.Header.Set("User-Agent", "Probo-Vendor-Assessment")
resp, err := client.Do(req)
if err != nil {
return agent.ResultJSON(hibpResult{
ErrorDetail: fmt.Sprintf("cannot fetch breaches: %s", err),
}), nil
return agent.ResultJSON(
hibpResult{
ErrorDetail: fmt.Sprintf("cannot fetch breaches: %s", err),
},
), nil
}
defer func() { _ = resp.Body.Close() }()
body, err := io.ReadAll(resp.Body)
if err != nil {
return agent.ResultJSON(hibpResult{
ErrorDetail: fmt.Sprintf("cannot read response: %s", err),
}), nil
return agent.ResultJSON(
hibpResult{
ErrorDetail: fmt.Sprintf("cannot read response: %s", err),
},
), nil
}
if resp.StatusCode == http.StatusNotFound {
@@ -96,23 +110,29 @@ func CheckBreachesTool() agent.Tool {
}
if resp.StatusCode != http.StatusOK {
return agent.ResultJSON(hibpResult{
ErrorDetail: fmt.Sprintf("HIBP API returned status %d", resp.StatusCode),
}), nil
return agent.ResultJSON(
hibpResult{
ErrorDetail: fmt.Sprintf("HIBP API returned status %d", resp.StatusCode),
},
), nil
}
var breaches []breach
if err := json.Unmarshal(body, &breaches); err != nil {
return agent.ResultJSON(hibpResult{
ErrorDetail: fmt.Sprintf("cannot parse response: %s", err),
}), nil
return agent.ResultJSON(
hibpResult{
ErrorDetail: fmt.Sprintf("cannot parse response: %s", err),
},
), nil
}
return agent.ResultJSON(hibpResult{
Found: len(breaches) > 0,
Count: len(breaches),
Breaches: breaches,
}), nil
return agent.ResultJSON(
hibpResult{
Found: len(breaches) > 0,
Count: len(breaches),
Breaches: breaches,
},
), nil
},
)
}

View File

@@ -77,10 +77,12 @@ func CheckSPFTool() agent.Tool {
},
)
if err != nil {
return agent.ResultJSON(spfResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot lookup SPF record: %s", err),
}), nil
return agent.ResultJSON(
spfResult{
Found: false,
ErrorDetail: fmt.Sprintf("cannot lookup SPF record: %s", err),
},
), nil
}
var spfRecords []string
@@ -100,21 +102,25 @@ func CheckSPFTool() agent.Tool {
}
if len(spfRecords) > 1 {
return agent.ResultJSON(spfResult{
Found: true,
ErrorDetail: fmt.Sprintf("multiple SPF records found (%d); this is an invalid configuration per RFC 7208", len(spfRecords)),
}), nil
return agent.ResultJSON(
spfResult{
Found: true,
ErrorDetail: fmt.Sprintf("multiple SPF records found (%d); this is an invalid configuration per RFC 7208", len(spfRecords)),
},
), nil
}
if len(spfRecords) == 1 {
record := spfRecords[0]
return agent.ResultJSON(spfResult{
Found: true,
RawRecord: record,
Policy: parseSPFPolicy(record),
Mechanisms: record,
}), nil
return agent.ResultJSON(
spfResult{
Found: true,
RawRecord: record,
Policy: parseSPFPolicy(record),
Mechanisms: record,
},
), nil
}
return agent.ResultJSON(spfResult{Found: false}), nil

View File

@@ -66,10 +66,12 @@ func CheckSSLCertificateTool() agent.Tool {
"Check the SSL/TLS certificate for a domain, returning issuer, expiry, protocol version, and validity.",
func(ctx context.Context, p sslParams) (agent.ToolResult, error) {
if err := netcheck.ValidatePublicDomain(p.Domain); err != nil {
return agent.ResultJSON(sslResult{
Valid: false,
ErrorDetail: fmt.Sprintf("domain not allowed: %s", err),
}), nil
return agent.ResultJSON(
sslResult{
Valid: false,
ErrorDetail: fmt.Sprintf("domain not allowed: %s", err),
},
), nil
}
// This is a certificate inspection tool: we intentionally
@@ -96,20 +98,24 @@ func CheckSSLCertificateTool() agent.Tool {
}
if err != nil {
return agent.ResultJSON(sslResult{
Valid: false,
ErrorDetail: err.Error(),
}), nil
return agent.ResultJSON(
sslResult{
Valid: false,
ErrorDetail: err.Error(),
},
), nil
}
defer func() { _ = conn.Close() }()
state := conn.ConnectionState()
if len(state.PeerCertificates) == 0 {
return agent.ResultJSON(sslResult{
Valid: false,
ErrorDetail: "no peer certificates",
}), nil
return agent.ResultJSON(
sslResult{
Valid: false,
ErrorDetail: "no peer certificates",
},
), nil
}
cert := state.PeerCertificates[0]

View File

@@ -50,17 +50,21 @@ func CheckWhoisTool() agent.Tool {
"Perform a WHOIS lookup on a domain to retrieve registration details including registrar, creation date, expiry date, registrant organization, and name servers.",
func(ctx context.Context, p whoisParams) (agent.ToolResult, error) {
if err := netcheck.ValidatePublicDomain(p.Domain); err != nil {
return agent.ResultJSON(whoisResult{
ErrorDetail: fmt.Sprintf("domain not allowed: %s", err),
}), nil
return agent.ResultJSON(
whoisResult{
ErrorDetail: fmt.Sprintf("domain not allowed: %s", err),
},
), nil
}
// Step 1: query IANA to find the referral WHOIS server.
referral, err := queryWhois(ctx, "whois.iana.org:43", p.Domain)
if err != nil {
return agent.ResultJSON(whoisResult{
ErrorDetail: fmt.Sprintf("cannot query IANA WHOIS: %s", err),
}), nil
return agent.ResultJSON(
whoisResult{
ErrorDetail: fmt.Sprintf("cannot query IANA WHOIS: %s", err),
},
), nil
}
whoisServer := parseWhoisField(referral, "refer")
@@ -87,17 +91,21 @@ func CheckWhoisTool() agent.Tool {
}
if err := netcheck.ValidatePublicDomain(whoisHost); err != nil {
return agent.ResultJSON(whoisResult{
ErrorDetail: fmt.Sprintf("WHOIS referral server not allowed: %s", err),
}), nil
return agent.ResultJSON(
whoisResult{
ErrorDetail: fmt.Sprintf("WHOIS referral server not allowed: %s", err),
},
), nil
}
// Step 2: query the registrar's WHOIS server.
raw, err := queryWhois(ctx, whoisServer, p.Domain)
if err != nil {
return agent.ResultJSON(whoisResult{
ErrorDetail: fmt.Sprintf("cannot query WHOIS server %s: %s", whoisServer, err),
}), nil
return agent.ResultJSON(
whoisResult{
ErrorDetail: fmt.Sprintf("cannot query WHOIS server %s: %s", whoisServer, err),
},
), nil
}
result := parseWhoisResponse(raw)