use seeker when available on request
This commit is contained in:
parent
73a7f0bf37
commit
2f2cda4122
25
requests.go
25
requests.go
@ -10,15 +10,30 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *Client) req(method, path string, body io.Reader, intercept func(*http.Request)) (req *http.Response, err error) {
|
func (c *Client) req(method, path string, body io.Reader, intercept func(*http.Request)) (req *http.Response, err error) {
|
||||||
// Tee the body, because if authorization fails we will need to read from it again.
|
|
||||||
var r *http.Request
|
var r *http.Request
|
||||||
var ba bytes.Buffer
|
var retryBuf io.Reader
|
||||||
bb := io.TeeReader(body, &ba)
|
|
||||||
|
// If the authorization fails, we will need to restart reading
|
||||||
|
// from the passed body stream.
|
||||||
|
// When body is seekable, use seek to reset the streams
|
||||||
|
// cursor to the start.
|
||||||
|
// Otherwise, copy the stream into a buffer while uploading
|
||||||
|
// and use the buffers content on retry.
|
||||||
|
if sk, ok := body.(io.Seeker); ok {
|
||||||
|
if _, err = sk.Seek(0, io.SeekStart); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
retryBuf = body
|
||||||
|
} else {
|
||||||
|
buff := &bytes.Buffer{}
|
||||||
|
retryBuf = buff
|
||||||
|
body = io.TeeReader(body, buff)
|
||||||
|
}
|
||||||
|
|
||||||
if body == nil {
|
if body == nil {
|
||||||
r, err = http.NewRequest(method, PathEscape(Join(c.root, path)), nil)
|
r, err = http.NewRequest(method, PathEscape(Join(c.root, path)), nil)
|
||||||
} else {
|
} else {
|
||||||
r, err = http.NewRequest(method, PathEscape(Join(c.root, path)), bb)
|
r, err = http.NewRequest(method, PathEscape(Join(c.root, path)), body)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -70,7 +85,7 @@ func (c *Client) req(method, path string, body io.Reader, intercept func(*http.R
|
|||||||
if body == nil {
|
if body == nil {
|
||||||
return c.req(method, path, nil, intercept)
|
return c.req(method, path, nil, intercept)
|
||||||
} else {
|
} else {
|
||||||
return c.req(method, path, &ba, intercept)
|
return c.req(method, path, retryBuf, intercept)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if rs.StatusCode == 401 {
|
} else if rs.StatusCode == 401 {
|
||||||
|
Loading…
Reference in New Issue
Block a user