Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable optional Redirect Handling Support #2021

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,67 @@
r.lk.Unlock()
}

// Redirect requests by re signing the request.
func (c *Client) redirectHeaders(req *http.Request, via []*http.Request) error {
if len(via) >= 5 {
return errors.New("stopped after 5 redirects")
}
if len(via) == 0 {
return nil
}
lastRequest := via[len(via)-1]
var reAuth bool
for attr, val := range lastRequest.Header {
// if hosts do not match do not copy Authorization header
if attr == "Authorization" && req.Host != lastRequest.Host {
reAuth = true
continue
}
if _, ok := req.Header[attr]; !ok {
req.Header[attr] = val
}
}

*c.endpointURL = *req.URL

value, err := c.credsProvider.Get()
if err != nil {
return err
}
var (
signerType = value.SignerType
accessKeyID = value.AccessKeyID
secretAccessKey = value.SecretAccessKey
sessionToken = value.SessionToken
region = c.region
)

// Custom signer set then override the behavior.
if c.overrideSignerType != credentials.SignatureDefault {
signerType = c.overrideSignerType
}

// If signerType returned by credentials helper is anonymous,
// then do not sign regardless of signerType override.
if value.SignerType == credentials.SignatureAnonymous {
signerType = credentials.SignatureAnonymous
}

if reAuth {
// Check if there is no region override, if not get it from the URL if possible.
if region == "" {
region = s3utils.GetRegionFromURL(*c.endpointURL)
}
switch {
case signerType.IsV2():
return errors.New("signature V2 cannot support redirection")
case signerType.IsV4():
signer.SignV4(*req, accessKeyID, secretAccessKey, sessionToken, getDefaultLocation(*c.endpointURL, region))
}
}
return nil
}

func privateNew(endpoint string, opts *Options) (*Client, error) {
// construct endpoint.
endpointURL, err := getEndpointURL(endpoint, opts.Secure)
Expand Down Expand Up @@ -248,6 +309,10 @@
},
}

if envValue := os.Getenv("ENABLE_REDIRECT_HANDLING"); envValue == "true" {

Check failure on line 312 in api.go

View workflow job for this annotation

GitHub Actions / Test on Go 1.22.x and ubuntu-latest

File is not `goimports`-ed (goimports)

Check failure on line 312 in api.go

View workflow job for this annotation

GitHub Actions / Test on Go 1.23.x and ubuntu-latest

File is not `goimports`-ed (goimports)
clnt.httpClient.CheckRedirect = clnt.redirectHeaders
}

Comment on lines +312 to +315
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't add env vars to a library. Add it to the Options.

// Sets custom region, if region is empty bucket location cache is used automatically.
if opts.Region == "" {
if opts.CustomRegionViaURL != nil {
Expand Down
Loading