rackspace reponse header structs
diff --git a/rackspace/objectstorage/v1/cdncontainers/delegate.go b/rackspace/objectstorage/v1/cdncontainers/delegate.go
index d7eef20..89adb83 100644
--- a/rackspace/objectstorage/v1/cdncontainers/delegate.go
+++ b/rackspace/objectstorage/v1/cdncontainers/delegate.go
@@ -1,8 +1,6 @@
 package cdncontainers
 
 import (
-	"strconv"
-
 	"github.com/rackspace/gophercloud"
 	os "github.com/rackspace/gophercloud/openstack/objectstorage/v1/containers"
 	"github.com/rackspace/gophercloud/pagination"
@@ -38,34 +36,3 @@
 func List(c *gophercloud.ServiceClient, opts os.ListOptsBuilder) pagination.Pager {
 	return os.List(c, opts)
 }
-
-// Get is a function that retrieves the metadata of a container. To extract just
-// the custom metadata, pass the GetResult response to the ExtractMetadata
-// function.
-func Get(c *gophercloud.ServiceClient, containerName string) os.GetResult {
-	return os.Get(c, containerName)
-}
-
-// UpdateOpts is a structure that holds parameters for updating, creating, or
-// deleting a container's metadata.
-type UpdateOpts struct {
-	CDNEnabled   bool `h:"X-Cdn-Enabled"`
-	LogRetention bool `h:"X-Log-Retention"`
-	TTL          int  `h:"X-Ttl"`
-}
-
-// ToContainerUpdateMap formats a CreateOpts into a map of headers.
-func (opts UpdateOpts) ToContainerUpdateMap() (map[string]string, error) {
-	h, err := gophercloud.BuildHeaders(opts)
-	if err != nil {
-		return nil, err
-	}
-	h["X-Cdn-Enabled"] = strconv.FormatBool(opts.CDNEnabled)
-	return h, nil
-}
-
-// Update is a function that creates, updates, or deletes a container's
-// metadata.
-func Update(c *gophercloud.ServiceClient, containerName string, opts os.UpdateOptsBuilder) os.UpdateResult {
-	return os.Update(c, containerName, opts)
-}
diff --git a/rackspace/objectstorage/v1/cdncontainers/requests.go b/rackspace/objectstorage/v1/cdncontainers/requests.go
index 0567833..05b1939 100644
--- a/rackspace/objectstorage/v1/cdncontainers/requests.go
+++ b/rackspace/objectstorage/v1/cdncontainers/requests.go
@@ -1,6 +1,8 @@
 package cdncontainers
 
 import (
+	"strconv"
+
 	"github.com/racker/perigee"
 	"github.com/rackspace/gophercloud"
 )
@@ -56,3 +58,100 @@
 	res.Err = err
 	return res
 }
+
+// Get is a function that retrieves the metadata of a container. To extract just
+// the custom metadata, pass the GetResult response to the ExtractMetadata
+// function.
+func Get(c *gophercloud.ServiceClient, containerName string) GetResult {
+	var res GetResult
+	resp, err := perigee.Request("HEAD", getURL(c, containerName), perigee.Options{
+		MoreHeaders: c.AuthenticatedHeaders(),
+		OkCodes:     []int{200, 204},
+	})
+	res.Header = resp.HttpResponse.Header
+	res.Err = err
+	return res
+}
+
+// State is the state of an option. It is a pointer to a boolean to enable checking for
+// a zero-value of nil instead of false, which is a valid option.
+type State *bool
+
+var (
+	iTrue  = true
+	iFalse = false
+
+	// Enabled is used for a true value for options in request bodies.
+	Enabled State = &iTrue
+	// Disabled is used for a false value for options in request bodies.
+	Disabled State = &iFalse
+)
+
+// UpdateOptsBuilder allows extensions to add additional parameters to the
+// Update request.
+type UpdateOptsBuilder interface {
+	ToContainerUpdateMap() (map[string]string, error)
+}
+
+// UpdateOpts is a structure that holds parameters for updating, creating, or
+// deleting a container's metadata.
+type UpdateOpts struct {
+	// Whether or not to CDN-enable a container. Prefer using XCDNEnabled, which
+	// is of type *bool underneath.
+	// TODO v2.0: change type to Enabled/Disabled (*bool)
+	CDNEnabled bool `h:"X-Cdn-Enabled"`
+	// Whether or not to enable log retention. Prefer using XLogRetention, which
+	// is of type *bool underneath.
+	// TODO v2.0: change type to Enabled/Disabled (*bool)
+	LogRetention  bool `h:"X-Log-Retention"`
+	XCDNEnabled   *bool
+	XLogRetention *bool
+	TTL           int `h:"X-Ttl"`
+}
+
+// ToContainerUpdateMap formats a CreateOpts into a map of headers.
+func (opts UpdateOpts) ToContainerUpdateMap() (map[string]string, error) {
+	h, err := gophercloud.BuildHeaders(opts)
+	if err != nil {
+		return nil, err
+	}
+	h["X-Cdn-Enabled"] = strconv.FormatBool(opts.CDNEnabled)
+	h["X-Log-Retention"] = strconv.FormatBool(opts.LogRetention)
+
+	if opts.XCDNEnabled != nil {
+		h["X-Cdn-Enabled"] = strconv.FormatBool(*opts.XCDNEnabled)
+	}
+
+	if opts.XLogRetention != nil {
+		h["X-Log-Retention"] = strconv.FormatBool(*opts.XLogRetention)
+	}
+
+	return h, nil
+}
+
+// Update is a function that creates, updates, or deletes a container's
+// metadata.
+func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsBuilder) UpdateResult {
+	var res UpdateResult
+	h := c.AuthenticatedHeaders()
+
+	if opts != nil {
+		headers, err := opts.ToContainerUpdateMap()
+		if err != nil {
+			res.Err = err
+			return res
+		}
+
+		for k, v := range headers {
+			h[k] = v
+		}
+	}
+
+	resp, err := perigee.Request("POST", updateURL(c, containerName), perigee.Options{
+		MoreHeaders: h,
+		OkCodes:     []int{202, 204},
+	})
+	res.Header = resp.HttpResponse.Header
+	res.Err = err
+	return res
+}
diff --git a/rackspace/objectstorage/v1/cdncontainers/results.go b/rackspace/objectstorage/v1/cdncontainers/results.go
index a5097ca..cb0ad30 100644
--- a/rackspace/objectstorage/v1/cdncontainers/results.go
+++ b/rackspace/objectstorage/v1/cdncontainers/results.go
@@ -1,8 +1,149 @@
 package cdncontainers
 
-import "github.com/rackspace/gophercloud"
+import (
+	"strings"
+	"time"
 
-// EnableResult represents the result of a get operation.
+	"github.com/rackspace/gophercloud"
+)
+
+// EnableHeader represents the headers returned in the response from an Enable request.
+type EnableHeader struct {
+	CDNIosURI       string    `mapstructure:"X-Cdn-Ios-Uri"`
+	CDNSslURI       string    `mapstructure:"X-Cdn-Ssl-Uri"`
+	CDNStreamingURI string    `mapstructure:"X-Cdn-Streaming-Uri"`
+	CDNUri          string    `mapstructure:"X-Cdn-Uri"`
+	ContentLength   int       `mapstructure:"Content-Length"`
+	ContentType     string    `mapstructure:"Content-Type"`
+	Date            time.Time `mapstructure:"-"`
+	TransID         string    `mapstructure:"X-Trans-Id"`
+}
+
+// EnableResult represents the result of an Enable operation.
 type EnableResult struct {
 	gophercloud.HeaderResult
 }
+
+// Extract will return extract an EnableHeader from the response to an Enable
+// request. To obtain a map of headers, call the ExtractHeader method on the EnableResult.
+func (er EnableResult) Extract() (EnableHeader, error) {
+	var eh EnableHeader
+	if er.Err != nil {
+		return eh, er.Err
+	}
+
+	if err := gophercloud.DecodeHeader(er.Header, &eh); err != nil {
+		return eh, err
+	}
+
+	if date, ok := er.Header["Date"]; ok && len(date) > 0 {
+		t, err := time.Parse(time.RFC1123, er.Header["Date"][0])
+		if err != nil {
+			return eh, err
+		}
+		eh.Date = t
+	}
+
+	return eh, nil
+}
+
+// GetHeader represents the headers returned in the response from a Get request.
+type GetHeader struct {
+	CDNEnabled      bool      `mapstructure:"X-Cdn-Enabled"`
+	CDNIosURI       string    `mapstructure:"X-Cdn-Ios-Uri"`
+	CDNSslURI       string    `mapstructure:"X-Cdn-Ssl-Uri"`
+	CDNStreamingURI string    `mapstructure:"X-Cdn-Streaming-Uri"`
+	CDNUri          string    `mapstructure:"X-Cdn-Uri"`
+	ContentLength   int       `mapstructure:"Content-Length"`
+	ContentType     string    `mapstructure:"Content-Type"`
+	Date            time.Time `mapstructure:"-"`
+	LogRetention    bool      `mapstructure:"X-Log-Retention"`
+	TransID         string    `mapstructure:"X-Trans-Id"`
+	TTL             int       `mapstructure:"X-Ttl"`
+}
+
+// GetResult represents the result of a Get operation.
+type GetResult struct {
+	gophercloud.HeaderResult
+}
+
+// Extract will return a struct of headers returned from a call to Get. To obtain
+// a map of headers, call the ExtractHeader method on the GetResult.
+func (gr GetResult) Extract() (GetHeader, error) {
+	var gh GetHeader
+	if gr.Err != nil {
+		return gh, gr.Err
+	}
+
+	if err := gophercloud.DecodeHeader(gr.Header, &gh); err != nil {
+		return gh, err
+	}
+
+	if date, ok := gr.Header["Date"]; ok && len(date) > 0 {
+		t, err := time.Parse(time.RFC1123, gr.Header["Date"][0])
+		if err != nil {
+			return gh, err
+		}
+		gh.Date = t
+	}
+
+	return gh, nil
+}
+
+// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
+// and returns the custom metadata associated with the container.
+func (gr GetResult) ExtractMetadata() (map[string]string, error) {
+	if gr.Err != nil {
+		return nil, gr.Err
+	}
+	metadata := make(map[string]string)
+	for k, v := range gr.Header {
+		if strings.HasPrefix(k, "X-Container-Meta-") {
+			key := strings.TrimPrefix(k, "X-Container-Meta-")
+			metadata[key] = v[0]
+		}
+	}
+	return metadata, nil
+}
+
+// UpdateHeader represents the headers returned in the response from a Update request.
+type UpdateHeader struct {
+	CDNIosURI       string    `mapstructure:"X-Cdn-Ios-Uri"`
+	CDNSslURI       string    `mapstructure:"X-Cdn-Ssl-Uri"`
+	CDNStreamingURI string    `mapstructure:"X-Cdn-Streaming-Uri"`
+	CDNUri          string    `mapstructure:"X-Cdn-Uri"`
+	ContentLength   int       `mapstructure:"Content-Length"`
+	ContentType     string    `mapstructure:"Content-Type"`
+	Date            time.Time `mapstructure:"-"`
+	TransID         string    `mapstructure:"X-Trans-Id"`
+}
+
+// UpdateResult represents the result of an update operation. To extract the
+// the headers from the HTTP response, you can invoke the 'ExtractHeader'
+// method on the result struct.
+type UpdateResult struct {
+	gophercloud.HeaderResult
+}
+
+// Extract will return a struct of headers returned from a call to Update. To obtain
+// a map of headers, call the ExtractHeader method on the UpdateResult.
+func (ur UpdateResult) Extract() (UpdateHeader, error) {
+	var uh UpdateHeader
+	if ur.Err != nil {
+		return uh, ur.Err
+	}
+
+	if err := gophercloud.DecodeHeader(ur.Header, &uh); err != nil {
+		return uh, err
+	}
+
+	if date, ok := ur.Header["Date"]; ok && len(date) > 0 {
+		t, err := time.Parse(time.RFC1123, ur.Header["Date"][0])
+		if err != nil {
+			return uh, err
+		}
+		uh.Date = t
+	}
+
+	return uh, nil
+}
diff --git a/rackspace/objectstorage/v1/cdncontainers/urls.go b/rackspace/objectstorage/v1/cdncontainers/urls.go
index 80653f2..541249a 100644
--- a/rackspace/objectstorage/v1/cdncontainers/urls.go
+++ b/rackspace/objectstorage/v1/cdncontainers/urls.go
@@ -5,3 +5,11 @@
 func enableURL(c *gophercloud.ServiceClient, containerName string) string {
 	return c.ServiceURL(containerName)
 }
+
+func getURL(c *gophercloud.ServiceClient, container string) string {
+	return c.ServiceURL(container)
+}
+
+func updateURL(c *gophercloud.ServiceClient, container string) string {
+	return getURL(c, container)
+}