Skip to content

🐛 Fix some (rare) errors while uploading files#17

Merged
HanXHX merged 2 commits intomasterfrom
api_calls
Mar 12, 2026
Merged

🐛 Fix some (rare) errors while uploading files#17
HanXHX merged 2 commits intomasterfrom
api_calls

Conversation

@HanXHX
Copy link
Copy Markdown
Contributor

@HanXHX HanXHX commented Mar 12, 2026

  • Refresh OIDC token when expired while uploading
  • Increase HTTP timeouts

Copilot AI review requested due to automatic review settings March 12, 2026 13:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to reduce rare upload failures by (1) refreshing OIDC access tokens during long-running transfers and (2) adjusting HTTP timeout behavior to better accommodate large uploads.

Changes:

  • Introduce an oauth2.TokenSource wrapper that refreshes expired access tokens (optionally persisting refreshed tokens to disk).
  • Update the API client to accept a TokenSource (instead of a static token) and adjust transport-level timeouts while removing the client-wide timeout.
  • Update the transfer command flow to pass a refreshing token source into the API client.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
internal/auth/oidc.go Adds a concurrency-safe refreshing TokenSource with optional on-disk persistence.
internal/api/client.go Switches client auth to use a TokenSource and changes timeout strategy for long uploads.
cmd/transfer.go Returns/passes a refreshing TokenSource instead of a single token for transfer operations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread internal/api/client.go
Comment on lines +74 to 80
// No client-level Timeout: that field caps the entire round-trip
// (including body upload), which would kill large chunk uploads on
// slow connections. Transport-level timeouts above protect against
// hung connections and unresponsive servers instead.
httpClient: &http.Client{
Timeout: 30 * time.Second,
Transport: transport,
},
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the http.Client Timeout eliminates an upper bound on the total request time. With callers frequently using context.Background(), a stalled upload/download (e.g., server stops reading request body or response body never completes) can now hang indefinitely; ResponseHeaderTimeout only covers waiting for headers after the request is written. Consider adding a generous but finite default via per-request contexts (or an option/config flag) so large uploads aren’t killed, but truly stuck transfers eventually fail.

Copilot uses AI. Check for mistakes.
Comment thread internal/auth/oidc.go
Comment on lines +287 to +294
func NewRefreshingTokenSource(
tok *oauth2.Token,
cfg config.OIDCConfig,
httpClient *http.Client,
persist bool,
) oauth2.TokenSource {
return &RefreshingTokenSource{tok: tok, cfg: cfg, httpClient: httpClient, persist: persist}
}
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NewRefreshingTokenSource accepts a *oauth2.Token but neither the constructor nor Token() guard against tok being nil. As written, Token() will panic on s.tok.Valid() if a nil token is passed (this is an exported API, so it’s worth making it robust). Consider validating inputs in NewRefreshingTokenSource (or returning an error) and/or returning a clear error from Token() when s.tok is nil.

Copilot uses AI. Check for mistakes.
Comment thread internal/auth/oidc.go Outdated
return nil, ErrNoRefreshToken
}

newTok, err := Refresh(context.Background(), s.cfg, s.tok.RefreshToken, s.httpClient)
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RefreshingTokenSource.Token() refreshes using context.Background(), and Refresh currently does not attach the provided context to the HTTP request (it uses httpClient.PostForm). This means refresh can’t be canceled and may hang longer than the calling request’s context. Consider updating Refresh to build an http.Request with context (Do(req)) and in Token() using a bounded context (e.g., WithTimeout) so refresh obeys cancellation/time limits.

Suggested change
newTok, err := Refresh(context.Background(), s.cfg, s.tok.RefreshToken, s.httpClient)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
newTok, err := Refresh(ctx, s.cfg, s.tok.RefreshToken, s.httpClient)

Copilot uses AI. Check for mistakes.
@HanXHX HanXHX merged commit f098738 into master Mar 12, 2026
4 checks passed
@HanXHX HanXHX deleted the api_calls branch March 12, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants