fix: Honor HTTP client timeouts in redirects - #4585
sb123sb123 wants to merge 1 commit into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
7ca717a to
5985a00
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #4585 +/- ##
=======================================
Coverage 98.59% 98.59%
=======================================
Files 197 197
Lines 18326 18323 -3
=======================================
- Hits 18068 18066 -2
+ Misses 258 257 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
gmlewis
left a comment
There was a problem hiding this comment.
Thanks for the diagnosis - the missing timeout needs to be addressed, but not in the manner that you are proposing, because this implementation causes 3 more issues:
- Transport errors are now wrapped in *url.Error, so err == mySentinel, error types, and error strings all change.
- Do attaches the client's http.CookieJar: these requests now send jar cookies and write response Set-Cookie values into the shared jar.
- Do parses Location before our checkRedirectHost gets to run, so an unparseable Location now returns (nil, err) instead of the redirect response and callers lose the *Response.
I believe the safer approach is to revert the changes you made and add the following BEFORE line 2381:
if t := c.client.Timeout; t > 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, t)
defer cancel()
}Also, please move your new test to github/github_test.go instead of making a new file.
And finally, please do not use time.Sleep in any unit tests - look at the other examples and take advantage of synctest and other testutils to make the unit test independent of time, for when these tests are run on extremely slow runners.
Once you fix the CLA issues, we can move forward with this PR.
Fixes #4584
Cause
roundTripWithOptionalFollowRedirectcalled the configured transport'sRoundTripmethod directly. That preserves access to 301/302 responses, but bypasseshttp.Client.Do, so the configuredhttp.Client.Timeoutwas never applied to these redirect-aware requests.Fix
Use the existing no-redirect
http.Clientfor the request. It shares the configured transport and timeout and returns the first redirect response because itsCheckRedirectreturnshttp.ErrUseLastResponse; the existing redirect and host checks remain unchanged.Tests
go test -modfile=go.test.mod ./github -run 'Test(RoundTripWithOptionalFollowRedirect|ActionsService_DownloadArtifact|ActionsService_GetWorkflowJobLogs|ActionsService_GetWorkflowRun.*Logs|RepositoriesService_GetArchiveLink|RepositoriesService_GetBranch)' -count=1go test -modfile=go.test.mod ./... -count=1go test -v -tags=integration -run='^$' -modfile=go.test.mod ./test/integrationgo vet -modfile=go.test.mod ./...gofmt -d github/github.go github/github_timeout_test.gogit diff --checkThe temporary
go.test.modused an uncommitted local replacement forgithub.com/google/go-querystringbecause this Windows host could not reachproxy.golang.org; it was removed after each run.Limitations
The required repository-wide race run was attempted, but this host has
CGO_ENABLED=0and no available C compiler. The all-module non-race script, custom linter bootstrap, generated-file check, schema check, and OpenAPI validation were also attempted; external module/TLS downloads and the custom-linter installer were unavailable on this host. The logs are retained under/g/OSS-PR-200/work/evidence.AI assistance was used to investigate, reproduce, implement, test, and prepare this PR. I reviewed the complete diff and the reported test results; the change is intentionally limited to the timeout behavior and its regression test.