blob: dd2c2d7c7640898d6df145502996becad6dc6f3c [file] [log] [blame]
Jamie Hannaford8c072a32014-10-16 14:33:32 +02001package pagination
2
3import (
4 "encoding/json"
5 "io/ioutil"
6 "net/http"
7 "net/url"
8 "strings"
9
10 "github.com/racker/perigee"
11 "github.com/rackspace/gophercloud"
12)
13
14// LastHTTPResponse stores generic information derived from an HTTP response.
15// This exists primarily because the body of an http.Response can only be used once.
16type LastHTTPResponse struct {
17 url.URL
18 http.Header
19 Body interface{}
20}
21
22// RememberHTTPResponse parses an HTTP response as JSON and returns a LastHTTPResponse containing the results.
23// The main reason to do this instead of holding the response directly is that a response body can only be read once.
24// Also, this centralizes the JSON decoding.
25func RememberHTTPResponse(resp http.Response) (LastHTTPResponse, error) {
26 var parsedBody interface{}
27
28 defer resp.Body.Close()
29 rawBody, err := ioutil.ReadAll(resp.Body)
30 if err != nil {
31 return LastHTTPResponse{}, err
32 }
33
34 if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") {
35 err = json.Unmarshal(rawBody, &parsedBody)
36 if err != nil {
37 return LastHTTPResponse{}, err
38 }
39 } else {
40 parsedBody = rawBody
41 }
42
43 return LastHTTPResponse{
44 URL: *resp.Request.URL,
45 Header: resp.Header,
46 Body: parsedBody,
47 }, err
48}
49
50// Request performs a Perigee request and extracts the http.Response from the result.
51func Request(client *gophercloud.ServiceClient, headers map[string]string, url string) (http.Response, error) {
52 h := client.Provider.AuthenticatedHeaders()
53 for key, value := range headers {
54 h[key] = value
55 }
56
57 resp, err := perigee.Request("GET", url, perigee.Options{
58 MoreHeaders: h,
59 OkCodes: []int{200, 204},
60 })
61 if err != nil {
62 return http.Response{}, err
63 }
64 return resp.HttpResponse, nil
65}