~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/preparer.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package autorest
 
2
 
 
3
import (
 
4
        "bytes"
 
5
        "encoding/json"
 
6
        "fmt"
 
7
        "io/ioutil"
 
8
        "net/http"
 
9
        "net/url"
 
10
        "strings"
 
11
)
 
12
 
 
13
const (
 
14
        mimeTypeJSON     = "application/json"
 
15
        mimeTypeFormPost = "application/x-www-form-urlencoded"
 
16
 
 
17
        headerAuthorization = "Authorization"
 
18
        headerContentType   = "Content-Type"
 
19
        headerUserAgent     = "User-Agent"
 
20
)
 
21
 
 
22
// Preparer is the interface that wraps the Prepare method.
 
23
//
 
24
// Prepare accepts and possibly modifies an http.Request (e.g., adding Headers). Implementations
 
25
// must ensure to not share or hold per-invocation state since Preparers may be shared and re-used.
 
26
type Preparer interface {
 
27
        Prepare(*http.Request) (*http.Request, error)
 
28
}
 
29
 
 
30
// PreparerFunc is a method that implements the Preparer interface.
 
31
type PreparerFunc func(*http.Request) (*http.Request, error)
 
32
 
 
33
// Prepare implements the Preparer interface on PreparerFunc.
 
34
func (pf PreparerFunc) Prepare(r *http.Request) (*http.Request, error) {
 
35
        return pf(r)
 
36
}
 
37
 
 
38
// PrepareDecorator takes and possibly decorates, by wrapping, a Preparer. Decorators may affect the
 
39
// http.Request and pass it along or, first, pass the http.Request along then affect the result.
 
40
type PrepareDecorator func(Preparer) Preparer
 
41
 
 
42
// CreatePreparer creates, decorates, and returns a Preparer.
 
43
// Without decorators, the returned Preparer returns the passed http.Request unmodified.
 
44
// Preparers are safe to share and re-use.
 
45
func CreatePreparer(decorators ...PrepareDecorator) Preparer {
 
46
        return DecoratePreparer(
 
47
                Preparer(PreparerFunc(func(r *http.Request) (*http.Request, error) { return r, nil })),
 
48
                decorators...)
 
49
}
 
50
 
 
51
// DecoratePreparer accepts a Preparer and a, possibly empty, set of PrepareDecorators, which it
 
52
// applies to the Preparer. Decorators are applied in the order received, but their affect upon the
 
53
// request depends on whether they are a pre-decorator (change the http.Request and then pass it
 
54
// along) or a post-decorator (pass the http.Request along and alter it on return).
 
55
func DecoratePreparer(p Preparer, decorators ...PrepareDecorator) Preparer {
 
56
        for _, decorate := range decorators {
 
57
                p = decorate(p)
 
58
        }
 
59
        return p
 
60
}
 
61
 
 
62
// Prepare accepts an http.Request and a, possibly empty, set of PrepareDecorators.
 
63
// It creates a Preparer from the decorators which it then applies to the passed http.Request.
 
64
func Prepare(r *http.Request, decorators ...PrepareDecorator) (*http.Request, error) {
 
65
        if r == nil {
 
66
                return nil, NewError("autorest", "Prepare", "Invoked without an http.Request")
 
67
        }
 
68
        return CreatePreparer(decorators...).Prepare(r)
 
69
}
 
70
 
 
71
// WithNothing returns a "do nothing" PrepareDecorator that makes no changes to the passed
 
72
// http.Request.
 
73
func WithNothing() PrepareDecorator {
 
74
        return func(p Preparer) Preparer {
 
75
                return PreparerFunc(func(r *http.Request) (*http.Request, error) {
 
76
                        return p.Prepare(r)
 
77
                })
 
78
        }
 
79
}
 
80
 
 
81
// WithHeader returns a PrepareDecorator that sets the specified HTTP header of the http.Request to
 
82
// the passed value. It canonicalizes the passed header name (via http.CanonicalHeaderKey) before
 
83
// adding the header.
 
84
func WithHeader(header string, value string) PrepareDecorator {
 
85
        return func(p Preparer) Preparer {
 
86
                return PreparerFunc(func(r *http.Request) (*http.Request, error) {
 
87
                        r, err := p.Prepare(r)
 
88
                        if err == nil {
 
89
                                if r.Header == nil {
 
90
                                        r.Header = make(http.Header)
 
91
                                }
 
92
                                r.Header.Set(http.CanonicalHeaderKey(header), value)
 
93
                        }
 
94
                        return r, err
 
95
                })
 
96
        }
 
97
}
 
98
 
 
99
// WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
 
100
// value is "Bearer " followed by the supplied token.
 
101
func WithBearerAuthorization(token string) PrepareDecorator {
 
102
        return WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", token))
 
103
}
 
104
 
 
105
// AsContentType returns a PrepareDecorator that adds an HTTP Content-Type header whose value
 
106
// is the passed contentType.
 
107
func AsContentType(contentType string) PrepareDecorator {
 
108
        return WithHeader(headerContentType, contentType)
 
109
}
 
110
 
 
111
// WithUserAgent returns a PrepareDecorator that adds an HTTP User-Agent header whose value is the
 
112
// passed string.
 
113
func WithUserAgent(ua string) PrepareDecorator {
 
114
        return WithHeader(headerUserAgent, ua)
 
115
}
 
116
 
 
117
// AsFormURLEncoded returns a PrepareDecorator that adds an HTTP Content-Type header whose value is
 
118
// "application/x-www-form-urlencoded".
 
119
func AsFormURLEncoded() PrepareDecorator {
 
120
        return AsContentType(mimeTypeFormPost)
 
121
}
 
122
 
 
123
// AsJSON returns a PrepareDecorator that adds an HTTP Content-Type header whose value is
 
124
// "application/json".
 
125
func AsJSON() PrepareDecorator {
 
126
        return AsContentType(mimeTypeJSON)
 
127
}
 
128
 
 
129
// WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The
 
130
// decorator does not validate that the passed method string is a known HTTP method.
 
131
func WithMethod(method string) PrepareDecorator {
 
132
        return func(p Preparer) Preparer {
 
133
                return PreparerFunc(func(r *http.Request) (*http.Request, error) {
 
134
                        r.Method = method
 
135
                        return p.Prepare(r)
 
136
                })
 
137
        }
 
138
}
 
139
 
 
140
// AsDelete returns a PrepareDecorator that sets the HTTP method to DELETE.
 
141
func AsDelete() PrepareDecorator { return WithMethod("DELETE") }
 
142
 
 
143
// AsGet returns a PrepareDecorator that sets the HTTP method to GET.
 
144
func AsGet() PrepareDecorator { return WithMethod("GET") }
 
145
 
 
146
// AsHead returns a PrepareDecorator that sets the HTTP method to HEAD.
 
147
func AsHead() PrepareDecorator { return WithMethod("HEAD") }
 
148
 
 
149
// AsOptions returns a PrepareDecorator that sets the HTTP method to OPTIONS.
 
150
func AsOptions() PrepareDecorator { return WithMethod("OPTIONS") }
 
151
 
 
152
// AsPatch returns a PrepareDecorator that sets the HTTP method to PATCH.
 
153
func AsPatch() PrepareDecorator { return WithMethod("PATCH") }
 
154
 
 
155
// AsPost returns a PrepareDecorator that sets the HTTP method to POST.
 
156
func AsPost() PrepareDecorator { return WithMethod("POST") }
 
157
 
 
158
// AsPut returns a PrepareDecorator that sets the HTTP method to PUT.
 
159
func AsPut() PrepareDecorator { return WithMethod("PUT") }
 
160
 
 
161
// WithBaseURL returns a PrepareDecorator that populates the http.Request with a url.URL constructed
 
162
// from the supplied baseUrl.
 
163
func WithBaseURL(baseURL string) PrepareDecorator {
 
164
        return func(p Preparer) Preparer {
 
165
                return PreparerFunc(func(r *http.Request) (*http.Request, error) {
 
166
                        r, err := p.Prepare(r)
 
167
                        if err == nil {
 
168
                                u, err := url.Parse(baseURL)
 
169
                                if err == nil {
 
170
                                        r.URL = u
 
171
                                }
 
172
                        }
 
173
                        return r, err
 
174
                })
 
175
        }
 
176
}
 
177
 
 
178
// WithFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) into the
 
179
// http.Request body.
 
180
func WithFormData(v url.Values) PrepareDecorator {
 
181
        return func(p Preparer) Preparer {
 
182
                return PreparerFunc(func(r *http.Request) (*http.Request, error) {
 
183
                        r, err := p.Prepare(r)
 
184
                        if err == nil {
 
185
                                s := v.Encode()
 
186
                                r.ContentLength = int64(len(s))
 
187
                                r.Body = ioutil.NopCloser(strings.NewReader(s))
 
188
                        }
 
189
                        return r, err
 
190
                })
 
191
        }
 
192
}
 
193
 
 
194
// WithJSON returns a PrepareDecorator that encodes the data passed as JSON into the body of the
 
195
// request and sets the Content-Length header.
 
196
func WithJSON(v interface{}) PrepareDecorator {
 
197
        return func(p Preparer) Preparer {
 
198
                return PreparerFunc(func(r *http.Request) (*http.Request, error) {
 
199
                        r, err := p.Prepare(r)
 
200
                        if err == nil {
 
201
                                b, err := json.Marshal(v)
 
202
                                if err == nil {
 
203
                                        r.ContentLength = int64(len(b))
 
204
                                        r.Body = ioutil.NopCloser(bytes.NewReader(b))
 
205
                                }
 
206
                        }
 
207
                        return r, err
 
208
                })
 
209
        }
 
210
}
 
211
 
 
212
// WithPath returns a PrepareDecorator that adds the supplied path to the request URL. If the path
 
213
// is absolute (that is, it begins with a "/"), it replaces the existing path.
 
214
func WithPath(path string) PrepareDecorator {
 
215
        return func(p Preparer) Preparer {
 
216
                return PreparerFunc(func(r *http.Request) (*http.Request, error) {
 
217
                        r, err := p.Prepare(r)
 
218
                        if err == nil {
 
219
                                if r.URL == nil {
 
220
                                        return r, NewError("autorest", "WithPath", "Invoked with a nil URL")
 
221
                                }
 
222
                                u := r.URL
 
223
                                u.Path = strings.TrimRight(u.Path, "/")
 
224
                                if strings.HasPrefix(path, "/") {
 
225
                                        u.Path = path
 
226
                                } else {
 
227
                                        u.Path += "/" + path
 
228
                                }
 
229
                        }
 
230
                        return r, err
 
231
                })
 
232
        }
 
233
}
 
234
 
 
235
// WithEscapedPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the
 
236
// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. The
 
237
// values will be escaped (aka URL encoded) before insertion into the path.
 
238
func WithEscapedPathParameters(pathParameters map[string]interface{}) PrepareDecorator {
 
239
        parameters := escapeValueStrings(ensureValueStrings(pathParameters))
 
240
        return func(p Preparer) Preparer {
 
241
                return PreparerFunc(func(r *http.Request) (*http.Request, error) {
 
242
                        r, err := p.Prepare(r)
 
243
                        if err == nil {
 
244
                                if r.URL == nil {
 
245
                                        return r, NewError("autorest", "WithEscapedPathParameters", "Invoked with a nil URL")
 
246
                                }
 
247
                                for key, value := range parameters {
 
248
                                        r.URL.Path = strings.Replace(r.URL.Path, "{"+key+"}", value, -1)
 
249
                                }
 
250
                        }
 
251
                        return r, err
 
252
                })
 
253
        }
 
254
}
 
255
 
 
256
// WithPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the
 
257
// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map.
 
258
func WithPathParameters(pathParameters map[string]interface{}) PrepareDecorator {
 
259
        parameters := ensureValueStrings(pathParameters)
 
260
        return func(p Preparer) Preparer {
 
261
                return PreparerFunc(func(r *http.Request) (*http.Request, error) {
 
262
                        r, err := p.Prepare(r)
 
263
                        if err == nil {
 
264
                                if r.URL == nil {
 
265
                                        return r, NewError("autorest", "WithPathParameters", "Invoked with a nil URL")
 
266
                                }
 
267
                                for key, value := range parameters {
 
268
                                        r.URL.Path = strings.Replace(r.URL.Path, "{"+key+"}", value, -1)
 
269
                                }
 
270
                        }
 
271
                        return r, err
 
272
                })
 
273
        }
 
274
}
 
275
 
 
276
// WithQueryParameters returns a PrepareDecorators that encodes and applies the query parameters
 
277
// given in the supplied map (i.e., key=value).
 
278
func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorator {
 
279
        parameters := ensureValueStrings(queryParameters)
 
280
        return func(p Preparer) Preparer {
 
281
                return PreparerFunc(func(r *http.Request) (*http.Request, error) {
 
282
                        r, err := p.Prepare(r)
 
283
                        if err == nil {
 
284
                                if r.URL == nil {
 
285
                                        return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL")
 
286
                                }
 
287
                                v := r.URL.Query()
 
288
                                for key, value := range parameters {
 
289
                                        v.Add(key, value)
 
290
                                }
 
291
                                r.URL.RawQuery = v.Encode()
 
292
                        }
 
293
                        return r, err
 
294
                })
 
295
        }
 
296
}
 
297
 
 
298
// Authorizer is the interface that provides a PrepareDecorator used to supply request
 
299
// authorization. Most often, the Authorizer decorator runs last so it has access to the full
 
300
// state of the formed HTTP request.
 
301
type Authorizer interface {
 
302
        WithAuthorization() PrepareDecorator
 
303
}
 
304
 
 
305
// NullAuthorizer implements a default, "do nothing" Authorizer.
 
306
type NullAuthorizer struct{}
 
307
 
 
308
// WithAuthorization returns a PrepareDecorator that does nothing.
 
309
func (na NullAuthorizer) WithAuthorization() PrepareDecorator {
 
310
        return WithNothing()
 
311
}