mirror of
https://github.com/rclone/rclone.git
synced 2025-01-18 04:09:41 +01:00
rest: make auth preserving redirects an option
This commit is contained in:
parent
f6efaf2a63
commit
15ef3b90fa
@ -151,6 +151,7 @@ type Opts struct {
|
||||
NoRedirect bool // if this is set then the client won't follow redirects
|
||||
// On Redirects, call this function - see the http.Client docs: https://pkg.go.dev/net/http#Client
|
||||
CheckRedirect func(req *http.Request, via []*http.Request) error
|
||||
AuthRedirect bool // if this is set then the client will redirect with Auth
|
||||
}
|
||||
|
||||
// Copy creates a copy of the options
|
||||
@ -216,6 +217,34 @@ func (api *Client) Do(req *http.Request) (*http.Response, error) {
|
||||
return api.c.Do(req)
|
||||
}
|
||||
|
||||
// ClientWithAuthRedirects makes a new http client which will re-apply Auth on redirects
|
||||
func ClientWithAuthRedirects(c *http.Client) *http.Client {
|
||||
clientCopy := *c
|
||||
clientCopy.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||
if len(via) >= 10 {
|
||||
return errors.New("stopped after 10 redirects")
|
||||
} else if len(via) == 0 {
|
||||
return nil
|
||||
}
|
||||
prevReq := via[len(via)-1]
|
||||
resp := req.Response
|
||||
if resp == nil {
|
||||
return nil
|
||||
}
|
||||
// Look at previous response to see if it was a redirect and preserve auth if so
|
||||
switch resp.StatusCode {
|
||||
case http.StatusMovedPermanently, http.StatusFound, http.StatusSeeOther, http.StatusTemporaryRedirect, http.StatusPermanentRedirect:
|
||||
// Reapply Auth (if any) from previous request on redirect
|
||||
auth := prevReq.Header.Get("Authorization")
|
||||
if auth != "" {
|
||||
req.Header.Add("Authorization", auth)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return &clientCopy
|
||||
}
|
||||
|
||||
// Call makes the call and returns the http.Response
|
||||
//
|
||||
// if err == nil then resp.Body will need to be closed unless
|
||||
@ -310,6 +339,8 @@ func (api *Client) Call(ctx context.Context, opts *Opts) (resp *http.Response, e
|
||||
clientCopy := *api.c
|
||||
clientCopy.CheckRedirect = opts.CheckRedirect
|
||||
c = &clientCopy
|
||||
} else if opts.AuthRedirect {
|
||||
c = ClientWithAuthRedirects(api.c)
|
||||
} else {
|
||||
c = api.c
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user