...
1 package autorest
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import (
18 "bytes"
19 "encoding/json"
20 "encoding/xml"
21 "fmt"
22 "io"
23 "io/ioutil"
24 "net/http"
25 "strings"
26 )
27
28
29
30
31
32 type Responder interface {
33 Respond(*http.Response) error
34 }
35
36
37 type ResponderFunc func(*http.Response) error
38
39
40 func (rf ResponderFunc) Respond(r *http.Response) error {
41 return rf(r)
42 }
43
44
45
46 type RespondDecorator func(Responder) Responder
47
48
49
50
51
52
53
54
55 func CreateResponder(decorators ...RespondDecorator) Responder {
56 return DecorateResponder(
57 Responder(ResponderFunc(func(r *http.Response) error { return nil })),
58 decorators...)
59 }
60
61
62
63
64
65 func DecorateResponder(r Responder, decorators ...RespondDecorator) Responder {
66 for _, decorate := range decorators {
67 r = decorate(r)
68 }
69 return r
70 }
71
72
73
74 func Respond(r *http.Response, decorators ...RespondDecorator) error {
75 if r == nil {
76 return nil
77 }
78 return CreateResponder(decorators...).Respond(r)
79 }
80
81
82
83 func ByIgnoring() RespondDecorator {
84 return func(r Responder) Responder {
85 return ResponderFunc(func(resp *http.Response) error {
86 return r.Respond(resp)
87 })
88 }
89 }
90
91
92
93 func ByCopying(b *bytes.Buffer) RespondDecorator {
94 return func(r Responder) Responder {
95 return ResponderFunc(func(resp *http.Response) error {
96 err := r.Respond(resp)
97 if err == nil && resp != nil && resp.Body != nil {
98 resp.Body = TeeReadCloser(resp.Body, b)
99 }
100 return err
101 })
102 }
103 }
104
105
106
107
108
109 func ByDiscardingBody() RespondDecorator {
110 return func(r Responder) Responder {
111 return ResponderFunc(func(resp *http.Response) error {
112 err := r.Respond(resp)
113 if err == nil && resp != nil && resp.Body != nil {
114 if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
115 return fmt.Errorf("Error discarding the response body: %v", err)
116 }
117 }
118 return err
119 })
120 }
121 }
122
123
124
125
126 func ByClosing() RespondDecorator {
127 return func(r Responder) Responder {
128 return ResponderFunc(func(resp *http.Response) error {
129 err := r.Respond(resp)
130 if resp != nil && resp.Body != nil {
131 if err := resp.Body.Close(); err != nil {
132 return fmt.Errorf("Error closing the response body: %v", err)
133 }
134 }
135 return err
136 })
137 }
138 }
139
140
141
142 func ByClosingIfError() RespondDecorator {
143 return func(r Responder) Responder {
144 return ResponderFunc(func(resp *http.Response) error {
145 err := r.Respond(resp)
146 if err != nil && resp != nil && resp.Body != nil {
147 if err := resp.Body.Close(); err != nil {
148 return fmt.Errorf("Error closing the response body: %v", err)
149 }
150 }
151 return err
152 })
153 }
154 }
155
156
157
158 func ByUnmarshallingBytes(v *[]byte) RespondDecorator {
159 return func(r Responder) Responder {
160 return ResponderFunc(func(resp *http.Response) error {
161 err := r.Respond(resp)
162 if err == nil {
163 bytes, errInner := ioutil.ReadAll(resp.Body)
164 if errInner != nil {
165 err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner)
166 } else {
167 *v = bytes
168 }
169 }
170 return err
171 })
172 }
173 }
174
175
176
177 func ByUnmarshallingJSON(v interface{}) RespondDecorator {
178 return func(r Responder) Responder {
179 return ResponderFunc(func(resp *http.Response) error {
180 err := r.Respond(resp)
181 if err == nil {
182 b, errInner := ioutil.ReadAll(resp.Body)
183
184 b = bytes.TrimPrefix(b, []byte("\xef\xbb\xbf"))
185 if errInner != nil {
186 err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner)
187 } else if len(strings.Trim(string(b), " ")) > 0 {
188 errInner = json.Unmarshal(b, v)
189 if errInner != nil {
190 err = fmt.Errorf("Error occurred unmarshalling JSON - Error = '%v' JSON = '%s'", errInner, string(b))
191 }
192 }
193 }
194 return err
195 })
196 }
197 }
198
199
200
201 func ByUnmarshallingXML(v interface{}) RespondDecorator {
202 return func(r Responder) Responder {
203 return ResponderFunc(func(resp *http.Response) error {
204 err := r.Respond(resp)
205 if err == nil {
206 b, errInner := ioutil.ReadAll(resp.Body)
207 if errInner != nil {
208 err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner)
209 } else {
210 errInner = xml.Unmarshal(b, v)
211 if errInner != nil {
212 err = fmt.Errorf("Error occurred unmarshalling Xml - Error = '%v' Xml = '%s'", errInner, string(b))
213 }
214 }
215 }
216 return err
217 })
218 }
219 }
220
221
222
223
224 func WithErrorUnlessStatusCode(codes ...int) RespondDecorator {
225 return func(r Responder) Responder {
226 return ResponderFunc(func(resp *http.Response) error {
227 err := r.Respond(resp)
228 if err == nil && !ResponseHasStatusCode(resp, codes...) {
229 derr := NewErrorWithResponse("autorest", "WithErrorUnlessStatusCode", resp, "%v %v failed with %s",
230 resp.Request.Method,
231 resp.Request.URL,
232 resp.Status)
233 if resp.Body != nil {
234 defer resp.Body.Close()
235 b, _ := ioutil.ReadAll(resp.Body)
236 derr.ServiceError = b
237 resp.Body = ioutil.NopCloser(bytes.NewReader(b))
238 }
239 err = derr
240 }
241 return err
242 })
243 }
244 }
245
246
247
248 func WithErrorUnlessOK() RespondDecorator {
249 return WithErrorUnlessStatusCode(http.StatusOK)
250 }
251
252
253
254 func ExtractHeader(header string, resp *http.Response) []string {
255 if resp != nil && resp.Header != nil {
256 return resp.Header[http.CanonicalHeaderKey(header)]
257 }
258 return nil
259 }
260
261
262
263 func ExtractHeaderValue(header string, resp *http.Response) string {
264 h := ExtractHeader(header, resp)
265 if len(h) > 0 {
266 return h[0]
267 }
268 return ""
269 }
270
View as plain text