Merge pull request #274 from jamiehannaford/result-consistency

DeleteResult consistency
diff --git a/openstack/objectstorage/v1/objects/requests.go b/openstack/objectstorage/v1/objects/requests.go
index 59ea81f..f5ca296 100644
--- a/openstack/objectstorage/v1/objects/requests.go
+++ b/openstack/objectstorage/v1/objects/requests.go
@@ -3,7 +3,6 @@
 import (
 	"fmt"
 	"io"
-	"io/ioutil"
 	"time"
 
 	"github.com/racker/perigee"
@@ -128,11 +127,11 @@
 		MoreHeaders: h,
 		OkCodes:     []int{200},
 	})
-	defer resp.HttpResponse.Body.Close()
-	body, err := ioutil.ReadAll(resp.HttpResponse.Body)
-	res.Body = body
+
+	res.Body = resp.HttpResponse.Body
 	res.Err = err
 	res.Header = resp.HttpResponse.Header
+
 	return res
 }
 
diff --git a/openstack/objectstorage/v1/objects/requests_test.go b/openstack/objectstorage/v1/objects/requests_test.go
index 7ab40f2..3935e1b 100644
--- a/openstack/objectstorage/v1/objects/requests_test.go
+++ b/openstack/objectstorage/v1/objects/requests_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"bytes"
+	"io"
 	"testing"
 
 	"github.com/rackspace/gophercloud/pagination"
@@ -9,14 +10,30 @@
 	fake "github.com/rackspace/gophercloud/testhelper/client"
 )
 
-func TestDownloadObject(t *testing.T) {
+func TestDownloadReader(t *testing.T) {
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
 	HandleDownloadObjectSuccessfully(t)
 
-	content, err := Download(fake.ServiceClient(), "testContainer", "testObject", nil).ExtractContent()
+	response := Download(fake.ServiceClient(), "testContainer", "testObject", nil)
+
+	// Check reader
+	buf := bytes.NewBuffer(make([]byte, 0))
+	io.CopyN(buf, response.Body, 10)
+	th.CheckEquals(t, "Successful", string(buf.Bytes()))
+}
+
+func TestDownloadExtraction(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleDownloadObjectSuccessfully(t)
+
+	response := Download(fake.ServiceClient(), "testContainer", "testObject", nil)
+
+	// Check []byte extraction
+	bytes, err := response.ExtractContent()
 	th.AssertNoErr(t, err)
-	th.CheckEquals(t, string(content), "Successful download with Gophercloud")
+	th.CheckEquals(t, "Successful download with Gophercloud", string(bytes))
 }
 
 func TestListObjectInfo(t *testing.T) {
diff --git a/openstack/objectstorage/v1/objects/results.go b/openstack/objectstorage/v1/objects/results.go
index c8f8b94..97a6f91 100644
--- a/openstack/objectstorage/v1/objects/results.go
+++ b/openstack/objectstorage/v1/objects/results.go
@@ -2,6 +2,8 @@
 
 import (
 	"fmt"
+	"io"
+	"io/ioutil"
 	"strings"
 
 	"github.com/rackspace/gophercloud"
@@ -102,15 +104,23 @@
 // DownloadResult is a *http.Response that is returned from a call to the Download function.
 type DownloadResult struct {
 	commonResult
+	Body io.Reader
 }
 
-// ExtractContent is a function that takes a DownloadResult (of type *http.Response)
-// and returns the object's content.
+// ExtractContent is a function that takes a DownloadResult's io.Reader body
+// and reads all available data into a slice of bytes. Please be aware that due
+// the nature of io.Reader is forward-only - meaning that it can only be read
+// once and not rewound. You can recreate a reader from the output of this
+// function by using bytes.NewReader(downloadBytes)
 func (dr DownloadResult) ExtractContent() ([]byte, error) {
 	if dr.Err != nil {
 		return nil, dr.Err
 	}
-	return dr.Body.([]byte), nil
+	body, err := ioutil.ReadAll(dr.Body)
+	if err != nil {
+		return nil, err
+	}
+	return body, nil
 }
 
 // GetResult is a *http.Response that is returned from a call to the Get function.