diff options
Diffstat (limited to 'vendor/google.golang.org/api/googleapi/googleapi.go')
-rw-r--r-- | vendor/google.golang.org/api/googleapi/googleapi.go | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/vendor/google.golang.org/api/googleapi/googleapi.go b/vendor/google.golang.org/api/googleapi/googleapi.go new file mode 100644 index 0000000..8cdb03b --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/googleapi.go | |||
@@ -0,0 +1,429 @@ | |||
1 | // Copyright 2011 Google Inc. All rights reserved. | ||
2 | // Use of this source code is governed by a BSD-style | ||
3 | // license that can be found in the LICENSE file. | ||
4 | |||
5 | // Package googleapi contains the common code shared by all Google API | ||
6 | // libraries. | ||
7 | package googleapi // import "google.golang.org/api/googleapi" | ||
8 | |||
9 | import ( | ||
10 | "bytes" | ||
11 | "encoding/json" | ||
12 | "fmt" | ||
13 | "io" | ||
14 | "io/ioutil" | ||
15 | "net/http" | ||
16 | "net/url" | ||
17 | "strings" | ||
18 | |||
19 | "google.golang.org/api/googleapi/internal/uritemplates" | ||
20 | ) | ||
21 | |||
22 | // ContentTyper is an interface for Readers which know (or would like | ||
23 | // to override) their Content-Type. If a media body doesn't implement | ||
24 | // ContentTyper, the type is sniffed from the content using | ||
25 | // http.DetectContentType. | ||
26 | type ContentTyper interface { | ||
27 | ContentType() string | ||
28 | } | ||
29 | |||
30 | // A SizeReaderAt is a ReaderAt with a Size method. | ||
31 | // An io.SectionReader implements SizeReaderAt. | ||
32 | type SizeReaderAt interface { | ||
33 | io.ReaderAt | ||
34 | Size() int64 | ||
35 | } | ||
36 | |||
37 | // ServerResponse is embedded in each Do response and | ||
38 | // provides the HTTP status code and header sent by the server. | ||
39 | type ServerResponse struct { | ||
40 | // HTTPStatusCode is the server's response status code. When using a | ||
41 | // resource method's Do call, this will always be in the 2xx range. | ||
42 | HTTPStatusCode int | ||
43 | // Header contains the response header fields from the server. | ||
44 | Header http.Header | ||
45 | } | ||
46 | |||
47 | const ( | ||
48 | // Version defines the gax version being used. This is typically sent | ||
49 | // in an HTTP header to services. | ||
50 | Version = "0.5" | ||
51 | |||
52 | // UserAgent is the header string used to identify this package. | ||
53 | UserAgent = "google-api-go-client/" + Version | ||
54 | |||
55 | // DefaultUploadChunkSize is the default chunk size to use for resumable | ||
56 | // uploads if not specified by the user. | ||
57 | DefaultUploadChunkSize = 8 * 1024 * 1024 | ||
58 | |||
59 | // MinUploadChunkSize is the minimum chunk size that can be used for | ||
60 | // resumable uploads. All user-specified chunk sizes must be multiple of | ||
61 | // this value. | ||
62 | MinUploadChunkSize = 256 * 1024 | ||
63 | ) | ||
64 | |||
65 | // Error contains an error response from the server. | ||
66 | type Error struct { | ||
67 | // Code is the HTTP response status code and will always be populated. | ||
68 | Code int `json:"code"` | ||
69 | // Message is the server response message and is only populated when | ||
70 | // explicitly referenced by the JSON server response. | ||
71 | Message string `json:"message"` | ||
72 | // Body is the raw response returned by the server. | ||
73 | // It is often but not always JSON, depending on how the request fails. | ||
74 | Body string | ||
75 | // Header contains the response header fields from the server. | ||
76 | Header http.Header | ||
77 | |||
78 | Errors []ErrorItem | ||
79 | } | ||
80 | |||
81 | // ErrorItem is a detailed error code & message from the Google API frontend. | ||
82 | type ErrorItem struct { | ||
83 | // Reason is the typed error code. For example: "some_example". | ||
84 | Reason string `json:"reason"` | ||
85 | // Message is the human-readable description of the error. | ||
86 | Message string `json:"message"` | ||
87 | } | ||
88 | |||
89 | func (e *Error) Error() string { | ||
90 | if len(e.Errors) == 0 && e.Message == "" { | ||
91 | return fmt.Sprintf("googleapi: got HTTP response code %d with body: %v", e.Code, e.Body) | ||
92 | } | ||
93 | var buf bytes.Buffer | ||
94 | fmt.Fprintf(&buf, "googleapi: Error %d: ", e.Code) | ||
95 | if e.Message != "" { | ||
96 | fmt.Fprintf(&buf, "%s", e.Message) | ||
97 | } | ||
98 | if len(e.Errors) == 0 { | ||
99 | return strings.TrimSpace(buf.String()) | ||
100 | } | ||
101 | if len(e.Errors) == 1 && e.Errors[0].Message == e.Message { | ||
102 | fmt.Fprintf(&buf, ", %s", e.Errors[0].Reason) | ||
103 | return buf.String() | ||
104 | } | ||
105 | fmt.Fprintln(&buf, "\nMore details:") | ||
106 | for _, v := range e.Errors { | ||
107 | fmt.Fprintf(&buf, "Reason: %s, Message: %s\n", v.Reason, v.Message) | ||
108 | } | ||
109 | return buf.String() | ||
110 | } | ||
111 | |||
112 | type errorReply struct { | ||
113 | Error *Error `json:"error"` | ||
114 | } | ||
115 | |||
116 | // CheckResponse returns an error (of type *Error) if the response | ||
117 | // status code is not 2xx. | ||
118 | func CheckResponse(res *http.Response) error { | ||
119 | if res.StatusCode >= 200 && res.StatusCode <= 299 { | ||
120 | return nil | ||
121 | } | ||
122 | slurp, err := ioutil.ReadAll(res.Body) | ||
123 | if err == nil { | ||
124 | jerr := new(errorReply) | ||
125 | err = json.Unmarshal(slurp, jerr) | ||
126 | if err == nil && jerr.Error != nil { | ||
127 | if jerr.Error.Code == 0 { | ||
128 | jerr.Error.Code = res.StatusCode | ||
129 | } | ||
130 | jerr.Error.Body = string(slurp) | ||
131 | return jerr.Error | ||
132 | } | ||
133 | } | ||
134 | return &Error{ | ||
135 | Code: res.StatusCode, | ||
136 | Body: string(slurp), | ||
137 | Header: res.Header, | ||
138 | } | ||
139 | } | ||
140 | |||
141 | // IsNotModified reports whether err is the result of the | ||
142 | // server replying with http.StatusNotModified. | ||
143 | // Such error values are sometimes returned by "Do" methods | ||
144 | // on calls when If-None-Match is used. | ||
145 | func IsNotModified(err error) bool { | ||
146 | if err == nil { | ||
147 | return false | ||
148 | } | ||
149 | ae, ok := err.(*Error) | ||
150 | return ok && ae.Code == http.StatusNotModified | ||
151 | } | ||
152 | |||
153 | // CheckMediaResponse returns an error (of type *Error) if the response | ||
154 | // status code is not 2xx. Unlike CheckResponse it does not assume the | ||
155 | // body is a JSON error document. | ||
156 | // It is the caller's responsibility to close res.Body. | ||
157 | func CheckMediaResponse(res *http.Response) error { | ||
158 | if res.StatusCode >= 200 && res.StatusCode <= 299 { | ||
159 | return nil | ||
160 | } | ||
161 | slurp, _ := ioutil.ReadAll(io.LimitReader(res.Body, 1<<20)) | ||
162 | return &Error{ | ||
163 | Code: res.StatusCode, | ||
164 | Body: string(slurp), | ||
165 | } | ||
166 | } | ||
167 | |||
168 | // MarshalStyle defines whether to marshal JSON with a {"data": ...} wrapper. | ||
169 | type MarshalStyle bool | ||
170 | |||
171 | // WithDataWrapper marshals JSON with a {"data": ...} wrapper. | ||
172 | var WithDataWrapper = MarshalStyle(true) | ||
173 | |||
174 | // WithoutDataWrapper marshals JSON without a {"data": ...} wrapper. | ||
175 | var WithoutDataWrapper = MarshalStyle(false) | ||
176 | |||
177 | func (wrap MarshalStyle) JSONReader(v interface{}) (io.Reader, error) { | ||
178 | buf := new(bytes.Buffer) | ||
179 | if wrap { | ||
180 | buf.Write([]byte(`{"data": `)) | ||
181 | } | ||
182 | err := json.NewEncoder(buf).Encode(v) | ||
183 | if err != nil { | ||
184 | return nil, err | ||
185 | } | ||
186 | if wrap { | ||
187 | buf.Write([]byte(`}`)) | ||
188 | } | ||
189 | return buf, nil | ||
190 | } | ||
191 | |||
192 | // endingWithErrorReader from r until it returns an error. If the | ||
193 | // final error from r is io.EOF and e is non-nil, e is used instead. | ||
194 | type endingWithErrorReader struct { | ||
195 | r io.Reader | ||
196 | e error | ||
197 | } | ||
198 | |||
199 | func (er endingWithErrorReader) Read(p []byte) (n int, err error) { | ||
200 | n, err = er.r.Read(p) | ||
201 | if err == io.EOF && er.e != nil { | ||
202 | err = er.e | ||
203 | } | ||
204 | return | ||
205 | } | ||
206 | |||
207 | // countingWriter counts the number of bytes it receives to write, but | ||
208 | // discards them. | ||
209 | type countingWriter struct { | ||
210 | n *int64 | ||
211 | } | ||
212 | |||
213 | func (w countingWriter) Write(p []byte) (int, error) { | ||
214 | *w.n += int64(len(p)) | ||
215 | return len(p), nil | ||
216 | } | ||
217 | |||
218 | // ProgressUpdater is a function that is called upon every progress update of a resumable upload. | ||
219 | // This is the only part of a resumable upload (from googleapi) that is usable by the developer. | ||
220 | // The remaining usable pieces of resumable uploads is exposed in each auto-generated API. | ||
221 | type ProgressUpdater func(current, total int64) | ||
222 | |||
223 | // MediaOption defines the interface for setting media options. | ||
224 | type MediaOption interface { | ||
225 | setOptions(o *MediaOptions) | ||
226 | } | ||
227 | |||
228 | type contentTypeOption string | ||
229 | |||
230 | func (ct contentTypeOption) setOptions(o *MediaOptions) { | ||
231 | o.ContentType = string(ct) | ||
232 | if o.ContentType == "" { | ||
233 | o.ForceEmptyContentType = true | ||
234 | } | ||
235 | } | ||
236 | |||
237 | // ContentType returns a MediaOption which sets the Content-Type header for media uploads. | ||
238 | // If ctype is empty, the Content-Type header will be omitted. | ||
239 | func ContentType(ctype string) MediaOption { | ||
240 | return contentTypeOption(ctype) | ||
241 | } | ||
242 | |||
243 | type chunkSizeOption int | ||
244 | |||
245 | func (cs chunkSizeOption) setOptions(o *MediaOptions) { | ||
246 | size := int(cs) | ||
247 | if size%MinUploadChunkSize != 0 { | ||
248 | size += MinUploadChunkSize - (size % MinUploadChunkSize) | ||
249 | } | ||
250 | o.ChunkSize = size | ||
251 | } | ||
252 | |||
253 | // ChunkSize returns a MediaOption which sets the chunk size for media uploads. | ||
254 | // size will be rounded up to the nearest multiple of 256K. | ||
255 | // Media which contains fewer than size bytes will be uploaded in a single request. | ||
256 | // Media which contains size bytes or more will be uploaded in separate chunks. | ||
257 | // If size is zero, media will be uploaded in a single request. | ||
258 | func ChunkSize(size int) MediaOption { | ||
259 | return chunkSizeOption(size) | ||
260 | } | ||
261 | |||
262 | // MediaOptions stores options for customizing media upload. It is not used by developers directly. | ||
263 | type MediaOptions struct { | ||
264 | ContentType string | ||
265 | ForceEmptyContentType bool | ||
266 | |||
267 | ChunkSize int | ||
268 | } | ||
269 | |||
270 | // ProcessMediaOptions stores options from opts in a MediaOptions. | ||
271 | // It is not used by developers directly. | ||
272 | func ProcessMediaOptions(opts []MediaOption) *MediaOptions { | ||
273 | mo := &MediaOptions{ChunkSize: DefaultUploadChunkSize} | ||
274 | for _, o := range opts { | ||
275 | o.setOptions(mo) | ||
276 | } | ||
277 | return mo | ||
278 | } | ||
279 | |||
280 | // ResolveRelative resolves relatives such as "http://www.golang.org/" and | ||
281 | // "topics/myproject/mytopic" into a single string, such as | ||
282 | // "http://www.golang.org/topics/myproject/mytopic". It strips all parent | ||
283 | // references (e.g. ../..) as well as anything after the host | ||
284 | // (e.g. /bar/gaz gets stripped out of foo.com/bar/gaz). | ||
285 | func ResolveRelative(basestr, relstr string) string { | ||
286 | u, _ := url.Parse(basestr) | ||
287 | afterColonPath := "" | ||
288 | if i := strings.IndexRune(relstr, ':'); i > 0 { | ||
289 | afterColonPath = relstr[i+1:] | ||
290 | relstr = relstr[:i] | ||
291 | } | ||
292 | rel, _ := url.Parse(relstr) | ||
293 | u = u.ResolveReference(rel) | ||
294 | us := u.String() | ||
295 | if afterColonPath != "" { | ||
296 | us = fmt.Sprintf("%s:%s", us, afterColonPath) | ||
297 | } | ||
298 | us = strings.Replace(us, "%7B", "{", -1) | ||
299 | us = strings.Replace(us, "%7D", "}", -1) | ||
300 | us = strings.Replace(us, "%2A", "*", -1) | ||
301 | return us | ||
302 | } | ||
303 | |||
304 | // Expand subsitutes any {encoded} strings in the URL passed in using | ||
305 | // the map supplied. | ||
306 | // | ||
307 | // This calls SetOpaque to avoid encoding of the parameters in the URL path. | ||
308 | func Expand(u *url.URL, expansions map[string]string) { | ||
309 | escaped, unescaped, err := uritemplates.Expand(u.Path, expansions) | ||
310 | if err == nil { | ||
311 | u.Path = unescaped | ||
312 | u.RawPath = escaped | ||
313 | } | ||
314 | } | ||
315 | |||
316 | // CloseBody is used to close res.Body. | ||
317 | // Prior to calling Close, it also tries to Read a small amount to see an EOF. | ||
318 | // Not seeing an EOF can prevent HTTP Transports from reusing connections. | ||
319 | func CloseBody(res *http.Response) { | ||
320 | if res == nil || res.Body == nil { | ||
321 | return | ||
322 | } | ||
323 | // Justification for 3 byte reads: two for up to "\r\n" after | ||
324 | // a JSON/XML document, and then 1 to see EOF if we haven't yet. | ||
325 | // TODO(bradfitz): detect Go 1.3+ and skip these reads. | ||
326 | // See https://codereview.appspot.com/58240043 | ||
327 | // and https://codereview.appspot.com/49570044 | ||
328 | buf := make([]byte, 1) | ||
329 | for i := 0; i < 3; i++ { | ||
330 | _, err := res.Body.Read(buf) | ||
331 | if err != nil { | ||
332 | break | ||
333 | } | ||
334 | } | ||
335 | res.Body.Close() | ||
336 | |||
337 | } | ||
338 | |||
339 | // VariantType returns the type name of the given variant. | ||
340 | // If the map doesn't contain the named key or the value is not a []interface{}, "" is returned. | ||
341 | // This is used to support "variant" APIs that can return one of a number of different types. | ||
342 | func VariantType(t map[string]interface{}) string { | ||
343 | s, _ := t["type"].(string) | ||
344 | return s | ||
345 | } | ||
346 | |||
347 | // ConvertVariant uses the JSON encoder/decoder to fill in the struct 'dst' with the fields found in variant 'v'. | ||
348 | // This is used to support "variant" APIs that can return one of a number of different types. | ||
349 | // It reports whether the conversion was successful. | ||
350 | func ConvertVariant(v map[string]interface{}, dst interface{}) bool { | ||
351 | var buf bytes.Buffer | ||
352 | err := json.NewEncoder(&buf).Encode(v) | ||
353 | if err != nil { | ||
354 | return false | ||
355 | } | ||
356 | return json.Unmarshal(buf.Bytes(), dst) == nil | ||
357 | } | ||
358 | |||
359 | // A Field names a field to be retrieved with a partial response. | ||
360 | // See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse | ||
361 | // | ||
362 | // Partial responses can dramatically reduce the amount of data that must be sent to your application. | ||
363 | // In order to request partial responses, you can specify the full list of fields | ||
364 | // that your application needs by adding the Fields option to your request. | ||
365 | // | ||
366 | // Field strings use camelCase with leading lower-case characters to identify fields within the response. | ||
367 | // | ||
368 | // For example, if your response has a "NextPageToken" and a slice of "Items" with "Id" fields, | ||
369 | // you could request just those fields like this: | ||
370 | // | ||
371 | // svc.Events.List().Fields("nextPageToken", "items/id").Do() | ||
372 | // | ||
373 | // or if you were also interested in each Item's "Updated" field, you can combine them like this: | ||
374 | // | ||
375 | // svc.Events.List().Fields("nextPageToken", "items(id,updated)").Do() | ||
376 | // | ||
377 | // More information about field formatting can be found here: | ||
378 | // https://developers.google.com/+/api/#fields-syntax | ||
379 | // | ||
380 | // Another way to find field names is through the Google API explorer: | ||
381 | // https://developers.google.com/apis-explorer/#p/ | ||
382 | type Field string | ||
383 | |||
384 | // CombineFields combines fields into a single string. | ||
385 | func CombineFields(s []Field) string { | ||
386 | r := make([]string, len(s)) | ||
387 | for i, v := range s { | ||
388 | r[i] = string(v) | ||
389 | } | ||
390 | return strings.Join(r, ",") | ||
391 | } | ||
392 | |||
393 | // A CallOption is an optional argument to an API call. | ||
394 | // It should be treated as an opaque value by users of Google APIs. | ||
395 | // | ||
396 | // A CallOption is something that configures an API call in a way that is | ||
397 | // not specific to that API; for instance, controlling the quota user for | ||
398 | // an API call is common across many APIs, and is thus a CallOption. | ||
399 | type CallOption interface { | ||
400 | Get() (key, value string) | ||
401 | } | ||
402 | |||
403 | // QuotaUser returns a CallOption that will set the quota user for a call. | ||
404 | // The quota user can be used by server-side applications to control accounting. | ||
405 | // It can be an arbitrary string up to 40 characters, and will override UserIP | ||
406 | // if both are provided. | ||
407 | func QuotaUser(u string) CallOption { return quotaUser(u) } | ||
408 | |||
409 | type quotaUser string | ||
410 | |||
411 | func (q quotaUser) Get() (string, string) { return "quotaUser", string(q) } | ||
412 | |||
413 | // UserIP returns a CallOption that will set the "userIp" parameter of a call. | ||
414 | // This should be the IP address of the originating request. | ||
415 | func UserIP(ip string) CallOption { return userIP(ip) } | ||
416 | |||
417 | type userIP string | ||
418 | |||
419 | func (i userIP) Get() (string, string) { return "userIp", string(i) } | ||
420 | |||
421 | // Trace returns a CallOption that enables diagnostic tracing for a call. | ||
422 | // traceToken is an ID supplied by Google support. | ||
423 | func Trace(traceToken string) CallOption { return traceTok(traceToken) } | ||
424 | |||
425 | type traceTok string | ||
426 | |||
427 | func (t traceTok) Get() (string, string) { return "trace", "token:" + string(t) } | ||
428 | |||
429 | // TODO: Fields too | ||