forked from akamai/AkamaiOPEN-edgegrid-golang
/
client.go
152 lines (125 loc) · 3.84 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Package client is a simple library for http.Client to sign Akamai OPEN Edgegrid API requests
package client
import (
"bytes"
"errors"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"
"github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1"
)
var (
libraryVersion = "0.6.2"
// UserAgent is the User-Agent value sent for all requests
UserAgent = "Akamai-Open-Edgegrid-golang/" + libraryVersion + " golang/" + strings.TrimPrefix(runtime.Version(), "go")
// Client is the *http.Client to use
Client = http.DefaultClient
)
// NewRequest creates an HTTP request that can be sent to Akamai APIs. A relative URL can be provided in path, which will be resolved to the
// Host specified in Config. If body is specified, it will be sent as the request body.
func NewRequest(config edgegrid.Config, method, path string, body io.Reader) (*http.Request, error) {
var (
baseURL *url.URL
err error
)
if strings.HasPrefix(config.Host, "https://") {
baseURL, err = url.Parse(config.Host)
} else {
baseURL, err = url.Parse("https://" + config.Host)
}
if err != nil {
return nil, err
}
rel, err := url.Parse(strings.TrimPrefix(path, "/"))
if err != nil {
return nil, err
}
u := baseURL.ResolveReference(rel)
req, err := http.NewRequest(method, u.String(), body)
if err != nil {
return nil, err
}
req.Header.Add("User-Agent", UserAgent)
return req, nil
}
// NewJSONRequest creates an HTTP request that can be sent to the Akamai APIs with a JSON body
// The JSON body is encoded and the Content-Type/Accept headers are set automatically.
func NewJSONRequest(config edgegrid.Config, method, path string, body interface{}) (*http.Request, error) {
var req *http.Request
var err error
if body != nil {
jsonBody, err := jsonhooks.Marshal(body)
if err != nil {
return nil, err
}
buf := bytes.NewReader(jsonBody)
req, err = NewRequest(config, method, path, buf)
} else {
req, err = NewRequest(config, method, path, nil)
}
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json,*/*")
return req, nil
}
// NewMultiPartFormDataRequest creates an HTTP request that uploads a file to the Akamai API
func NewMultiPartFormDataRequest(config edgegrid.Config, uriPath, filePath string, otherFormParams map[string]string) (*http.Request, error) {
file, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
// TODO: make this field name configurable
part, err := writer.CreateFormFile("importFile", filepath.Base(filePath))
if err != nil {
return nil, err
}
_, err = io.Copy(part, file)
for key, val := range otherFormParams {
_ = writer.WriteField(key, val)
}
err = writer.Close()
if err != nil {
return nil, err
}
req, err := NewRequest(config, "POST", uriPath, body)
req.Header.Set("Content-Type", writer.FormDataContentType())
return req, err
}
// Do performs a given HTTP Request, signed with the Akamai OPEN Edgegrid
// Authorization header. An edgegrid.Response or an error is returned.
func Do(config edgegrid.Config, req *http.Request) (*http.Response, error) {
Client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
req = edgegrid.AddRequestHeader(config, req)
return nil
}
req = edgegrid.AddRequestHeader(config, req)
res, err := Client.Do(req)
if err != nil {
return nil, err
}
return res, nil
}
// BodyJSON unmarshals the Response.Body into a given data structure
func BodyJSON(r *http.Response, data interface{}) error {
if data == nil {
return errors.New("You must pass in an interface{}")
}
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return err
}
err = jsonhooks.Unmarshal(body, data)
return err
}