blob: dd2c2d7c7640898d6df145502996becad6dc6f3c [file] [log] [blame]
Ash Wilsonc8e68872014-09-16 10:36:56 -04001package pagination
2
3import (
4 "encoding/json"
5 "io/ioutil"
6 "net/http"
7 "net/url"
Ash Wilsona7402472014-09-16 15:18:34 -04008 "strings"
Ash Wilsonc8e68872014-09-16 10:36:56 -04009
10 "github.com/racker/perigee"
11 "github.com/rackspace/gophercloud"
12)
13
14// LastHTTPResponse stores generic information derived from an HTTP response.
Ash Wilsona7402472014-09-16 15:18:34 -040015// This exists primarily because the body of an http.Response can only be used once.
Ash Wilsonc8e68872014-09-16 10:36:56 -040016type 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
Ash Wilsona7402472014-09-16 15:18:34 -040034 if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") {
Ash Wilsonc8e68872014-09-16 10:36:56 -040035 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.
Ash Wilsona7402472014-09-16 15:18:34 -040051func 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
Ash Wilsonc8e68872014-09-16 10:36:56 -040057 resp, err := perigee.Request("GET", url, perigee.Options{
Ash Wilsona7402472014-09-16 15:18:34 -040058 MoreHeaders: h,
Ash Wilsonc8e68872014-09-16 10:36:56 -040059 OkCodes: []int{200, 204},
60 })
61 if err != nil {
62 return http.Response{}, err
63 }
64 return resp.HttpResponse, nil
65}