diff options
Diffstat (limited to 'vendor/google.golang.org/api/googleapi')
6 files changed, 952 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 | ||
diff --git a/vendor/google.golang.org/api/googleapi/internal/uritemplates/LICENSE b/vendor/google.golang.org/api/googleapi/internal/uritemplates/LICENSE new file mode 100644 index 0000000..de9c88c --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/internal/uritemplates/LICENSE | |||
@@ -0,0 +1,18 @@ | |||
1 | Copyright (c) 2013 Joshua Tacoma | ||
2 | |||
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
4 | this software and associated documentation files (the "Software"), to deal in | ||
5 | the Software without restriction, including without limitation the rights to | ||
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
7 | the Software, and to permit persons to whom the Software is furnished to do so, | ||
8 | subject to the following conditions: | ||
9 | |||
10 | The above copyright notice and this permission notice shall be included in all | ||
11 | copies or substantial portions of the Software. | ||
12 | |||
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
diff --git a/vendor/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go b/vendor/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go new file mode 100644 index 0000000..63bf053 --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go | |||
@@ -0,0 +1,248 @@ | |||
1 | // Copyright 2013 Joshua Tacoma. 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 uritemplates is a level 3 implementation of RFC 6570 (URI | ||
6 | // Template, http://tools.ietf.org/html/rfc6570). | ||
7 | // uritemplates does not support composite values (in Go: slices or maps) | ||
8 | // and so does not qualify as a level 4 implementation. | ||
9 | package uritemplates | ||
10 | |||
11 | import ( | ||
12 | "bytes" | ||
13 | "errors" | ||
14 | "regexp" | ||
15 | "strconv" | ||
16 | "strings" | ||
17 | ) | ||
18 | |||
19 | var ( | ||
20 | unreserved = regexp.MustCompile("[^A-Za-z0-9\\-._~]") | ||
21 | reserved = regexp.MustCompile("[^A-Za-z0-9\\-._~:/?#[\\]@!$&'()*+,;=]") | ||
22 | validname = regexp.MustCompile("^([A-Za-z0-9_\\.]|%[0-9A-Fa-f][0-9A-Fa-f])+$") | ||
23 | hex = []byte("0123456789ABCDEF") | ||
24 | ) | ||
25 | |||
26 | func pctEncode(src []byte) []byte { | ||
27 | dst := make([]byte, len(src)*3) | ||
28 | for i, b := range src { | ||
29 | buf := dst[i*3 : i*3+3] | ||
30 | buf[0] = 0x25 | ||
31 | buf[1] = hex[b/16] | ||
32 | buf[2] = hex[b%16] | ||
33 | } | ||
34 | return dst | ||
35 | } | ||
36 | |||
37 | // pairWriter is a convenience struct which allows escaped and unescaped | ||
38 | // versions of the template to be written in parallel. | ||
39 | type pairWriter struct { | ||
40 | escaped, unescaped bytes.Buffer | ||
41 | } | ||
42 | |||
43 | // Write writes the provided string directly without any escaping. | ||
44 | func (w *pairWriter) Write(s string) { | ||
45 | w.escaped.WriteString(s) | ||
46 | w.unescaped.WriteString(s) | ||
47 | } | ||
48 | |||
49 | // Escape writes the provided string, escaping the string for the | ||
50 | // escaped output. | ||
51 | func (w *pairWriter) Escape(s string, allowReserved bool) { | ||
52 | w.unescaped.WriteString(s) | ||
53 | if allowReserved { | ||
54 | w.escaped.Write(reserved.ReplaceAllFunc([]byte(s), pctEncode)) | ||
55 | } else { | ||
56 | w.escaped.Write(unreserved.ReplaceAllFunc([]byte(s), pctEncode)) | ||
57 | } | ||
58 | } | ||
59 | |||
60 | // Escaped returns the escaped string. | ||
61 | func (w *pairWriter) Escaped() string { | ||
62 | return w.escaped.String() | ||
63 | } | ||
64 | |||
65 | // Unescaped returns the unescaped string. | ||
66 | func (w *pairWriter) Unescaped() string { | ||
67 | return w.unescaped.String() | ||
68 | } | ||
69 | |||
70 | // A uriTemplate is a parsed representation of a URI template. | ||
71 | type uriTemplate struct { | ||
72 | raw string | ||
73 | parts []templatePart | ||
74 | } | ||
75 | |||
76 | // parse parses a URI template string into a uriTemplate object. | ||
77 | func parse(rawTemplate string) (*uriTemplate, error) { | ||
78 | split := strings.Split(rawTemplate, "{") | ||
79 | parts := make([]templatePart, len(split)*2-1) | ||
80 | for i, s := range split { | ||
81 | if i == 0 { | ||
82 | if strings.Contains(s, "}") { | ||
83 | return nil, errors.New("unexpected }") | ||
84 | } | ||
85 | parts[i].raw = s | ||
86 | continue | ||
87 | } | ||
88 | subsplit := strings.Split(s, "}") | ||
89 | if len(subsplit) != 2 { | ||
90 | return nil, errors.New("malformed template") | ||
91 | } | ||
92 | expression := subsplit[0] | ||
93 | var err error | ||
94 | parts[i*2-1], err = parseExpression(expression) | ||
95 | if err != nil { | ||
96 | return nil, err | ||
97 | } | ||
98 | parts[i*2].raw = subsplit[1] | ||
99 | } | ||
100 | return &uriTemplate{ | ||
101 | raw: rawTemplate, | ||
102 | parts: parts, | ||
103 | }, nil | ||
104 | } | ||
105 | |||
106 | type templatePart struct { | ||
107 | raw string | ||
108 | terms []templateTerm | ||
109 | first string | ||
110 | sep string | ||
111 | named bool | ||
112 | ifemp string | ||
113 | allowReserved bool | ||
114 | } | ||
115 | |||
116 | type templateTerm struct { | ||
117 | name string | ||
118 | explode bool | ||
119 | truncate int | ||
120 | } | ||
121 | |||
122 | func parseExpression(expression string) (result templatePart, err error) { | ||
123 | switch expression[0] { | ||
124 | case '+': | ||
125 | result.sep = "," | ||
126 | result.allowReserved = true | ||
127 | expression = expression[1:] | ||
128 | case '.': | ||
129 | result.first = "." | ||
130 | result.sep = "." | ||
131 | expression = expression[1:] | ||
132 | case '/': | ||
133 | result.first = "/" | ||
134 | result.sep = "/" | ||
135 | expression = expression[1:] | ||
136 | case ';': | ||
137 | result.first = ";" | ||
138 | result.sep = ";" | ||
139 | result.named = true | ||
140 | expression = expression[1:] | ||
141 | case '?': | ||
142 | result.first = "?" | ||
143 | result.sep = "&" | ||
144 | result.named = true | ||
145 | result.ifemp = "=" | ||
146 | expression = expression[1:] | ||
147 | case '&': | ||
148 | result.first = "&" | ||
149 | result.sep = "&" | ||
150 | result.named = true | ||
151 | result.ifemp = "=" | ||
152 | expression = expression[1:] | ||
153 | case '#': | ||
154 | result.first = "#" | ||
155 | result.sep = "," | ||
156 | result.allowReserved = true | ||
157 | expression = expression[1:] | ||
158 | default: | ||
159 | result.sep = "," | ||
160 | } | ||
161 | rawterms := strings.Split(expression, ",") | ||
162 | result.terms = make([]templateTerm, len(rawterms)) | ||
163 | for i, raw := range rawterms { | ||
164 | result.terms[i], err = parseTerm(raw) | ||
165 | if err != nil { | ||
166 | break | ||
167 | } | ||
168 | } | ||
169 | return result, err | ||
170 | } | ||
171 | |||
172 | func parseTerm(term string) (result templateTerm, err error) { | ||
173 | // TODO(djd): Remove "*" suffix parsing once we check that no APIs have | ||
174 | // mistakenly used that attribute. | ||
175 | if strings.HasSuffix(term, "*") { | ||
176 | result.explode = true | ||
177 | term = term[:len(term)-1] | ||
178 | } | ||
179 | split := strings.Split(term, ":") | ||
180 | if len(split) == 1 { | ||
181 | result.name = term | ||
182 | } else if len(split) == 2 { | ||
183 | result.name = split[0] | ||
184 | var parsed int64 | ||
185 | parsed, err = strconv.ParseInt(split[1], 10, 0) | ||
186 | result.truncate = int(parsed) | ||
187 | } else { | ||
188 | err = errors.New("multiple colons in same term") | ||
189 | } | ||
190 | if !validname.MatchString(result.name) { | ||
191 | err = errors.New("not a valid name: " + result.name) | ||
192 | } | ||
193 | if result.explode && result.truncate > 0 { | ||
194 | err = errors.New("both explode and prefix modifers on same term") | ||
195 | } | ||
196 | return result, err | ||
197 | } | ||
198 | |||
199 | // Expand expands a URI template with a set of values to produce the | ||
200 | // resultant URI. Two forms of the result are returned: one with all the | ||
201 | // elements escaped, and one with the elements unescaped. | ||
202 | func (t *uriTemplate) Expand(values map[string]string) (escaped, unescaped string) { | ||
203 | var w pairWriter | ||
204 | for _, p := range t.parts { | ||
205 | p.expand(&w, values) | ||
206 | } | ||
207 | return w.Escaped(), w.Unescaped() | ||
208 | } | ||
209 | |||
210 | func (tp *templatePart) expand(w *pairWriter, values map[string]string) { | ||
211 | if len(tp.raw) > 0 { | ||
212 | w.Write(tp.raw) | ||
213 | return | ||
214 | } | ||
215 | var first = true | ||
216 | for _, term := range tp.terms { | ||
217 | value, exists := values[term.name] | ||
218 | if !exists { | ||
219 | continue | ||
220 | } | ||
221 | if first { | ||
222 | w.Write(tp.first) | ||
223 | first = false | ||
224 | } else { | ||
225 | w.Write(tp.sep) | ||
226 | } | ||
227 | tp.expandString(w, term, value) | ||
228 | } | ||
229 | } | ||
230 | |||
231 | func (tp *templatePart) expandName(w *pairWriter, name string, empty bool) { | ||
232 | if tp.named { | ||
233 | w.Write(name) | ||
234 | if empty { | ||
235 | w.Write(tp.ifemp) | ||
236 | } else { | ||
237 | w.Write("=") | ||
238 | } | ||
239 | } | ||
240 | } | ||
241 | |||
242 | func (tp *templatePart) expandString(w *pairWriter, t templateTerm, s string) { | ||
243 | if len(s) > t.truncate && t.truncate > 0 { | ||
244 | s = s[:t.truncate] | ||
245 | } | ||
246 | tp.expandName(w, t.name, len(s) == 0) | ||
247 | w.Escape(s, tp.allowReserved) | ||
248 | } | ||
diff --git a/vendor/google.golang.org/api/googleapi/internal/uritemplates/utils.go b/vendor/google.golang.org/api/googleapi/internal/uritemplates/utils.go new file mode 100644 index 0000000..2e70b81 --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/internal/uritemplates/utils.go | |||
@@ -0,0 +1,17 @@ | |||
1 | // Copyright 2016 The Go Authors. 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 uritemplates | ||
6 | |||
7 | // Expand parses then expands a URI template with a set of values to produce | ||
8 | // the resultant URI. Two forms of the result are returned: one with all the | ||
9 | // elements escaped, and one with the elements unescaped. | ||
10 | func Expand(path string, values map[string]string) (escaped, unescaped string, err error) { | ||
11 | template, err := parse(path) | ||
12 | if err != nil { | ||
13 | return "", "", err | ||
14 | } | ||
15 | escaped, unescaped = template.Expand(values) | ||
16 | return escaped, unescaped, nil | ||
17 | } | ||
diff --git a/vendor/google.golang.org/api/googleapi/transport/apikey.go b/vendor/google.golang.org/api/googleapi/transport/apikey.go new file mode 100644 index 0000000..eca1ea2 --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/transport/apikey.go | |||
@@ -0,0 +1,38 @@ | |||
1 | // Copyright 2012 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 transport contains HTTP transports used to make | ||
6 | // authenticated API requests. | ||
7 | package transport | ||
8 | |||
9 | import ( | ||
10 | "errors" | ||
11 | "net/http" | ||
12 | ) | ||
13 | |||
14 | // APIKey is an HTTP Transport which wraps an underlying transport and | ||
15 | // appends an API Key "key" parameter to the URL of outgoing requests. | ||
16 | type APIKey struct { | ||
17 | // Key is the API Key to set on requests. | ||
18 | Key string | ||
19 | |||
20 | // Transport is the underlying HTTP transport. | ||
21 | // If nil, http.DefaultTransport is used. | ||
22 | Transport http.RoundTripper | ||
23 | } | ||
24 | |||
25 | func (t *APIKey) RoundTrip(req *http.Request) (*http.Response, error) { | ||
26 | rt := t.Transport | ||
27 | if rt == nil { | ||
28 | rt = http.DefaultTransport | ||
29 | if rt == nil { | ||
30 | return nil, errors.New("googleapi/transport: no Transport specified or available") | ||
31 | } | ||
32 | } | ||
33 | newReq := *req | ||
34 | args := newReq.URL.Query() | ||
35 | args.Set("key", t.Key) | ||
36 | newReq.URL.RawQuery = args.Encode() | ||
37 | return rt.RoundTrip(&newReq) | ||
38 | } | ||
diff --git a/vendor/google.golang.org/api/googleapi/types.go b/vendor/google.golang.org/api/googleapi/types.go new file mode 100644 index 0000000..a280e30 --- /dev/null +++ b/vendor/google.golang.org/api/googleapi/types.go | |||
@@ -0,0 +1,202 @@ | |||
1 | // Copyright 2013 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 | ||
6 | |||
7 | import ( | ||
8 | "encoding/json" | ||
9 | "errors" | ||
10 | "strconv" | ||
11 | ) | ||
12 | |||
13 | // Int64s is a slice of int64s that marshal as quoted strings in JSON. | ||
14 | type Int64s []int64 | ||
15 | |||
16 | func (q *Int64s) UnmarshalJSON(raw []byte) error { | ||
17 | *q = (*q)[:0] | ||
18 | var ss []string | ||
19 | if err := json.Unmarshal(raw, &ss); err != nil { | ||
20 | return err | ||
21 | } | ||
22 | for _, s := range ss { | ||
23 | v, err := strconv.ParseInt(s, 10, 64) | ||
24 | if err != nil { | ||
25 | return err | ||
26 | } | ||
27 | *q = append(*q, int64(v)) | ||
28 | } | ||
29 | return nil | ||
30 | } | ||
31 | |||
32 | // Int32s is a slice of int32s that marshal as quoted strings in JSON. | ||
33 | type Int32s []int32 | ||
34 | |||
35 | func (q *Int32s) UnmarshalJSON(raw []byte) error { | ||
36 | *q = (*q)[:0] | ||
37 | var ss []string | ||
38 | if err := json.Unmarshal(raw, &ss); err != nil { | ||
39 | return err | ||
40 | } | ||
41 | for _, s := range ss { | ||
42 | v, err := strconv.ParseInt(s, 10, 32) | ||
43 | if err != nil { | ||
44 | return err | ||
45 | } | ||
46 | *q = append(*q, int32(v)) | ||
47 | } | ||
48 | return nil | ||
49 | } | ||
50 | |||
51 | // Uint64s is a slice of uint64s that marshal as quoted strings in JSON. | ||
52 | type Uint64s []uint64 | ||
53 | |||
54 | func (q *Uint64s) UnmarshalJSON(raw []byte) error { | ||
55 | *q = (*q)[:0] | ||
56 | var ss []string | ||
57 | if err := json.Unmarshal(raw, &ss); err != nil { | ||
58 | return err | ||
59 | } | ||
60 | for _, s := range ss { | ||
61 | v, err := strconv.ParseUint(s, 10, 64) | ||
62 | if err != nil { | ||
63 | return err | ||
64 | } | ||
65 | *q = append(*q, uint64(v)) | ||
66 | } | ||
67 | return nil | ||
68 | } | ||
69 | |||
70 | // Uint32s is a slice of uint32s that marshal as quoted strings in JSON. | ||
71 | type Uint32s []uint32 | ||
72 | |||
73 | func (q *Uint32s) UnmarshalJSON(raw []byte) error { | ||
74 | *q = (*q)[:0] | ||
75 | var ss []string | ||
76 | if err := json.Unmarshal(raw, &ss); err != nil { | ||
77 | return err | ||
78 | } | ||
79 | for _, s := range ss { | ||
80 | v, err := strconv.ParseUint(s, 10, 32) | ||
81 | if err != nil { | ||
82 | return err | ||
83 | } | ||
84 | *q = append(*q, uint32(v)) | ||
85 | } | ||
86 | return nil | ||
87 | } | ||
88 | |||
89 | // Float64s is a slice of float64s that marshal as quoted strings in JSON. | ||
90 | type Float64s []float64 | ||
91 | |||
92 | func (q *Float64s) UnmarshalJSON(raw []byte) error { | ||
93 | *q = (*q)[:0] | ||
94 | var ss []string | ||
95 | if err := json.Unmarshal(raw, &ss); err != nil { | ||
96 | return err | ||
97 | } | ||
98 | for _, s := range ss { | ||
99 | v, err := strconv.ParseFloat(s, 64) | ||
100 | if err != nil { | ||
101 | return err | ||
102 | } | ||
103 | *q = append(*q, float64(v)) | ||
104 | } | ||
105 | return nil | ||
106 | } | ||
107 | |||
108 | func quotedList(n int, fn func(dst []byte, i int) []byte) ([]byte, error) { | ||
109 | dst := make([]byte, 0, 2+n*10) // somewhat arbitrary | ||
110 | dst = append(dst, '[') | ||
111 | for i := 0; i < n; i++ { | ||
112 | if i > 0 { | ||
113 | dst = append(dst, ',') | ||
114 | } | ||
115 | dst = append(dst, '"') | ||
116 | dst = fn(dst, i) | ||
117 | dst = append(dst, '"') | ||
118 | } | ||
119 | dst = append(dst, ']') | ||
120 | return dst, nil | ||
121 | } | ||
122 | |||
123 | func (q Int64s) MarshalJSON() ([]byte, error) { | ||
124 | return quotedList(len(q), func(dst []byte, i int) []byte { | ||
125 | return strconv.AppendInt(dst, q[i], 10) | ||
126 | }) | ||
127 | } | ||
128 | |||
129 | func (q Int32s) MarshalJSON() ([]byte, error) { | ||
130 | return quotedList(len(q), func(dst []byte, i int) []byte { | ||
131 | return strconv.AppendInt(dst, int64(q[i]), 10) | ||
132 | }) | ||
133 | } | ||
134 | |||
135 | func (q Uint64s) MarshalJSON() ([]byte, error) { | ||
136 | return quotedList(len(q), func(dst []byte, i int) []byte { | ||
137 | return strconv.AppendUint(dst, q[i], 10) | ||
138 | }) | ||
139 | } | ||
140 | |||
141 | func (q Uint32s) MarshalJSON() ([]byte, error) { | ||
142 | return quotedList(len(q), func(dst []byte, i int) []byte { | ||
143 | return strconv.AppendUint(dst, uint64(q[i]), 10) | ||
144 | }) | ||
145 | } | ||
146 | |||
147 | func (q Float64s) MarshalJSON() ([]byte, error) { | ||
148 | return quotedList(len(q), func(dst []byte, i int) []byte { | ||
149 | return strconv.AppendFloat(dst, q[i], 'g', -1, 64) | ||
150 | }) | ||
151 | } | ||
152 | |||
153 | // RawMessage is a raw encoded JSON value. | ||
154 | // It is identical to json.RawMessage, except it does not suffer from | ||
155 | // https://golang.org/issue/14493. | ||
156 | type RawMessage []byte | ||
157 | |||
158 | // MarshalJSON returns m. | ||
159 | func (m RawMessage) MarshalJSON() ([]byte, error) { | ||
160 | return m, nil | ||
161 | } | ||
162 | |||
163 | // UnmarshalJSON sets *m to a copy of data. | ||
164 | func (m *RawMessage) UnmarshalJSON(data []byte) error { | ||
165 | if m == nil { | ||
166 | return errors.New("googleapi.RawMessage: UnmarshalJSON on nil pointer") | ||
167 | } | ||
168 | *m = append((*m)[:0], data...) | ||
169 | return nil | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * Helper routines for simplifying the creation of optional fields of basic type. | ||
174 | */ | ||
175 | |||
176 | // Bool is a helper routine that allocates a new bool value | ||
177 | // to store v and returns a pointer to it. | ||
178 | func Bool(v bool) *bool { return &v } | ||
179 | |||
180 | // Int32 is a helper routine that allocates a new int32 value | ||
181 | // to store v and returns a pointer to it. | ||
182 | func Int32(v int32) *int32 { return &v } | ||
183 | |||
184 | // Int64 is a helper routine that allocates a new int64 value | ||
185 | // to store v and returns a pointer to it. | ||
186 | func Int64(v int64) *int64 { return &v } | ||
187 | |||
188 | // Float64 is a helper routine that allocates a new float64 value | ||
189 | // to store v and returns a pointer to it. | ||
190 | func Float64(v float64) *float64 { return &v } | ||
191 | |||
192 | // Uint32 is a helper routine that allocates a new uint32 value | ||
193 | // to store v and returns a pointer to it. | ||
194 | func Uint32(v uint32) *uint32 { return &v } | ||
195 | |||
196 | // Uint64 is a helper routine that allocates a new uint64 value | ||
197 | // to store v and returns a pointer to it. | ||
198 | func Uint64(v uint64) *uint64 { return &v } | ||
199 | |||
200 | // String is a helper routine that allocates a new string value | ||
201 | // to store v and returns a pointer to it. | ||
202 | func String(v string) *string { return &v } | ||