Merge pull request #277 from jrperritt/ExtractHeader-method

Extract header method
diff --git a/acceptance/openstack/blockstorage/v1/snapshots_test.go b/acceptance/openstack/blockstorage/v1/snapshots_test.go
index bd6a961..9132ee5 100644
--- a/acceptance/openstack/blockstorage/v1/snapshots_test.go
+++ b/acceptance/openstack/blockstorage/v1/snapshots_test.go
@@ -8,27 +8,22 @@
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots"
 	"github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes"
+	th "github.com/rackspace/gophercloud/testhelper"
 )
 
 func TestSnapshots(t *testing.T) {
 
 	client, err := newClient()
-	if err != nil {
-		t.Fatalf("Failed to create Block Storage v1 client: %v", err)
-	}
-
+	th.AssertNoErr(t, err)
+	
 	v, err := volumes.Create(client, &volumes.CreateOpts{
 		Name: "gophercloud-test-volume",
 		Size: 1,
 	}).Extract()
-	if err != nil {
-		t.Fatalf("Failed to create volume: %v\n", err)
-	}
+	th.AssertNoErr(t, err)
 
 	err = volumes.WaitForStatus(client, v.ID, "available", 120)
-	if err != nil {
-		t.Fatalf("Failed to create volume: %v\n", err)
-	}
+	th.AssertNoErr(t, err)
 
 	t.Logf("Created volume: %v\n", v)
 
@@ -36,21 +31,15 @@
 		Name:     "gophercloud-test-snapshot",
 		VolumeID: v.ID,
 	}).Extract()
-	if err != nil {
-		t.Fatalf("Failed to create snapshot: %v\n", err)
-	}
+	th.AssertNoErr(t, err)
 
 	err = snapshots.WaitForStatus(client, ss.ID, "available", 120)
-	if err != nil {
-		t.Fatalf("Failed to create snapshot: %v\n", err)
-	}
+	th.AssertNoErr(t, err)
 
 	t.Logf("Created snapshot: %+v\n", ss)
 
-	res = snapshots.Delete(client, ss.ID)
-	if res.Err != nil {
-		t.Fatalf("Failed to delete snapshot: %v", err)
-	}
+	err = snapshots.Delete(client, ss.ID).ExtractErr()
+	th.AssertNoErr(t, err)
 
 	err = gophercloud.WaitFor(120, func() (bool, error) {
 		_, err := snapshots.Get(client, ss.ID).Extract()
@@ -60,16 +49,12 @@
 
 		return false, nil
 	})
-	if err != nil {
-		t.Fatalf("Failed to delete snapshot: %v", err)
-	}
+	th.AssertNoErr(t, err)
 
 	t.Log("Deleted snapshot\n")
 
-	res = volumes.Delete(client, v.ID)
-	if res.Err != nil {
-		t.Errorf("Failed to delete volume: %v", err)
-	}
+	err = volumes.Delete(client, v.ID).ExtractErr()
+	th.AssertNoErr(t, err)
 
 	err = gophercloud.WaitFor(120, func() (bool, error) {
 		_, err := volumes.Get(client, v.ID).Extract()
@@ -79,9 +64,7 @@
 
 		return false, nil
 	})
-	if err != nil {
-		t.Errorf("Failed to delete volume: %v", err)
-	}
+	th.AssertNoErr(t, err)
 
 	t.Log("Deleted volume\n")
 }
diff --git a/acceptance/openstack/blockstorage/v1/volumes_test.go b/acceptance/openstack/blockstorage/v1/volumes_test.go
index d2281e6..99da39a 100644
--- a/acceptance/openstack/blockstorage/v1/volumes_test.go
+++ b/acceptance/openstack/blockstorage/v1/volumes_test.go
@@ -10,18 +10,15 @@
 	"github.com/rackspace/gophercloud/openstack"
 	"github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes"
 	"github.com/rackspace/gophercloud/pagination"
+	th "github.com/rackspace/gophercloud/testhelper"
 )
 
 func newClient() (*gophercloud.ServiceClient, error) {
 	ao, err := openstack.AuthOptionsFromEnv()
-	if err != nil {
-		return nil, err
-	}
+	th.AssertNoErr(t, err)
 
 	client, err := openstack.AuthenticatedClient(ao)
-	if err != nil {
-		return nil, err
-	}
+	th.AssertNoErr(t, err)
 
 	return openstack.NewBlockStorageV1(client, gophercloud.EndpointOpts{
 		Region: os.Getenv("OS_REGION_NAME"),
@@ -30,43 +27,27 @@
 
 func TestVolumes(t *testing.T) {
 	client, err := newClient()
-	if err != nil {
-		t.Fatalf("Failed to create Block Storage v1 client: %v", err)
-	}
+	th.AssertNoErr(t, err)
 
 	cv, err := volumes.Create(client, &volumes.CreateOpts{
 		Size: 1,
 		Name: "gophercloud-test-volume",
 	}).Extract()
-	if err != nil {
-		t.Error(err)
-		return
-	}
+	th.AssertNoErr(t, err)
 	defer func() {
 		err = volumes.WaitForStatus(client, cv.ID, "available", 60)
-		if err != nil {
-			t.Error(err)
-		}
-		res = volumes.Delete(client, cv.ID)
-		if res.Err != nil {
-			t.Error(err)
-			return
-		}
+		th.AssertNoErr(t, err)
+		err = volumes.Delete(client, cv.ID).ExtractErr()
+		th.AssertNoErr(t, err)
 	}()
 
 	_, err = volumes.Update(client, cv.ID, &volumes.UpdateOpts{
 		Name: "gophercloud-updated-volume",
 	}).Extract()
-	if err != nil {
-		t.Error(err)
-		return
-	}
+	th.AssertNoErr(t, err)
 
 	v, err := volumes.Get(client, cv.ID).Extract()
-	if err != nil {
-		t.Error(err)
-		return
-	}
+	th.AssertNoErr(t, err)
 	t.Logf("Got volume: %+v\n", v)
 
 	if v.Name != "gophercloud-updated-volume" {
@@ -75,12 +56,8 @@
 
 	err = volumes.List(client, &volumes.ListOpts{Name: "gophercloud-updated-volume"}).EachPage(func(page pagination.Page) (bool, error) {
 		vols, err := volumes.ExtractVolumes(page)
-		if len(vols) != 1 {
-			t.Errorf("Expected 1 volume, got %d", len(vols))
-		}
+		th.CheckEquals(t, 1, len(vols))
 		return true, err
 	})
-	if err != nil {
-		t.Errorf("Error listing volumes: %v", err)
-	}
+	th.AssertNoErr(t, err)
 }
diff --git a/acceptance/openstack/blockstorage/v1/volumetypes_test.go b/acceptance/openstack/blockstorage/v1/volumetypes_test.go
index 416e341..5adcd81 100644
--- a/acceptance/openstack/blockstorage/v1/volumetypes_test.go
+++ b/acceptance/openstack/blockstorage/v1/volumetypes_test.go
@@ -8,13 +8,12 @@
 
 	"github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumetypes"
 	"github.com/rackspace/gophercloud/pagination"
+	th "github.com/rackspace/gophercloud/testhelper"
 )
 
 func TestVolumeTypes(t *testing.T) {
 	client, err := newClient()
-	if err != nil {
-		t.Fatalf("Failed to create Block Storage v1 client: %v", err)
-	}
+	th.AssertNoErr(t, err)
 
 	vt, err := volumetypes.Create(client, &volumetypes.CreateOpts{
 		ExtraSpecs: map[string]interface{}{
@@ -23,13 +22,10 @@
 		},
 		Name: "gophercloud-test-volumeType",
 	}).Extract()
-	if err != nil {
-		t.Error(err)
-		return
-	}
+	th.AssertNoErr(t, err)
 	defer func() {
 		time.Sleep(10000 * time.Millisecond)
-		err = volumetypes.Delete(client, vt.ID)
+		err = volumetypes.Delete(client, vt.ID).ExtractErr()
 		if err != nil {
 			t.Error(err)
 			return
@@ -38,10 +34,7 @@
 	t.Logf("Created volume type: %+v\n", vt)
 
 	vt, err = volumetypes.Get(client, vt.ID).Extract()
-	if err != nil {
-		t.Error(err)
-		return
-	}
+	th.AssertNoErr(t, err)
 	t.Logf("Got volume type: %+v\n", vt)
 
 	err = volumetypes.List(client).EachPage(func(page pagination.Page) (bool, error) {
@@ -52,7 +45,5 @@
 		t.Logf("Listing volume types: %+v\n", volTypes)
 		return true, err
 	})
-	if err != nil {
-		t.Errorf("Error trying to list volume types: %v", err)
-	}
+	th.AssertNoErr(t, err)
 }
diff --git a/acceptance/openstack/objectstorage/v1/objects_test.go b/acceptance/openstack/objectstorage/v1/objects_test.go
index 987f733..a8de338 100644
--- a/acceptance/openstack/objectstorage/v1/objects_test.go
+++ b/acceptance/openstack/objectstorage/v1/objects_test.go
@@ -30,8 +30,9 @@
 
 	// Create a container to hold the test objects.
 	cName := tools.RandomString("test-container-", 8)
-	createres := containers.Create(client, cName, nil)
-	th.AssertNoErr(t, createres.Err)
+	header, err := containers.Create(client, cName, nil).ExtractHeader()
+	th.AssertNoErr(t, err)
+	t.Logf("Create object headers: %+v\n", header)
 
 	// Defer deletion of the container until after testing.
 	defer func() {
@@ -55,7 +56,7 @@
 	}()
 
 	ons := make([]string, 0, len(oNames))
-	err := objects.List(client, cName, &objects.ListOpts{Full: false, Prefix: "test-object-"}).EachPage(func(page pagination.Page) (bool, error) {
+	err = objects.List(client, cName, &objects.ListOpts{Full: false, Prefix: "test-object-"}).EachPage(func(page pagination.Page) (bool, error) {
 		names, err := objects.ExtractNames(page)
 		th.AssertNoErr(t, err)
 		ons = append(ons, names...)
diff --git a/acceptance/rackspace/compute/v2/keypairs_test.go b/acceptance/rackspace/compute/v2/keypairs_test.go
index ac5a1f2..9bd6eb4 100644
--- a/acceptance/rackspace/compute/v2/keypairs_test.go
+++ b/acceptance/rackspace/compute/v2/keypairs_test.go
@@ -14,7 +14,7 @@
 )
 
 func deleteKeyPair(t *testing.T, client *gophercloud.ServiceClient, name string) {
-	err := keypairs.Delete(client, name).Extract()
+	err := keypairs.Delete(client, name).ExtractErr()
 	th.AssertNoErr(t, err)
 	t.Logf("Successfully deleted key [%s].", name)
 }
diff --git a/acceptance/rackspace/compute/v2/servers_test.go b/acceptance/rackspace/compute/v2/servers_test.go
index 58b5fa3..511f0a9 100644
--- a/acceptance/rackspace/compute/v2/servers_test.go
+++ b/acceptance/rackspace/compute/v2/servers_test.go
@@ -175,7 +175,7 @@
 func deleteServerKeyPair(t *testing.T, client *gophercloud.ServiceClient, k *oskey.KeyPair) {
 	t.Logf("> keypairs.Delete")
 
-	err := keypairs.Delete(client, k.Name).Extract()
+	err := keypairs.Delete(client, k.Name).ExtractErr()
 	th.AssertNoErr(t, err)
 
 	t.Logf("Keypair deleted successfully.")
diff --git a/acceptance/rackspace/objectstorage/v1/cdnobjects_test.go b/acceptance/rackspace/objectstorage/v1/cdnobjects_test.go
index dfc2dca..6e477ae 100644
--- a/acceptance/rackspace/objectstorage/v1/cdnobjects_test.go
+++ b/acceptance/rackspace/objectstorage/v1/cdnobjects_test.go
@@ -25,9 +25,9 @@
 		th.AssertNoErr(t, deleteResult.Err)
 	}()
 
-	createObjResult := raxObjects.Create(raxClient, "gophercloud-test", "test-object", bytes.NewBufferString("gophercloud cdn test"), nil)
-	th.AssertNoErr(t, createObjResult.Err)
-	t.Logf("Headers from Create Object request: %+v\n", createObjResult.Header)
+	header, err := raxObjects.Create(raxClient, "gophercloud-test", "test-object", bytes.NewBufferString("gophercloud cdn test"), nil).ExtractHeader()
+	th.AssertNoErr(t, err)
+	t.Logf("Headers from Create Object request: %+v\n", header)
 	defer func() {
 		deleteResult := raxObjects.Delete(raxClient, "gophercloud-test", "test-object", nil)
 		th.AssertNoErr(t, deleteResult.Err)
diff --git a/openstack/blockstorage/v1/snapshots/results.go b/openstack/blockstorage/v1/snapshots/results.go
index c531a04..e595798 100644
--- a/openstack/blockstorage/v1/snapshots/results.go
+++ b/openstack/blockstorage/v1/snapshots/results.go
@@ -61,7 +61,7 @@
 
 // DeleteResult contains the response body and error from a Delete request.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // ListResult is a pagination.Pager that is returned from a call to the List function.
diff --git a/openstack/blockstorage/v1/volumes/results.go b/openstack/blockstorage/v1/volumes/results.go
index 0572558..c6ddbb5 100644
--- a/openstack/blockstorage/v1/volumes/results.go
+++ b/openstack/blockstorage/v1/volumes/results.go
@@ -61,7 +61,7 @@
 
 // DeleteResult contains the response body and error from a Delete request.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // ListResult is a pagination.pager that is returned from a call to the List function.
diff --git a/openstack/blockstorage/v1/volumetypes/requests.go b/openstack/blockstorage/v1/volumetypes/requests.go
index 32d323d..87e20f6 100644
--- a/openstack/blockstorage/v1/volumetypes/requests.go
+++ b/openstack/blockstorage/v1/volumetypes/requests.go
@@ -55,12 +55,13 @@
 }
 
 // Delete will delete the volume type with the provided ID.
-func Delete(client *gophercloud.ServiceClient, id string) error {
-	_, err := perigee.Request("DELETE", deleteURL(client, id), perigee.Options{
+func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
+	var res DeleteResult
+	_, res.Err = perigee.Request("DELETE", deleteURL(client, id), perigee.Options{
 		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{202},
 	})
-	return err
+	return res
 }
 
 // Get will retrieve the volume type with the provided ID. To extract the volume
diff --git a/openstack/blockstorage/v1/volumetypes/requests_test.go b/openstack/blockstorage/v1/volumetypes/requests_test.go
index 8b11786..8d40bfe 100644
--- a/openstack/blockstorage/v1/volumetypes/requests_test.go
+++ b/openstack/blockstorage/v1/volumetypes/requests_test.go
@@ -113,6 +113,6 @@
 		w.WriteHeader(http.StatusAccepted)
 	})
 
-	err := Delete(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22")
+	err := Delete(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").ExtractErr()
 	th.AssertNoErr(t, err)
 }
diff --git a/openstack/blockstorage/v1/volumetypes/results.go b/openstack/blockstorage/v1/volumetypes/results.go
index a13f7c1..c049a04 100644
--- a/openstack/blockstorage/v1/volumetypes/results.go
+++ b/openstack/blockstorage/v1/volumetypes/results.go
@@ -23,6 +23,11 @@
 	commonResult
 }
 
+// DeleteResult contains the response error from a Delete request.
+type DeleteResult struct {
+	gophercloud.ErrResult
+}
+
 // ListResult is a pagination.Pager that is returned from a call to the List function.
 type ListResult struct {
 	pagination.SinglePageBase
diff --git a/openstack/compute/v2/extensions/keypairs/requests_test.go b/openstack/compute/v2/extensions/keypairs/requests_test.go
index 502a154..67d1833 100644
--- a/openstack/compute/v2/extensions/keypairs/requests_test.go
+++ b/openstack/compute/v2/extensions/keypairs/requests_test.go
@@ -66,6 +66,6 @@
 	defer th.TeardownHTTP()
 	HandleDeleteSuccessfully(t)
 
-	err := Delete(client.ServiceClient(), "deletedkey").Extract()
+	err := Delete(client.ServiceClient(), "deletedkey").ExtractErr()
 	th.AssertNoErr(t, err)
 }
diff --git a/openstack/compute/v2/extensions/keypairs/results.go b/openstack/compute/v2/extensions/keypairs/results.go
index dc49f99..f1a0d8e 100644
--- a/openstack/compute/v2/extensions/keypairs/results.go
+++ b/openstack/compute/v2/extensions/keypairs/results.go
@@ -90,5 +90,5 @@
 // DeleteResult is the response from a Delete operation. Call its Extract method to determine if
 // the call succeeded or failed.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go
index 63cc257..53946ba 100644
--- a/openstack/compute/v2/servers/results.go
+++ b/openstack/compute/v2/servers/results.go
@@ -41,7 +41,7 @@
 
 // DeleteResult temporarily contains the response from an Delete call.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // RebuildResult temporarily contains the response from a Rebuild call.
@@ -51,7 +51,7 @@
 
 // ActionResult represents the result of server action operations, like reboot
 type ActionResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // Server exposes only the standard OpenStack fields corresponding to a given server on the user's account.
diff --git a/openstack/identity/v3/endpoints/results.go b/openstack/identity/v3/endpoints/results.go
index 2aa0483..1281122 100644
--- a/openstack/identity/v3/endpoints/results.go
+++ b/openstack/identity/v3/endpoints/results.go
@@ -43,7 +43,7 @@
 
 // DeleteResult is the deferred result of an Delete call.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // Endpoint describes the entry point for another service's API.
diff --git a/openstack/identity/v3/services/results.go b/openstack/identity/v3/services/results.go
index d90b1bd..1d0d141 100644
--- a/openstack/identity/v3/services/results.go
+++ b/openstack/identity/v3/services/results.go
@@ -44,7 +44,7 @@
 
 // DeleteResult is the deferred result of an Delete call.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // Service is the result of a list or information query.
diff --git a/openstack/networking/v2/extensions/layer3/floatingips/results.go b/openstack/networking/v2/extensions/layer3/floatingips/results.go
index 3eac001..a1c7afe 100644
--- a/openstack/networking/v2/extensions/layer3/floatingips/results.go
+++ b/openstack/networking/v2/extensions/layer3/floatingips/results.go
@@ -78,7 +78,7 @@
 
 // DeleteResult represents the result of an update operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // FloatingIPPage is the page returned by a pager when traversing over a
diff --git a/openstack/networking/v2/extensions/layer3/routers/results.go b/openstack/networking/v2/extensions/layer3/routers/results.go
index 2ce1e6c..bdad4cb 100755
--- a/openstack/networking/v2/extensions/layer3/routers/results.go
+++ b/openstack/networking/v2/extensions/layer3/routers/results.go
@@ -122,7 +122,7 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // InterfaceInfo represents information about a particular router interface. As
diff --git a/openstack/networking/v2/extensions/lbaas/members/results.go b/openstack/networking/v2/extensions/lbaas/members/results.go
index 447fe29..3cad339 100644
--- a/openstack/networking/v2/extensions/lbaas/members/results.go
+++ b/openstack/networking/v2/extensions/lbaas/members/results.go
@@ -118,5 +118,5 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
diff --git a/openstack/networking/v2/extensions/lbaas/monitors/results.go b/openstack/networking/v2/extensions/lbaas/monitors/results.go
index 7f7ff97..d595abd 100644
--- a/openstack/networking/v2/extensions/lbaas/monitors/results.go
+++ b/openstack/networking/v2/extensions/lbaas/monitors/results.go
@@ -143,5 +143,5 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
diff --git a/openstack/networking/v2/extensions/lbaas/pools/results.go b/openstack/networking/v2/extensions/lbaas/pools/results.go
index 0f95e15..07ec85e 100644
--- a/openstack/networking/v2/extensions/lbaas/pools/results.go
+++ b/openstack/networking/v2/extensions/lbaas/pools/results.go
@@ -137,7 +137,7 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // AssociateResult represents the result of an association operation.
diff --git a/openstack/networking/v2/extensions/lbaas/vips/results.go b/openstack/networking/v2/extensions/lbaas/vips/results.go
index 39c980a..e1092e7 100644
--- a/openstack/networking/v2/extensions/lbaas/vips/results.go
+++ b/openstack/networking/v2/extensions/lbaas/vips/results.go
@@ -162,5 +162,5 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
diff --git a/openstack/networking/v2/extensions/security/groups/results.go b/openstack/networking/v2/extensions/security/groups/results.go
index 9df3268..49db261 100644
--- a/openstack/networking/v2/extensions/security/groups/results.go
+++ b/openstack/networking/v2/extensions/security/groups/results.go
@@ -104,5 +104,5 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
diff --git a/openstack/networking/v2/extensions/security/rules/results.go b/openstack/networking/v2/extensions/security/rules/results.go
index 6684272..6e13857 100644
--- a/openstack/networking/v2/extensions/security/rules/results.go
+++ b/openstack/networking/v2/extensions/security/rules/results.go
@@ -129,5 +129,5 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
diff --git a/openstack/networking/v2/networks/results.go b/openstack/networking/v2/networks/results.go
index 9b39e8c..3ecedde 100644
--- a/openstack/networking/v2/networks/results.go
+++ b/openstack/networking/v2/networks/results.go
@@ -42,7 +42,7 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // Network represents, well, a network.
diff --git a/openstack/networking/v2/ports/results.go b/openstack/networking/v2/ports/results.go
index 2d72c35..2511ff5 100644
--- a/openstack/networking/v2/ports/results.go
+++ b/openstack/networking/v2/ports/results.go
@@ -42,7 +42,7 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // IP is a sub-struct that represents an individual IP.
diff --git a/openstack/networking/v2/subnets/results.go b/openstack/networking/v2/subnets/results.go
index 70aa543..1910f17 100644
--- a/openstack/networking/v2/subnets/results.go
+++ b/openstack/networking/v2/subnets/results.go
@@ -42,7 +42,7 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // AllocationPool represents a sub-range of cidr available for dynamic
diff --git a/openstack/objectstorage/v1/accounts/requests.go b/openstack/objectstorage/v1/accounts/requests.go
index 55b4217..e6f5f95 100644
--- a/openstack/objectstorage/v1/accounts/requests.go
+++ b/openstack/objectstorage/v1/accounts/requests.go
@@ -25,7 +25,7 @@
 // Get is a function that retrieves an account's metadata. To extract just the
 // custom metadata, call the ExtractMetadata method on the GetResult. To extract
 // all the headers that are returned (including the metadata), call the
-// ExtractHeaders method on the GetResult.
+// ExtractHeader method on the GetResult.
 func Get(c *gophercloud.ServiceClient, opts GetOptsBuilder) GetResult {
 	var res GetResult
 	h := c.AuthenticatedHeaders()
diff --git a/openstack/objectstorage/v1/accounts/results.go b/openstack/objectstorage/v1/accounts/results.go
index ba379eb..abae026 100644
--- a/openstack/objectstorage/v1/accounts/results.go
+++ b/openstack/objectstorage/v1/accounts/results.go
@@ -8,7 +8,7 @@
 
 // GetResult is returned from a call to the Get function.
 type GetResult struct {
-	gophercloud.Result
+	gophercloud.HeaderResult
 }
 
 // ExtractMetadata is a function that takes a GetResult (of type *http.Response)
@@ -30,5 +30,5 @@
 
 // UpdateResult is returned from a call to the Update function.
 type UpdateResult struct {
-	gophercloud.Result
+	gophercloud.HeaderResult
 }
diff --git a/openstack/objectstorage/v1/containers/results.go b/openstack/objectstorage/v1/containers/results.go
index f7f84c3..74f3286 100644
--- a/openstack/objectstorage/v1/containers/results.go
+++ b/openstack/objectstorage/v1/containers/results.go
@@ -96,13 +96,9 @@
 	}
 }
 
-type commonResult struct {
-	gophercloud.Result
-}
-
 // GetResult represents the result of a get operation.
 type GetResult struct {
-	commonResult
+	gophercloud.HeaderResult
 }
 
 // ExtractMetadata is a function that takes a GetResult (of type *http.Response)
@@ -122,22 +118,22 @@
 }
 
 // CreateResult represents the result of a create operation. To extract the
-// the headers from the HTTP response, you can invoke the 'ExtractHeaders'
+// the headers from the HTTP response, you can invoke the 'ExtractHeader'
 // method on the result struct.
 type CreateResult struct {
-	commonResult
+	gophercloud.HeaderResult
 }
 
 // UpdateResult represents the result of an update operation. To extract the
-// the headers from the HTTP response, you can invoke the 'ExtractHeaders'
+// the headers from the HTTP response, you can invoke the 'ExtractHeader'
 // method on the result struct.
 type UpdateResult struct {
-	commonResult
+	gophercloud.HeaderResult
 }
 
 // DeleteResult represents the result of a delete operation. To extract the
-// the headers from the HTTP response, you can invoke the 'ExtractHeaders'
+// the headers from the HTTP response, you can invoke the 'ExtractHeader'
 // method on the result struct.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.HeaderResult
 }
diff --git a/openstack/objectstorage/v1/objects/requests.go b/openstack/objectstorage/v1/objects/requests.go
index f5ca296..9778de3 100644
--- a/openstack/objectstorage/v1/objects/requests.go
+++ b/openstack/objectstorage/v1/objects/requests.go
@@ -266,6 +266,7 @@
 		OkCodes:     []int{201},
 	})
 	res.Header = resp.HttpResponse.Header
+	res.Err = err
 	return res
 }
 
@@ -303,11 +304,12 @@
 		url += query
 	}
 
-	_, res.Err = perigee.Request("DELETE", url, perigee.Options{
+	resp, err := perigee.Request("DELETE", url, perigee.Options{
 		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
-
+	res.Header = resp.HttpResponse.Header
+	res.Err = err
 	return res
 }
 
diff --git a/openstack/objectstorage/v1/objects/results.go b/openstack/objectstorage/v1/objects/results.go
index 97020df..102d94c 100644
--- a/openstack/objectstorage/v1/objects/results.go
+++ b/openstack/objectstorage/v1/objects/results.go
@@ -97,13 +97,9 @@
 	}
 }
 
-type commonResult struct {
-	gophercloud.Result
-}
-
 // DownloadResult is a *http.Response that is returned from a call to the Download function.
 type DownloadResult struct {
-	commonResult
+	gophercloud.HeaderResult
 	Body io.ReadCloser
 }
 
@@ -126,7 +122,7 @@
 
 // GetResult is a *http.Response that is returned from a call to the Get function.
 type GetResult struct {
-	commonResult
+	gophercloud.HeaderResult
 }
 
 // ExtractMetadata is a function that takes a GetResult (of type *http.Response)
@@ -147,20 +143,20 @@
 
 // CreateResult represents the result of a create operation.
 type CreateResult struct {
-	commonResult
+	gophercloud.HeaderResult
 }
 
 // UpdateResult represents the result of an update operation.
 type UpdateResult struct {
-	commonResult
+	gophercloud.HeaderResult
 }
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.HeaderResult
 }
 
 // CopyResult represents the result of a copy operation.
 type CopyResult struct {
-	commonResult
+	gophercloud.HeaderResult
 }
diff --git a/rackspace/compute/v2/keypairs/delegate_test.go b/rackspace/compute/v2/keypairs/delegate_test.go
index b72e69e..62e5df9 100644
--- a/rackspace/compute/v2/keypairs/delegate_test.go
+++ b/rackspace/compute/v2/keypairs/delegate_test.go
@@ -67,6 +67,6 @@
 	defer th.TeardownHTTP()
 	os.HandleDeleteSuccessfully(t)
 
-	err := Delete(client.ServiceClient(), "deletedkey").Extract()
+	err := Delete(client.ServiceClient(), "deletedkey").ExtractErr()
 	th.AssertNoErr(t, err)
 }
diff --git a/rackspace/compute/v2/networks/results.go b/rackspace/compute/v2/networks/results.go
index 558df47..eb6a76c 100644
--- a/rackspace/compute/v2/networks/results.go
+++ b/rackspace/compute/v2/networks/results.go
@@ -37,7 +37,7 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // Network represents, well, a network.
diff --git a/rackspace/compute/v2/virtualinterfaces/results.go b/rackspace/compute/v2/virtualinterfaces/results.go
index 14c7a47..26fa7f3 100644
--- a/rackspace/compute/v2/virtualinterfaces/results.go
+++ b/rackspace/compute/v2/virtualinterfaces/results.go
@@ -32,7 +32,7 @@
 
 // DeleteResult represents the result of a delete operation.
 type DeleteResult struct {
-	gophercloud.ExtractErrResult
+	gophercloud.ErrResult
 }
 
 // IPAddress represents a vitual address attached to a VirtualInterface.
diff --git a/rackspace/objectstorage/v1/accounts/delegate.go b/rackspace/objectstorage/v1/accounts/delegate.go
index ae3de26..9473930 100644
--- a/rackspace/objectstorage/v1/accounts/delegate.go
+++ b/rackspace/objectstorage/v1/accounts/delegate.go
@@ -8,7 +8,7 @@
 // Get is a function that retrieves an account's metadata. To extract just the
 // custom metadata, call the ExtractMetadata method on the GetResult. To extract
 // all the headers that are returned (including the metadata), call the
-// ExtractHeaders method on the GetResult.
+// ExtractHeader method on the GetResult.
 func Get(c *gophercloud.ServiceClient) os.GetResult {
 	return os.Get(c, nil)
 }
@@ -33,6 +33,7 @@
 	return headers, err
 }
 
+// Update will update an account's metadata with the Metadata in the UpdateOptsBuilder.
 func Update(c *gophercloud.ServiceClient, opts os.UpdateOptsBuilder) os.UpdateResult {
 	return os.Update(c, opts)
 }
diff --git a/rackspace/objectstorage/v1/cdncontainers/results.go b/rackspace/objectstorage/v1/cdncontainers/results.go
index 374d884..a5097ca 100644
--- a/rackspace/objectstorage/v1/cdncontainers/results.go
+++ b/rackspace/objectstorage/v1/cdncontainers/results.go
@@ -4,5 +4,5 @@
 
 // EnableResult represents the result of a get operation.
 type EnableResult struct {
-	gophercloud.Result
+	gophercloud.HeaderResult
 }
diff --git a/results.go b/results.go
index e60088e..f480bc7 100644
--- a/results.go
+++ b/results.go
@@ -28,18 +28,31 @@
 	return string(pretty)
 }
 
-// ExtractErrResult represents results that only contain a potential error and
+// ErrResult represents results that only contain a potential error and
 // nothing else. Usually if the operation executed successfully, the Err field
 // will be nil; otherwise it will be stocked with a relevant error.
-type ExtractErrResult struct {
-	Err error
+type ErrResult struct {
+	Result
 }
 
-// Extract is a function that extracts error information from a result
-func (r ExtractErrResult) Extract() error {
+// ExtractErr is a function that extracts error information from a result.
+func (r ErrResult) ExtractErr() error {
 	return r.Err
 }
 
+// HeaderResult represents a result that only contains an `error` (possibly nil)
+// and an http.Header. This is used, for example, by the `objectstorage` packages
+// in `openstack`, because most of the operations don't return response bodies.
+type HeaderResult struct {
+	Result
+}
+
+// ExtractHeader will return the http.Header and error from the HeaderResult.
+// Usage: header, err := objects.Create(client, "my_container", objects.CreateOpts{}).ExtractHeader()
+func (hr HeaderResult) ExtractHeader() (http.Header, error) {
+	return hr.Header, hr.Err
+}
+
 // RFC3339Milli describes a time format used by API responses.
 const RFC3339Milli = "2006-01-02T15:04:05.999999Z"