14
mimeTypeJSON = "application/json"
15
mimeTypeFormPost = "application/x-www-form-urlencoded"
17
headerAuthorization = "Authorization"
18
headerContentType = "Content-Type"
19
headerUserAgent = "User-Agent"
22
// Preparer is the interface that wraps the Prepare method.
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)
30
// PreparerFunc is a method that implements the Preparer interface.
31
type PreparerFunc func(*http.Request) (*http.Request, error)
33
// Prepare implements the Preparer interface on PreparerFunc.
34
func (pf PreparerFunc) Prepare(r *http.Request) (*http.Request, error) {
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
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 })),
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 {
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) {
66
return nil, NewError("autorest", "Prepare", "Invoked without an http.Request")
68
return CreatePreparer(decorators...).Prepare(r)
71
// WithNothing returns a "do nothing" PrepareDecorator that makes no changes to the passed
73
func WithNothing() PrepareDecorator {
74
return func(p Preparer) Preparer {
75
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
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
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)
90
r.Header = make(http.Header)
92
r.Header.Set(http.CanonicalHeaderKey(header), value)
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))
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)
111
// WithUserAgent returns a PrepareDecorator that adds an HTTP User-Agent header whose value is the
113
func WithUserAgent(ua string) PrepareDecorator {
114
return WithHeader(headerUserAgent, ua)
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)
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)
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) {
140
// AsDelete returns a PrepareDecorator that sets the HTTP method to DELETE.
141
func AsDelete() PrepareDecorator { return WithMethod("DELETE") }
143
// AsGet returns a PrepareDecorator that sets the HTTP method to GET.
144
func AsGet() PrepareDecorator { return WithMethod("GET") }
146
// AsHead returns a PrepareDecorator that sets the HTTP method to HEAD.
147
func AsHead() PrepareDecorator { return WithMethod("HEAD") }
149
// AsOptions returns a PrepareDecorator that sets the HTTP method to OPTIONS.
150
func AsOptions() PrepareDecorator { return WithMethod("OPTIONS") }
152
// AsPatch returns a PrepareDecorator that sets the HTTP method to PATCH.
153
func AsPatch() PrepareDecorator { return WithMethod("PATCH") }
155
// AsPost returns a PrepareDecorator that sets the HTTP method to POST.
156
func AsPost() PrepareDecorator { return WithMethod("POST") }
158
// AsPut returns a PrepareDecorator that sets the HTTP method to PUT.
159
func AsPut() PrepareDecorator { return WithMethod("PUT") }
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)
168
u, err := url.Parse(baseURL)
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)
186
r.ContentLength = int64(len(s))
187
r.Body = ioutil.NopCloser(strings.NewReader(s))
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)
201
b, err := json.Marshal(v)
203
r.ContentLength = int64(len(b))
204
r.Body = ioutil.NopCloser(bytes.NewReader(b))
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)
220
return r, NewError("autorest", "WithPath", "Invoked with a nil URL")
223
u.Path = strings.TrimRight(u.Path, "/")
224
if strings.HasPrefix(path, "/") {
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)
245
return r, NewError("autorest", "WithEscapedPathParameters", "Invoked with a nil URL")
247
for key, value := range parameters {
248
r.URL.Path = strings.Replace(r.URL.Path, "{"+key+"}", value, -1)
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)
265
return r, NewError("autorest", "WithPathParameters", "Invoked with a nil URL")
267
for key, value := range parameters {
268
r.URL.Path = strings.Replace(r.URL.Path, "{"+key+"}", value, -1)
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)
285
return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL")
288
for key, value := range parameters {
291
r.URL.RawQuery = v.Encode()
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
305
// NullAuthorizer implements a default, "do nothing" Authorizer.
306
type NullAuthorizer struct{}
308
// WithAuthorization returns a PrepareDecorator that does nothing.
309
func (na NullAuthorizer) WithAuthorization() PrepareDecorator {