Use a ReadSeeker for upload content and rewind the offset on retries
diff --git a/provider_client.go b/provider_client.go
index 0dff2cf..e5b75b2 100644
--- a/provider_client.go
+++ b/provider_client.go
@@ -85,9 +85,9 @@
// content type of the request will default to "application/json" unless overridden by MoreHeaders.
// It's an error to specify both a JSONBody and a RawBody.
JSONBody interface{}
- // RawBody contains an io.Reader that will be consumed by the request directly. No content-type
+ // RawBody contains an io.ReadSeeker that will be consumed by the request directly. No content-type
// will be set unless one is provided explicitly by MoreHeaders.
- RawBody io.Reader
+ RawBody io.ReadSeeker
// JSONResponse, if provided, will be populated with the contents of the response body parsed as
// JSON.
@@ -124,11 +124,11 @@
// Request performs an HTTP request using the ProviderClient's current HTTPClient. An authentication
// header will automatically be provided.
func (client *ProviderClient) Request(method, url string, options RequestOpts) (*http.Response, error) {
- var body io.Reader
+ var body io.ReadSeeker
var contentType *string
// Derive the content body by either encoding an arbitrary object as JSON, or by taking a provided
- // io.Reader as-is. Default the content-type to application/json.
+ // io.ReadSeeker as-is. Default the content-type to application/json.
if options.JSONBody != nil {
if options.RawBody != nil {
panic("Please provide only one of JSONBody or RawBody to gophercloud.Request().")
@@ -189,6 +189,7 @@
if err != nil {
return nil, fmt.Errorf("Error trying to re-authenticate: %s", err)
}
+ options.RawBody.Seek(0, 0)
resp, err = client.Request(method, url, options)
if err != nil {
return nil, fmt.Errorf("Successfully re-authenticated, but got error executing request: %s", err)
@@ -260,7 +261,7 @@
opts = &RequestOpts{}
}
- if v, ok := (JSONBody).(io.Reader); ok {
+ if v, ok := (JSONBody).(io.ReadSeeker); ok {
opts.RawBody = v
} else if JSONBody != nil {
opts.JSONBody = JSONBody
@@ -278,7 +279,7 @@
opts = &RequestOpts{}
}
- if v, ok := (JSONBody).(io.Reader); ok {
+ if v, ok := (JSONBody).(io.ReadSeeker); ok {
opts.RawBody = v
} else if JSONBody != nil {
opts.JSONBody = JSONBody