]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / aws / aws-sdk-go / aws / request / handlers.go
CommitLineData
bae9f6d2
JC
1package request
2
3import (
4 "fmt"
5 "strings"
6)
7
8// A Handlers provides a collection of request handlers for various
9// stages of handling requests.
10type Handlers struct {
11 Validate HandlerList
12 Build HandlerList
13 Sign HandlerList
14 Send HandlerList
15 ValidateResponse HandlerList
16 Unmarshal HandlerList
15c0b25d 17 UnmarshalStream HandlerList
bae9f6d2
JC
18 UnmarshalMeta HandlerList
19 UnmarshalError HandlerList
20 Retry HandlerList
21 AfterRetry HandlerList
107c1cdb 22 CompleteAttempt HandlerList
bae9f6d2
JC
23 Complete HandlerList
24}
25
26// Copy returns of this handler's lists.
27func (h *Handlers) Copy() Handlers {
28 return Handlers{
29 Validate: h.Validate.copy(),
30 Build: h.Build.copy(),
31 Sign: h.Sign.copy(),
32 Send: h.Send.copy(),
33 ValidateResponse: h.ValidateResponse.copy(),
34 Unmarshal: h.Unmarshal.copy(),
15c0b25d 35 UnmarshalStream: h.UnmarshalStream.copy(),
bae9f6d2
JC
36 UnmarshalError: h.UnmarshalError.copy(),
37 UnmarshalMeta: h.UnmarshalMeta.copy(),
38 Retry: h.Retry.copy(),
39 AfterRetry: h.AfterRetry.copy(),
107c1cdb 40 CompleteAttempt: h.CompleteAttempt.copy(),
bae9f6d2
JC
41 Complete: h.Complete.copy(),
42 }
43}
44
45// Clear removes callback functions for all handlers
46func (h *Handlers) Clear() {
47 h.Validate.Clear()
48 h.Build.Clear()
49 h.Send.Clear()
50 h.Sign.Clear()
51 h.Unmarshal.Clear()
15c0b25d 52 h.UnmarshalStream.Clear()
bae9f6d2
JC
53 h.UnmarshalMeta.Clear()
54 h.UnmarshalError.Clear()
55 h.ValidateResponse.Clear()
56 h.Retry.Clear()
57 h.AfterRetry.Clear()
107c1cdb 58 h.CompleteAttempt.Clear()
bae9f6d2
JC
59 h.Complete.Clear()
60}
61
62// A HandlerListRunItem represents an entry in the HandlerList which
63// is being run.
64type HandlerListRunItem struct {
65 Index int
66 Handler NamedHandler
67 Request *Request
68}
69
70// A HandlerList manages zero or more handlers in a list.
71type HandlerList struct {
72 list []NamedHandler
73
74 // Called after each request handler in the list is called. If set
75 // and the func returns true the HandlerList will continue to iterate
76 // over the request handlers. If false is returned the HandlerList
77 // will stop iterating.
78 //
79 // Should be used if extra logic to be performed between each handler
80 // in the list. This can be used to terminate a list's iteration
81 // based on a condition such as error like, HandlerListStopOnError.
82 // Or for logging like HandlerListLogItem.
83 AfterEachFn func(item HandlerListRunItem) bool
84}
85
86// A NamedHandler is a struct that contains a name and function callback.
87type NamedHandler struct {
88 Name string
89 Fn func(*Request)
90}
91
92// copy creates a copy of the handler list.
93func (l *HandlerList) copy() HandlerList {
94 n := HandlerList{
95 AfterEachFn: l.AfterEachFn,
96 }
97 if len(l.list) == 0 {
98 return n
99 }
100
101 n.list = append(make([]NamedHandler, 0, len(l.list)), l.list...)
102 return n
103}
104
105// Clear clears the handler list.
106func (l *HandlerList) Clear() {
107 l.list = l.list[0:0]
108}
109
110// Len returns the number of handlers in the list.
111func (l *HandlerList) Len() int {
112 return len(l.list)
113}
114
115// PushBack pushes handler f to the back of the handler list.
116func (l *HandlerList) PushBack(f func(*Request)) {
117 l.PushBackNamed(NamedHandler{"__anonymous", f})
118}
119
120// PushBackNamed pushes named handler f to the back of the handler list.
121func (l *HandlerList) PushBackNamed(n NamedHandler) {
122 if cap(l.list) == 0 {
123 l.list = make([]NamedHandler, 0, 5)
124 }
125 l.list = append(l.list, n)
126}
127
128// PushFront pushes handler f to the front of the handler list.
129func (l *HandlerList) PushFront(f func(*Request)) {
130 l.PushFrontNamed(NamedHandler{"__anonymous", f})
131}
132
133// PushFrontNamed pushes named handler f to the front of the handler list.
134func (l *HandlerList) PushFrontNamed(n NamedHandler) {
135 if cap(l.list) == len(l.list) {
136 // Allocating new list required
137 l.list = append([]NamedHandler{n}, l.list...)
138 } else {
139 // Enough room to prepend into list.
140 l.list = append(l.list, NamedHandler{})
141 copy(l.list[1:], l.list)
142 l.list[0] = n
143 }
144}
145
146// Remove removes a NamedHandler n
147func (l *HandlerList) Remove(n NamedHandler) {
148 l.RemoveByName(n.Name)
149}
150
151// RemoveByName removes a NamedHandler by name.
152func (l *HandlerList) RemoveByName(name string) {
153 for i := 0; i < len(l.list); i++ {
154 m := l.list[i]
155 if m.Name == name {
156 // Shift array preventing creating new arrays
157 copy(l.list[i:], l.list[i+1:])
158 l.list[len(l.list)-1] = NamedHandler{}
159 l.list = l.list[:len(l.list)-1]
160
161 // decrement list so next check to length is correct
162 i--
163 }
164 }
165}
166
9b12e4fe
JC
167// SwapNamed will swap out any existing handlers with the same name as the
168// passed in NamedHandler returning true if handlers were swapped. False is
169// returned otherwise.
170func (l *HandlerList) SwapNamed(n NamedHandler) (swapped bool) {
171 for i := 0; i < len(l.list); i++ {
172 if l.list[i].Name == n.Name {
173 l.list[i].Fn = n.Fn
174 swapped = true
175 }
176 }
177
178 return swapped
179}
180
15c0b25d
AP
181// Swap will swap out all handlers matching the name passed in. The matched
182// handlers will be swapped in. True is returned if the handlers were swapped.
183func (l *HandlerList) Swap(name string, replace NamedHandler) bool {
184 var swapped bool
185
186 for i := 0; i < len(l.list); i++ {
187 if l.list[i].Name == name {
188 l.list[i] = replace
189 swapped = true
190 }
191 }
192
193 return swapped
194}
195
9b12e4fe
JC
196// SetBackNamed will replace the named handler if it exists in the handler list.
197// If the handler does not exist the handler will be added to the end of the list.
198func (l *HandlerList) SetBackNamed(n NamedHandler) {
199 if !l.SwapNamed(n) {
200 l.PushBackNamed(n)
201 }
202}
203
204// SetFrontNamed will replace the named handler if it exists in the handler list.
205// If the handler does not exist the handler will be added to the beginning of
206// the list.
207func (l *HandlerList) SetFrontNamed(n NamedHandler) {
208 if !l.SwapNamed(n) {
209 l.PushFrontNamed(n)
210 }
211}
212
bae9f6d2
JC
213// Run executes all handlers in the list with a given request object.
214func (l *HandlerList) Run(r *Request) {
215 for i, h := range l.list {
216 h.Fn(r)
217 item := HandlerListRunItem{
218 Index: i, Handler: h, Request: r,
219 }
220 if l.AfterEachFn != nil && !l.AfterEachFn(item) {
221 return
222 }
223 }
224}
225
226// HandlerListLogItem logs the request handler and the state of the
227// request's Error value. Always returns true to continue iterating
228// request handlers in a HandlerList.
229func HandlerListLogItem(item HandlerListRunItem) bool {
230 if item.Request.Config.Logger == nil {
231 return true
232 }
233 item.Request.Config.Logger.Log("DEBUG: RequestHandler",
234 item.Index, item.Handler.Name, item.Request.Error)
235
236 return true
237}
238
239// HandlerListStopOnError returns false to stop the HandlerList iterating
240// over request handlers if Request.Error is not nil. True otherwise
241// to continue iterating.
242func HandlerListStopOnError(item HandlerListRunItem) bool {
243 return item.Request.Error == nil
244}
245
246// WithAppendUserAgent will add a string to the user agent prefixed with a
247// single white space.
248func WithAppendUserAgent(s string) Option {
249 return func(r *Request) {
250 r.Handlers.Build.PushBack(func(r2 *Request) {
251 AddToUserAgent(r, s)
252 })
253 }
254}
255
256// MakeAddToUserAgentHandler will add the name/version pair to the User-Agent request
257// header. If the extra parameters are provided they will be added as metadata to the
258// name/version pair resulting in the following format.
259// "name/version (extra0; extra1; ...)"
260// The user agent part will be concatenated with this current request's user agent string.
261func MakeAddToUserAgentHandler(name, version string, extra ...string) func(*Request) {
262 ua := fmt.Sprintf("%s/%s", name, version)
263 if len(extra) > 0 {
264 ua += fmt.Sprintf(" (%s)", strings.Join(extra, "; "))
265 }
266 return func(r *Request) {
267 AddToUserAgent(r, ua)
268 }
269}
270
271// MakeAddToUserAgentFreeFormHandler adds the input to the User-Agent request header.
272// The input string will be concatenated with the current request's user agent string.
273func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) {
274 return func(r *Request) {
275 AddToUserAgent(r, s)
276 }
277}