Compare commits
3 commits
1f0372e15b
...
504003c47e
| Author | SHA1 | Date | |
|---|---|---|---|
| 504003c47e | |||
|
|
1cecf00148 | ||
|
|
ec1a591b71 |
2 changed files with 28 additions and 8 deletions
19
client.go
19
client.go
|
|
@ -144,7 +144,7 @@ func (a *APIClient) Do(req *http.Request, result any) error {
|
||||||
|
|
||||||
// Server errors are retryable.
|
// Server errors are retryable.
|
||||||
if resp.StatusCode >= 500 {
|
if resp.StatusCode >= 500 {
|
||||||
lastErr = coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, string(data)), nil)
|
lastErr = coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, truncateBody(data, maxErrBodyLen)), nil)
|
||||||
if attempt < attempts-1 {
|
if attempt < attempts-1 {
|
||||||
a.backoff(attempt, req)
|
a.backoff(attempt, req)
|
||||||
}
|
}
|
||||||
|
|
@ -153,7 +153,7 @@ func (a *APIClient) Do(req *http.Request, result any) error {
|
||||||
|
|
||||||
// Client errors (4xx, except 429 handled above) are not retried.
|
// Client errors (4xx, except 429 handled above) are not retried.
|
||||||
if resp.StatusCode >= 400 {
|
if resp.StatusCode >= 400 {
|
||||||
return coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, string(data)), nil)
|
return coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, truncateBody(data, maxErrBodyLen)), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Success — decode if requested.
|
// Success — decode if requested.
|
||||||
|
|
@ -228,7 +228,7 @@ func (a *APIClient) DoRaw(req *http.Request) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode >= 500 {
|
if resp.StatusCode >= 500 {
|
||||||
lastErr = coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, string(data)), nil)
|
lastErr = coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, truncateBody(data, maxErrBodyLen)), nil)
|
||||||
if attempt < attempts-1 {
|
if attempt < attempts-1 {
|
||||||
a.backoff(attempt, req)
|
a.backoff(attempt, req)
|
||||||
}
|
}
|
||||||
|
|
@ -236,7 +236,7 @@ func (a *APIClient) DoRaw(req *http.Request) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode >= 400 {
|
if resp.StatusCode >= 400 {
|
||||||
return nil, coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, string(data)), nil)
|
return nil, coreerr.E(a.prefix, fmt.Sprintf("HTTP %d: %s", resp.StatusCode, truncateBody(data, maxErrBodyLen)), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return data, nil
|
return data, nil
|
||||||
|
|
@ -261,6 +261,17 @@ func (a *APIClient) backoff(attempt int, req *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// maxErrBodyLen is the maximum number of bytes from a response body included in error messages.
|
||||||
|
const maxErrBodyLen = 256
|
||||||
|
|
||||||
|
// truncateBody limits response body length in error messages to prevent sensitive data leakage.
|
||||||
|
func truncateBody(data []byte, max int) string {
|
||||||
|
if len(data) <= max {
|
||||||
|
return string(data)
|
||||||
|
}
|
||||||
|
return string(data[:max]) + "...(truncated)"
|
||||||
|
}
|
||||||
|
|
||||||
// parseRetryAfter interprets the Retry-After header value.
|
// parseRetryAfter interprets the Retry-After header value.
|
||||||
// Supports seconds (integer) format. Falls back to 1 second.
|
// Supports seconds (integer) format. Falls back to 1 second.
|
||||||
func parseRetryAfter(val string) time.Duration {
|
func parseRetryAfter(val string) time.Duration {
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ func resolveRepos() ([]string, error) {
|
||||||
func fetchRepoFindings(repoFullName string) ([]Finding, []string) {
|
func fetchRepoFindings(repoFullName string) ([]Finding, []string) {
|
||||||
var findings []Finding
|
var findings []Finding
|
||||||
var errs []string
|
var errs []string
|
||||||
repoName := strings.Split(repoFullName, "/")[1]
|
repoName := repoShortName(repoFullName)
|
||||||
|
|
||||||
// Fetch code scanning alerts
|
// Fetch code scanning alerts
|
||||||
codeFindings, err := fetchCodeScanningAlerts(repoFullName)
|
codeFindings, err := fetchCodeScanningAlerts(repoFullName)
|
||||||
|
|
@ -264,7 +264,7 @@ func fetchCodeScanningAlerts(repoFullName string) ([]Finding, error) {
|
||||||
return nil, log.E("monitor.fetchCodeScanning", "failed to parse response", err)
|
return nil, log.E("monitor.fetchCodeScanning", "failed to parse response", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
repoName := strings.Split(repoFullName, "/")[1]
|
repoName := repoShortName(repoFullName)
|
||||||
var findings []Finding
|
var findings []Finding
|
||||||
for _, alert := range alerts {
|
for _, alert := range alerts {
|
||||||
if alert.State != "open" {
|
if alert.State != "open" {
|
||||||
|
|
@ -318,7 +318,7 @@ func fetchDependabotAlerts(repoFullName string) ([]Finding, error) {
|
||||||
return nil, log.E("monitor.fetchDependabot", "failed to parse response", err)
|
return nil, log.E("monitor.fetchDependabot", "failed to parse response", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
repoName := strings.Split(repoFullName, "/")[1]
|
repoName := repoShortName(repoFullName)
|
||||||
var findings []Finding
|
var findings []Finding
|
||||||
for _, alert := range alerts {
|
for _, alert := range alerts {
|
||||||
if alert.State != "open" {
|
if alert.State != "open" {
|
||||||
|
|
@ -369,7 +369,7 @@ func fetchSecretScanningAlerts(repoFullName string) ([]Finding, error) {
|
||||||
return nil, log.E("monitor.fetchSecretScanning", "failed to parse response", err)
|
return nil, log.E("monitor.fetchSecretScanning", "failed to parse response", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
repoName := strings.Split(repoFullName, "/")[1]
|
repoName := repoShortName(repoFullName)
|
||||||
var findings []Finding
|
var findings []Finding
|
||||||
for _, alert := range alerts {
|
for _, alert := range alerts {
|
||||||
if alert.State != "open" {
|
if alert.State != "open" {
|
||||||
|
|
@ -530,6 +530,15 @@ func outputTable(findings []Finding) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// repoShortName extracts the repo name from "org/repo" format.
|
||||||
|
// Returns the full string if no "/" is present.
|
||||||
|
func repoShortName(fullName string) string {
|
||||||
|
if i := strings.LastIndex(fullName, "/"); i >= 0 {
|
||||||
|
return fullName[i+1:]
|
||||||
|
}
|
||||||
|
return fullName
|
||||||
|
}
|
||||||
|
|
||||||
// truncate truncates a string to max runes (Unicode-safe)
|
// truncate truncates a string to max runes (Unicode-safe)
|
||||||
func truncate(s string, max int) string {
|
func truncate(s string, max int) string {
|
||||||
runes := []rune(s)
|
runes := []rune(s)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue