mirror of https://github.com/rclone/rclone.git
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
|
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
|
// 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
|
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
|
// 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)
|
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
|
// Call makes the call and returns the http.Response
|
||||||
//
|
//
|
||||||
// if err == nil then resp.Body will need to be closed unless
|
// 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 := *api.c
|
||||||
clientCopy.CheckRedirect = opts.CheckRedirect
|
clientCopy.CheckRedirect = opts.CheckRedirect
|
||||||
c = &clientCopy
|
c = &clientCopy
|
||||||
|
} else if opts.AuthRedirect {
|
||||||
|
c = ClientWithAuthRedirects(api.c)
|
||||||
} else {
|
} else {
|
||||||
c = api.c
|
c = api.c
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue