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