Nextcloud API Client, Uers/Response types, User list/search/get/create/delete

This commit is contained in:
2018-07-05 12:50:56 +02:00
commit 48fa0d6642
28 changed files with 13714 additions and 0 deletions

202
vendor/github.com/levigross/grequests/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2015 Levi Gross
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

776
vendor/github.com/levigross/grequests/README.md generated vendored Normal file
View File

@@ -0,0 +1,776 @@
# GRequests
A Go "clone" of the great and famous Requests library
[![Build Status](https://travis-ci.org/levigross/grequests.svg?branch=master)](https://travis-ci.org/levigross/grequests) [![GoDoc](https://godoc.org/github.com/levigross/grequests?status.svg)](https://godoc.org/github.com/levigross/grequests)
[![Coverage Status](https://coveralls.io/repos/levigross/grequests/badge.svg)](https://coveralls.io/r/levigross/grequests)
[![Join the chat at https://gitter.im/levigross/grequests](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/levigross/grequests?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
License
======
GRequests is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text
Features
========
- Responses can be serialized into JSON and XML
- Easy file uploads
- Easy file downloads
- Support for the following HTTP verbs `GET, HEAD, POST, PUT, DELETE, PATCH, OPTIONS`
Install
=======
`go get -u github.com/levigross/grequests`
Usage
======
`import "github.com/levigross/grequests"`
Basic Examples
=========
Basic GET request:
```go
resp, err := grequests.Get("http://httpbin.org/get", nil)
// You can modify the request by passing an optional RequestOptions struct
if err != nil {
log.Fatalln("Unable to make request: ", err)
}
fmt.Println(resp.String())
// {
// "args": {},
// "headers": {
// "Accept": "*/*",
// "Host": "httpbin.org",
```
If an error occurs all of the other properties and methods of a `Response` will be `nil`
Quirks
=======
## Request Quirks
When passing parameters to be added to a URL, if the URL has existing parameters that *_contradict_* with what has been passed within `Params` `Params` will be the "source of authority" and overwrite the contradicting URL parameter.
Lets see how it works...
```go
ro := &RequestOptions{
Params: map[string]string{"Hello": "Goodbye"},
}
Get("http://httpbin.org/get?Hello=World", ro)
// The URL is now http://httpbin.org/get?Hello=Goodbye
```
## Response Quirks
Order matters! This is because `grequests.Response` is implemented as an `io.ReadCloser` which proxies the *http.Response.Body* `io.ReadCloser` interface. It also includes an internal buffer for use in `Response.String()` and `Response.Bytes()`.
Here are a list of methods that consume the *http.Response.Body* `io.ReadCloser` interface.
- Response.JSON
- Response.XML
- Response.DownloadToFile
- Response.Close
- Response.Read
The following methods make use of an internal byte buffer
- Response.String
- Response.Bytes
In the code below, once the file is downloaded the `Response` struct no longer has access to the request bytes
```go
response := Get("http://some-wonderful-file.txt", nil)
if err := response.DownloadToFile("randomFile"); err != nil {
log.Println("Unable to download file: ", err)
}
// At this point the .String and .Bytes method will return empty responses
response.Bytes() == nil // true
response.String() == "" // true
```
But if we were to call `response.Bytes()` or `response.String()` first, every operation will succeed until the internal buffer is cleared:
```go
response := Get("http://some-wonderful-file.txt", nil)
// This call to .Bytes caches the request bytes in an internal byte buffer which can be used again and again until it is cleared
response.Bytes() == `file-bytes`
response.String() == "file-string"
// This will work because it will use the internal byte buffer
if err := resp.DownloadToFile("randomFile"); err != nil {
log.Println("Unable to download file: ", err)
}
// Now if we clear the internal buffer....
response.ClearInternalBuffer()
// At this point the .String and .Bytes method will return empty responses
response.Bytes() == nil // true
response.String() == "" // true
```
# grequests
`import "github.com/levigross/grequests"`
* [Overview](#pkg-overview)
* [Index](#pkg-index)
* [Examples](#pkg-examples)
## <a name="pkg-overview">Overview</a>
Package grequests implements a friendly API over Go's existing net/http library
## <a name="pkg-index">Index</a>
* [Variables](#pkg-variables)
* [func BuildHTTPClient(ro RequestOptions) *http.Client](#BuildHTTPClient)
* [func EnsureTransporterFinalized(httpTransport *http.Transport)](#EnsureTransporterFinalized)
* [func FileUploadFromDisk(fileName string) ([]FileUpload, error)](#FileUploadFromDisk)
* [func FileUploadFromGlob(fileSystemGlob string) ([]FileUpload, error)](#FileUploadFromGlob)
* [type FileUpload](#FileUpload)
* [type RequestOptions](#RequestOptions)
* [type Response](#Response)
* [func Delete(url string, ro *RequestOptions) (*Response, error)](#Delete)
* [func Get(url string, ro *RequestOptions) (*Response, error)](#Get)
* [func Head(url string, ro *RequestOptions) (*Response, error)](#Head)
* [func Options(url string, ro *RequestOptions) (*Response, error)](#Options)
* [func Patch(url string, ro *RequestOptions) (*Response, error)](#Patch)
* [func Post(url string, ro *RequestOptions) (*Response, error)](#Post)
* [func Put(url string, ro *RequestOptions) (*Response, error)](#Put)
* [func (r *Response) Bytes() []byte](#Response.Bytes)
* [func (r *Response) ClearInternalBuffer()](#Response.ClearInternalBuffer)
* [func (r *Response) Close() error](#Response.Close)
* [func (r *Response) DownloadToFile(fileName string) error](#Response.DownloadToFile)
* [func (r *Response) JSON(userStruct interface{}) error](#Response.JSON)
* [func (r *Response) Read(p []byte) (n int, err error)](#Response.Read)
* [func (r *Response) String() string](#Response.String)
* [func (r *Response) XML(userStruct interface{}, charsetReader XMLCharDecoder) error](#Response.XML)
* [type Session](#Session)
* [func NewSession(ro *RequestOptions) *Session](#NewSession)
* [func (s *Session) CloseIdleConnections()](#Session.CloseIdleConnections)
* [func (s *Session) Delete(url string, ro *RequestOptions) (*Response, error)](#Session.Delete)
* [func (s *Session) Get(url string, ro *RequestOptions) (*Response, error)](#Session.Get)
* [func (s *Session) Head(url string, ro *RequestOptions) (*Response, error)](#Session.Head)
* [func (s *Session) Options(url string, ro *RequestOptions) (*Response, error)](#Session.Options)
* [func (s *Session) Patch(url string, ro *RequestOptions) (*Response, error)](#Session.Patch)
* [func (s *Session) Post(url string, ro *RequestOptions) (*Response, error)](#Session.Post)
* [func (s *Session) Put(url string, ro *RequestOptions) (*Response, error)](#Session.Put)
* [type XMLCharDecoder](#XMLCharDecoder)
#### <a name="pkg-examples">Examples</a>
* [Package (AcceptInvalidTLSCert)](#example__acceptInvalidTLSCert)
* [Package (BasicAuth)](#example__basicAuth)
* [Package (BasicGet)](#example__basicGet)
* [Package (BasicGetCustomHTTPClient)](#example__basicGetCustomHTTPClient)
* [Package (Cookies)](#example__cookies)
* [Package (CustomHTTPHeader)](#example__customHTTPHeader)
* [Package (CustomUserAgent)](#example__customUserAgent)
* [Package (DownloadFile)](#example__downloadFile)
* [Package (PostFileUpload)](#example__postFileUpload)
* [Package (PostForm)](#example__postForm)
* [Package (PostJSONAJAX)](#example__postJSONAJAX)
* [Package (PostXML)](#example__postXML)
* [Package (Proxy)](#example__proxy)
* [Package (Session)](#example__session)
* [Package (UrlQueryParams)](#example__urlQueryParams)
#### <a name="pkg-files">Package files</a>
[base.go](/src/github.com/levigross/grequests/base.go) [file_upload.go](/src/github.com/levigross/grequests/file_upload.go) [request.go](/src/github.com/levigross/grequests/request.go) [response.go](/src/github.com/levigross/grequests/response.go) [session.go](/src/github.com/levigross/grequests/session.go) [utils.go](/src/github.com/levigross/grequests/utils.go)
## <a name="pkg-variables">Variables</a>
``` go
var (
// ErrRedirectLimitExceeded is the error returned when the request responded
// with too many redirects
ErrRedirectLimitExceeded = errors.New("grequests: Request exceeded redirect count")
// RedirectLimit is a tunable variable that specifies how many times we can
// redirect in response to a redirect. This is the global variable, if you
// wish to set this on a request by request basis, set it within the
// `RequestOptions` structure
RedirectLimit = 30
// SensitiveHTTPHeaders is a map of sensitive HTTP headers that a user
// doesn't want passed on a redirect. This is the global variable, if you
// wish to set this on a request by request basis, set it within the
// `RequestOptions` structure
SensitiveHTTPHeaders = map[string]struct{}{
"Www-Authenticate": {},
"Authorization": {},
"Proxy-Authorization": {},
}
)
```
## <a name="BuildHTTPClient">func</a> [BuildHTTPClient](/src/target/request.go?s=11478:11530#L405)
``` go
func BuildHTTPClient(ro RequestOptions) *http.Client
```
BuildHTTPClient is a function that will return a custom HTTP client based on the request options provided
the check is in UseDefaultClient
## <a name="EnsureTransporterFinalized">func</a> [EnsureTransporterFinalized](/src/target/utils.go?s=2482:2544#L79)
``` go
func EnsureTransporterFinalized(httpTransport *http.Transport)
```
EnsureTransporterFinalized will ensure that when the HTTP client is GCed
the runtime will close the idle connections (so that they won't leak)
this function was adopted from Hashicorp's go-cleanhttp package
## <a name="FileUploadFromDisk">func</a> [FileUploadFromDisk](/src/target/file_upload.go?s=625:687#L14)
``` go
func FileUploadFromDisk(fileName string) ([]FileUpload, error)
```
FileUploadFromDisk allows you to create a FileUpload struct slice by just specifying a location on the disk
## <a name="FileUploadFromGlob">func</a> [FileUploadFromGlob](/src/target/file_upload.go?s=1068:1136#L27)
``` go
func FileUploadFromGlob(fileSystemGlob string) ([]FileUpload, error)
```
FileUploadFromGlob allows you to create a FileUpload struct slice by just specifying a glob location on the disk
this function will gloss over all errors in the files and only upload the files that don't return errors from the glob
## <a name="FileUpload">type</a> [FileUpload](/src/target/file_upload.go?s=162:512#L2)
``` go
type FileUpload struct {
// Filename is the name of the file that you wish to upload. We use this to guess the mimetype as well as pass it onto the server
FileName string
// FileContents is happy as long as you pass it a io.ReadCloser (which most file use anyways)
FileContents io.ReadCloser
// FieldName is form field name
FieldName string
}
```
FileUpload is a struct that is used to specify the file that a User
wishes to upload.
## <a name="RequestOptions">type</a> [RequestOptions](/src/target/request.go?s=357:4258#L18)
``` go
type RequestOptions struct {
// Data is a map of key values that will eventually convert into the
// query string of a GET request or the body of a POST request.
Data map[string]string
// Params is a map of query strings that may be used within a GET request
Params map[string]string
// QueryStruct is a struct that encapsulates a set of URL query params
// this paramter is mutually exclusive with `Params map[string]string` (they cannot be combined)
// for more information please see https://godoc.org/github.com/google/go-querystring/query
QueryStruct interface{}
// Files is where you can include files to upload. The use of this data
// structure is limited to POST requests
Files []FileUpload
// JSON can be used when you wish to send JSON within the request body
JSON interface{}
// XML can be used if you wish to send XML within the request body
XML interface{}
// Headers if you want to add custom HTTP headers to the request,
// this is your friend
Headers map[string]string
// InsecureSkipVerify is a flag that specifies if we should validate the
// server's TLS certificate. It should be noted that Go's TLS verify mechanism
// doesn't validate if a certificate has been revoked
InsecureSkipVerify bool
// DisableCompression will disable gzip compression on requests
DisableCompression bool
// UserAgent allows you to set an arbitrary custom user agent
UserAgent string
// Host allows you to set an arbitrary custom host
Host string
// Auth allows you to specify a user name and password that you wish to
// use when requesting the URL. It will use basic HTTP authentication
// formatting the username and password in base64 the format is:
// []string{username, password}
Auth []string
// IsAjax is a flag that can be set to make the request appear
// to be generated by browser Javascript
IsAjax bool
// Cookies is an array of `http.Cookie` that allows you to attach
// cookies to your request
Cookies []*http.Cookie
// UseCookieJar will create a custom HTTP client that will
// process and store HTTP cookies when they are sent down
UseCookieJar bool
// Proxies is a map in the following format
// *protocol* => proxy address e.g http => http://127.0.0.1:8080
Proxies map[string]*url.URL
// TLSHandshakeTimeout specifies the maximum amount of time waiting to
// wait for a TLS handshake. Zero means no timeout.
TLSHandshakeTimeout time.Duration
// DialTimeout is the maximum amount of time a dial will wait for
// a connect to complete.
DialTimeout time.Duration
// KeepAlive specifies the keep-alive period for an active
// network connection. If zero, keep-alive are not enabled.
DialKeepAlive time.Duration
// RequestTimeout is the maximum amount of time a whole request(include dial / request / redirect)
// will wait.
RequestTimeout time.Duration
// HTTPClient can be provided if you wish to supply a custom HTTP client
// this is useful if you want to use an OAUTH client with your request.
HTTPClient *http.Client
// SensitiveHTTPHeaders is a map of sensitive HTTP headers that a user
// doesn't want passed on a redirect.
SensitiveHTTPHeaders map[string]struct{}
// RedirectLimit is the acceptable amount of redirects that we should expect
// before returning an error be default this is set to 30. You can change this
// globally by modifying the `RedirectLimit` variable.
RedirectLimit int
// RequestBody allows you to put anything matching an `io.Reader` into the request
// this option will take precedence over any other request option specified
RequestBody io.Reader
// CookieJar allows you to specify a special cookiejar to use with your request.
// this option will take precedence over the `UseCookieJar` option above.
CookieJar http.CookieJar
// Context can be used to maintain state between requests https://golang.org/pkg/context/#Context
Context context.Context
}
```
RequestOptions is the location that of where the data
## <a name="Response">type</a> [Response](/src/target/response.go?s=181:806#L4)
``` go
type Response struct {
// Ok is a boolean flag that validates that the server returned a 2xx code
Ok bool
// This is the Go error flag if something went wrong within the request, this flag will be set.
Error error
// We want to abstract (at least at the moment) the Go http.Response object away. So we are going to make use of it
// internal but not give the user access
RawResponse *http.Response
// StatusCode is the HTTP Status Code returned by the HTTP Response. Taken from resp.StatusCode
StatusCode int
// Header is a net/http/Header structure
Header http.Header
// contains filtered or unexported fields
}
```
Response is what is returned to a user when they fire off a request
### <a name="Delete">func</a> [Delete](/src/target/base.go?s=1221:1283#L22)
``` go
func Delete(url string, ro *RequestOptions) (*Response, error)
```
Delete takes 2 parameters and returns a Response struct. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
### <a name="Get">func</a> [Get](/src/target/base.go?s=300:359#L1)
``` go
func Get(url string, ro *RequestOptions) (*Response, error)
```
Get takes 2 parameters and returns a Response Struct. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
### <a name="Head">func</a> [Head](/src/target/base.go?s=1841:1901#L38)
``` go
func Head(url string, ro *RequestOptions) (*Response, error)
```
Head takes 2 parameters and returns a Response channel. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
### <a name="Options">func</a> [Options](/src/target/base.go?s=2151:2214#L46)
``` go
func Options(url string, ro *RequestOptions) (*Response, error)
```
Options takes 2 parameters and returns a Response struct. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
### <a name="Patch">func</a> [Patch](/src/target/base.go?s=910:971#L14)
``` go
func Patch(url string, ro *RequestOptions) (*Response, error)
```
Patch takes 2 parameters and returns a Response struct. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
### <a name="Post">func</a> [Post](/src/target/base.go?s=1533:1593#L30)
``` go
func Post(url string, ro *RequestOptions) (*Response, error)
```
Post takes 2 parameters and returns a Response channel. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
### <a name="Put">func</a> [Put](/src/target/base.go?s=604:663#L6)
``` go
func Put(url string, ro *RequestOptions) (*Response, error)
```
Put takes 2 parameters and returns a Response struct. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
### <a name="Response.Bytes">func</a> (\*Response) [Bytes](/src/target/response.go?s=4298:4331#L169)
``` go
func (r *Response) Bytes() []byte
```
Bytes returns the response as a byte array
### <a name="Response.ClearInternalBuffer">func</a> (\*Response) [ClearInternalBuffer](/src/target/response.go?s=4920:4960#L198)
``` go
func (r *Response) ClearInternalBuffer()
```
ClearInternalBuffer is a function that will clear the internal buffer that we use to hold the .String() and .Bytes()
data. Once you have used these functions you may want to free up the memory.
### <a name="Response.Close">func</a> (\*Response) [Close](/src/target/response.go?s=1793:1825#L55)
``` go
func (r *Response) Close() error
```
Close is part of our ability to support io.ReadCloser if someone wants to make use of the raw body
### <a name="Response.DownloadToFile">func</a> (\*Response) [DownloadToFile](/src/target/response.go?s=2018:2074#L67)
``` go
func (r *Response) DownloadToFile(fileName string) error
```
DownloadToFile allows you to download the contents of the response to a file
### <a name="Response.JSON">func</a> (\*Response) [JSON](/src/target/response.go?s=3300:3353#L124)
``` go
func (r *Response) JSON(userStruct interface{}) error
```
JSON is a method that will populate a struct that is provided `userStruct` with the JSON returned within the
response body
### <a name="Response.Read">func</a> (\*Response) [Read](/src/target/response.go?s=1551:1603#L45)
``` go
func (r *Response) Read(p []byte) (n int, err error)
```
Read is part of our ability to support io.ReadCloser if someone wants to make use of the raw body
### <a name="Response.String">func</a> (\*Response) [String](/src/target/response.go?s=4568:4602#L186)
``` go
func (r *Response) String() string
```
String returns the response as a string
### <a name="Response.XML">func</a> (\*Response) [XML](/src/target/response.go?s=2792:2874#L101)
``` go
func (r *Response) XML(userStruct interface{}, charsetReader XMLCharDecoder) error
```
XML is a method that will populate a struct that is provided `userStruct` with the XML returned within the
response body
## <a name="Session">type</a> [Session](/src/target/session.go?s=125:314#L1)
``` go
type Session struct {
// RequestOptions is global options
RequestOptions *RequestOptions
// HTTPClient is the client that we will use to request the resources
HTTPClient *http.Client
}
```
Session allows a user to make use of persistent cookies in between
HTTP requests
### <a name="NewSession">func</a> [NewSession](/src/target/session.go?s=532:576#L8)
``` go
func NewSession(ro *RequestOptions) *Session
```
NewSession returns a session struct which enables can be used to maintain establish a persistent state with the
server
This function will set UseCookieJar to true as that is the purpose of using the session
### <a name="Session.CloseIdleConnections">func</a> (\*Session) [CloseIdleConnections](/src/target/session.go?s=4738:4778#L124)
``` go
func (s *Session) CloseIdleConnections()
```
CloseIdleConnections closes the idle connections that a session client may make use of
### <a name="Session.Delete">func</a> (\*Session) [Delete](/src/target/session.go?s=3120:3195#L88)
``` go
func (s *Session) Delete(url string, ro *RequestOptions) (*Response, error)
```
Delete takes 2 parameters and returns a Response struct. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
A new session is created by calling NewSession with a request options struct
### <a name="Session.Get">func</a> (\*Session) [Get](/src/target/session.go?s=1776:1848#L58)
``` go
func (s *Session) Get(url string, ro *RequestOptions) (*Response, error)
```
Get takes 2 parameters and returns a Response Struct. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
A new session is created by calling NewSession with a request options struct
### <a name="Session.Head">func</a> (\*Session) [Head](/src/target/session.go?s=4022:4095#L108)
``` go
func (s *Session) Head(url string, ro *RequestOptions) (*Response, error)
```
Head takes 2 parameters and returns a Response channel. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
A new session is created by calling NewSession with a request options struct
### <a name="Session.Options">func</a> (\*Session) [Options](/src/target/session.go?s=4473:4549#L118)
``` go
func (s *Session) Options(url string, ro *RequestOptions) (*Response, error)
```
Options takes 2 parameters and returns a Response struct. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
A new session is created by calling NewSession with a request options struct
### <a name="Session.Patch">func</a> (\*Session) [Patch](/src/target/session.go?s=2668:2742#L78)
``` go
func (s *Session) Patch(url string, ro *RequestOptions) (*Response, error)
```
Patch takes 2 parameters and returns a Response struct. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
A new session is created by calling NewSession with a request options struct
### <a name="Session.Post">func</a> (\*Session) [Post](/src/target/session.go?s=3573:3646#L98)
``` go
func (s *Session) Post(url string, ro *RequestOptions) (*Response, error)
```
Post takes 2 parameters and returns a Response channel. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
A new session is created by calling NewSession with a request options struct
### <a name="Session.Put">func</a> (\*Session) [Put](/src/target/session.go?s=2221:2293#L68)
``` go
func (s *Session) Put(url string, ro *RequestOptions) (*Response, error)
```
Put takes 2 parameters and returns a Response struct. These two options are:
1. A URL
2. A RequestOptions struct
If you do not intend to use the `RequestOptions` you can just pass nil
A new session is created by calling NewSession with a request options struct
## <a name="XMLCharDecoder">type</a> [XMLCharDecoder](/src/target/utils.go?s=1529:1605#L42)
``` go
type XMLCharDecoder func(charset string, input io.Reader) (io.Reader, error)
```
XMLCharDecoder is a helper type that takes a stream of bytes (not encoded in
UTF-8) and returns a reader that encodes the bytes into UTF-8. This is done
because Go's XML library only supports XML encoded in UTF-8
- - -
Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)

67
vendor/github.com/levigross/grequests/base.go generated vendored Normal file
View File

@@ -0,0 +1,67 @@
// Package grequests implements a friendly API over Go's existing net/http library
package grequests
// Get takes 2 parameters and returns a Response Struct. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
func Get(url string, ro *RequestOptions) (*Response, error) {
return doRegularRequest("GET", url, ro)
}
// Put takes 2 parameters and returns a Response struct. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
func Put(url string, ro *RequestOptions) (*Response, error) {
return doRegularRequest("PUT", url, ro)
}
// Patch takes 2 parameters and returns a Response struct. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
func Patch(url string, ro *RequestOptions) (*Response, error) {
return doRegularRequest("PATCH", url, ro)
}
// Delete takes 2 parameters and returns a Response struct. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
func Delete(url string, ro *RequestOptions) (*Response, error) {
return doRegularRequest("DELETE", url, ro)
}
// Post takes 2 parameters and returns a Response channel. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
func Post(url string, ro *RequestOptions) (*Response, error) {
return doRegularRequest("POST", url, ro)
}
// Head takes 2 parameters and returns a Response channel. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
func Head(url string, ro *RequestOptions) (*Response, error) {
return doRegularRequest("HEAD", url, ro)
}
// Options takes 2 parameters and returns a Response struct. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
func Options(url string, ro *RequestOptions) (*Response, error) {
return doRegularRequest("OPTIONS", url, ro)
}
// Req takes 3 parameters and returns a Response Struct. These three options are:
// 1. A verb
// 2. A URL
// 3. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
func Req(verb string, url string, ro *RequestOptions) (*Response, error) {
return doRegularRequest(verb, url, ro)
}

68
vendor/github.com/levigross/grequests/file_upload.go generated vendored Normal file
View File

@@ -0,0 +1,68 @@
package grequests
import (
"errors"
"io"
"os"
"path/filepath"
)
// FileUpload is a struct that is used to specify the file that a User
// wishes to upload.
type FileUpload struct {
// Filename is the name of the file that you wish to upload. We use this to guess the mimetype as well as pass it onto the server
FileName string
// FileContents is happy as long as you pass it a io.ReadCloser (which most file use anyways)
FileContents io.ReadCloser
// FieldName is form field name
FieldName string
// FileMime represents which mimetime should be sent along with the file.
// When empty, defaults to application/octet-stream
FileMime string
}
// FileUploadFromDisk allows you to create a FileUpload struct slice by just specifying a location on the disk
func FileUploadFromDisk(fileName string) ([]FileUpload, error) {
fd, err := os.Open(fileName)
if err != nil {
return nil, err
}
return []FileUpload{{FileContents: fd, FileName: fileName}}, nil
}
// FileUploadFromGlob allows you to create a FileUpload struct slice by just specifying a glob location on the disk
// this function will gloss over all errors in the files and only upload the files that don't return errors from the glob
func FileUploadFromGlob(fileSystemGlob string) ([]FileUpload, error) {
files, err := filepath.Glob(fileSystemGlob)
if err != nil {
return nil, err
}
if len(files) == 0 {
return nil, errors.New("grequests: No files have been returned in the glob")
}
filesToUpload := make([]FileUpload, 0, len(files))
for _, f := range files {
if s, err := os.Stat(f); err != nil || s.IsDir() {
continue
}
// ignoring error because I can stat the file
fd, _ := os.Open(f)
filesToUpload = append(filesToUpload, FileUpload{FileContents: fd, FileName: filepath.Base(fd.Name())})
}
return filesToUpload, nil
}

585
vendor/github.com/levigross/grequests/request.go generated vendored Normal file
View File

@@ -0,0 +1,585 @@
package grequests
import (
"bytes"
"crypto/tls"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
"io"
"mime"
"mime/multipart"
"net"
"net/http"
"net/http/cookiejar"
"net/textproto"
"net/url"
"strconv"
"strings"
"time"
"github.com/google/go-querystring/query"
"context"
"golang.org/x/net/publicsuffix"
)
// RequestOptions is the location that of where the data
type RequestOptions struct {
// Data is a map of key values that will eventually convert into the
// query string of a GET request or the body of a POST request.
Data map[string]string
// Params is a map of query strings that may be used within a GET request
Params map[string]string
// QueryStruct is a struct that encapsulates a set of URL query params
// this paramter is mutually exclusive with `Params map[string]string` (they cannot be combined)
// for more information please see https://godoc.org/github.com/google/go-querystring/query
QueryStruct interface{}
// Files is where you can include files to upload. The use of this data
// structure is limited to POST requests
Files []FileUpload
// JSON can be used when you wish to send JSON within the request body
JSON interface{}
// XML can be used if you wish to send XML within the request body
XML interface{}
// Headers if you want to add custom HTTP headers to the request,
// this is your friend
Headers map[string]string
// InsecureSkipVerify is a flag that specifies if we should validate the
// server's TLS certificate. It should be noted that Go's TLS verify mechanism
// doesn't validate if a certificate has been revoked
InsecureSkipVerify bool
// DisableCompression will disable gzip compression on requests
DisableCompression bool
// UserAgent allows you to set an arbitrary custom user agent
UserAgent string
// Host allows you to set an arbitrary custom host
Host string
// Auth allows you to specify a user name and password that you wish to
// use when requesting the URL. It will use basic HTTP authentication
// formatting the username and password in base64 the format is:
// []string{username, password}
Auth []string
// IsAjax is a flag that can be set to make the request appear
// to be generated by browser Javascript
IsAjax bool
// Cookies is an array of `http.Cookie` that allows you to attach
// cookies to your request
Cookies []*http.Cookie
// UseCookieJar will create a custom HTTP client that will
// process and store HTTP cookies when they are sent down
UseCookieJar bool
// Proxies is a map in the following format
// *protocol* => proxy address e.g http => http://127.0.0.1:8080
Proxies map[string]*url.URL
// TLSHandshakeTimeout specifies the maximum amount of time waiting to
// wait for a TLS handshake. Zero means no timeout.
TLSHandshakeTimeout time.Duration
// DialTimeout is the maximum amount of time a dial will wait for
// a connect to complete.
DialTimeout time.Duration
// KeepAlive specifies the keep-alive period for an active
// network connection. If zero, keep-alive are not enabled.
DialKeepAlive time.Duration
// RequestTimeout is the maximum amount of time a whole request(include dial / request / redirect)
// will wait.
RequestTimeout time.Duration
// HTTPClient can be provided if you wish to supply a custom HTTP client
// this is useful if you want to use an OAUTH client with your request.
HTTPClient *http.Client
// SensitiveHTTPHeaders is a map of sensitive HTTP headers that a user
// doesn't want passed on a redirect.
SensitiveHTTPHeaders map[string]struct{}
// RedirectLimit is the acceptable amount of redirects that we should expect
// before returning an error be default this is set to 30. You can change this
// globally by modifying the `RedirectLimit` variable.
RedirectLimit int
// RequestBody allows you to put anything matching an `io.Reader` into the request
// this option will take precedence over any other request option specified
RequestBody io.Reader
// CookieJar allows you to specify a special cookiejar to use with your request.
// this option will take precedence over the `UseCookieJar` option above.
CookieJar http.CookieJar
// Context can be used to maintain state between requests https://golang.org/pkg/context/#Context
Context context.Context
}
func doRegularRequest(requestVerb, url string, ro *RequestOptions) (*Response, error) {
return buildResponse(buildRequest(requestVerb, url, ro, nil))
}
func doSessionRequest(requestVerb, url string, ro *RequestOptions, httpClient *http.Client) (*Response, error) {
return buildResponse(buildRequest(requestVerb, url, ro, httpClient))
}
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")
func escapeQuotes(s string) string {
return quoteEscaper.Replace(s)
}
// buildRequest is where most of the magic happens for request processing
func buildRequest(httpMethod, url string, ro *RequestOptions, httpClient *http.Client) (*http.Response, error) {
if ro == nil {
ro = &RequestOptions{}
}
if ro.CookieJar != nil {
ro.UseCookieJar = true
}
// Create our own HTTP client
if httpClient == nil {
httpClient = BuildHTTPClient(*ro)
}
var err error // we don't want to shadow url so we won't use :=
switch {
case len(ro.Params) != 0:
if url, err = buildURLParams(url, ro.Params); err != nil {
return nil, err
}
case ro.QueryStruct != nil:
if url, err = buildURLStruct(url, ro.QueryStruct); err != nil {
return nil, err
}
}
// Build the request
req, err := buildHTTPRequest(httpMethod, url, ro)
if err != nil {
return nil, err
}
// Do we need to add any HTTP headers or Basic Auth?
addHTTPHeaders(ro, req)
addCookies(ro, req)
addRedirectFunctionality(httpClient, ro)
if ro.Context != nil {
req = req.WithContext(ro.Context)
}
return httpClient.Do(req)
}
func buildHTTPRequest(httpMethod, userURL string, ro *RequestOptions) (*http.Request, error) {
if ro.RequestBody != nil {
return http.NewRequest(httpMethod, userURL, ro.RequestBody)
}
if ro.JSON != nil {
return createBasicJSONRequest(httpMethod, userURL, ro)
}
if ro.XML != nil {
return createBasicXMLRequest(httpMethod, userURL, ro)
}
if ro.Files != nil {
return createFileUploadRequest(httpMethod, userURL, ro)
}
if ro.Data != nil {
return createBasicRequest(httpMethod, userURL, ro)
}
return http.NewRequest(httpMethod, userURL, nil)
}
func createFileUploadRequest(httpMethod, userURL string, ro *RequestOptions) (*http.Request, error) {
if httpMethod == "POST" {
return createMultiPartPostRequest(httpMethod, userURL, ro)
}
// This may be a PUT or PATCH request so we will just put the raw
// io.ReadCloser in the request body
// and guess the MIME type from the file name
// At the moment, we will only support 1 file upload as a time
// when uploading using PUT or PATCH
req, err := http.NewRequest(httpMethod, userURL, ro.Files[0].FileContents)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", mime.TypeByExtension(ro.Files[0].FileName))
return req, nil
}
func createBasicXMLRequest(httpMethod, userURL string, ro *RequestOptions) (*http.Request, error) {
var reader io.Reader
switch ro.XML.(type) {
case string:
reader = strings.NewReader(ro.XML.(string))
case []byte:
reader = bytes.NewReader(ro.XML.([]byte))
default:
byteSlice, err := xml.Marshal(ro.XML)
if err != nil {
return nil, err
}
reader = bytes.NewReader(byteSlice)
}
req, err := http.NewRequest(httpMethod, userURL, reader)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/xml")
return req, nil
}
func createMultiPartPostRequest(httpMethod, userURL string, ro *RequestOptions) (*http.Request, error) {
requestBody := &bytes.Buffer{}
multipartWriter := multipart.NewWriter(requestBody)
for i, f := range ro.Files {
if f.FileContents == nil {
return nil, errors.New("grequests: Pointer FileContents cannot be nil")
}
fieldName := f.FieldName
if fieldName == "" {
if len(ro.Files) > 1 {
fieldName = strings.Join([]string{"file", strconv.Itoa(i + 1)}, "")
} else {
fieldName = "file"
}
}
var writer io.Writer
var err error
if f.FileMime != "" {
h := make(textproto.MIMEHeader)
h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`, escapeQuotes(fieldName), escapeQuotes(f.FileName)))
h.Set("Content-Type", f.FileMime)
writer, err = multipartWriter.CreatePart(h)
} else {
writer, err = multipartWriter.CreateFormFile(fieldName, f.FileName)
}
if err != nil {
return nil, err
}
if _, err = io.Copy(writer, f.FileContents); err != nil && err != io.EOF {
return nil, err
}
f.FileContents.Close()
}
// Populate the other parts of the form (if there are any)
for key, value := range ro.Data {
multipartWriter.WriteField(key, value)
}
if err := multipartWriter.Close(); err != nil {
return nil, err
}
req, err := http.NewRequest(httpMethod, userURL, requestBody)
if err != nil {
return nil, err
}
req.Header.Add("Content-Type", multipartWriter.FormDataContentType())
return req, err
}
func createBasicJSONRequest(httpMethod, userURL string, ro *RequestOptions) (*http.Request, error) {
var reader io.Reader
switch ro.JSON.(type) {
case string:
reader = strings.NewReader(ro.JSON.(string))
case []byte:
reader = bytes.NewReader(ro.JSON.([]byte))
default:
byteSlice, err := json.Marshal(ro.JSON)
if err != nil {
return nil, err
}
reader = bytes.NewReader(byteSlice)
}
req, err := http.NewRequest(httpMethod, userURL, reader)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
return req, nil
}
func createBasicRequest(httpMethod, userURL string, ro *RequestOptions) (*http.Request, error) {
req, err := http.NewRequest(httpMethod, userURL, strings.NewReader(encodePostValues(ro.Data)))
if err != nil {
return nil, err
}
// The content type must be set to a regular form
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return req, nil
}
func encodePostValues(postValues map[string]string) string {
urlValues := &url.Values{}
for key, value := range postValues {
urlValues.Set(key, value)
}
return urlValues.Encode() // This will sort all of the string values
}
// proxySettings will default to the default proxy settings if none are provided
// if settings are provided they will override the environment variables
func (ro RequestOptions) proxySettings(req *http.Request) (*url.URL, error) {
// No proxies lets use the default
if len(ro.Proxies) == 0 {
return http.ProxyFromEnvironment(req)
}
// There was a proxy specified do we support the protocol?
if _, ok := ro.Proxies[req.URL.Scheme]; ok {
return ro.Proxies[req.URL.Scheme], nil
}
// Proxies were specified but not for any protocol that we use
return http.ProxyFromEnvironment(req)
}
// dontUseDefaultClient will tell the "client creator" if a custom client is needed
// it checks the following items (and will create a custom client of these are)
// true
// 1. Do we want to accept invalid SSL certificates?
// 2. Do we want to disable compression?
// 3. Do we want a custom proxy?
// 4. Do we want to change the default timeout for TLS Handshake?
// 5. Do we want to change the default request timeout?
// 6. Do we want to change the default connection timeout?
// 7. Do you want to use the http.Client's cookieJar?
func (ro RequestOptions) dontUseDefaultClient() bool {
switch {
case ro.InsecureSkipVerify == true:
case ro.DisableCompression == true:
case len(ro.Proxies) != 0:
case ro.TLSHandshakeTimeout != 0:
case ro.DialTimeout != 0:
case ro.DialKeepAlive != 0:
case len(ro.Cookies) != 0:
case ro.UseCookieJar != false:
case ro.RequestTimeout != 0:
default:
return false
}
return true
}
// BuildHTTPClient is a function that will return a custom HTTP client based on the request options provided
// the check is in UseDefaultClient
func BuildHTTPClient(ro RequestOptions) *http.Client {
if ro.HTTPClient != nil {
return ro.HTTPClient
}
// Does the user want to change the defaults?
if !ro.dontUseDefaultClient() {
return http.DefaultClient
}
// Using the user config for tls timeout or default
if ro.TLSHandshakeTimeout == 0 {
ro.TLSHandshakeTimeout = tlsHandshakeTimeout
}
// Using the user config for dial timeout or default
if ro.DialTimeout == 0 {
ro.DialTimeout = dialTimeout
}
// Using the user config for dial keep alive or default
if ro.DialKeepAlive == 0 {
ro.DialKeepAlive = dialKeepAlive
}
if ro.RequestTimeout == 0 {
ro.RequestTimeout = requestTimeout
}
var cookieJar http.CookieJar
if ro.UseCookieJar {
if ro.CookieJar != nil {
cookieJar = ro.CookieJar
} else {
// The function does not return an error ever... so we are just ignoring it
cookieJar, _ = cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
}
}
return &http.Client{
Jar: cookieJar,
Transport: createHTTPTransport(ro),
Timeout: ro.RequestTimeout,
}
}
func createHTTPTransport(ro RequestOptions) *http.Transport {
ourHTTPTransport := &http.Transport{
// These are borrowed from the default transporter
Proxy: ro.proxySettings,
Dial: (&net.Dialer{
Timeout: ro.DialTimeout,
KeepAlive: ro.DialKeepAlive,
}).Dial,
TLSHandshakeTimeout: ro.TLSHandshakeTimeout,
// Here comes the user settings
TLSClientConfig: &tls.Config{InsecureSkipVerify: ro.InsecureSkipVerify},
DisableCompression: ro.DisableCompression,
}
EnsureTransporterFinalized(ourHTTPTransport)
return ourHTTPTransport
}
// buildURLParams returns a URL with all of the params
// Note: This function will override current URL params if they contradict what is provided in the map
// That is what the "magic" is on the last line
func buildURLParams(userURL string, params map[string]string) (string, error) {
parsedURL, err := url.Parse(userURL)
if err != nil {
return "", err
}
parsedQuery, err := url.ParseQuery(parsedURL.RawQuery)
if err != nil {
return "", nil
}
for key, value := range params {
parsedQuery.Set(key, value)
}
return addQueryParams(parsedURL, parsedQuery), nil
}
// addHTTPHeaders adds any additional HTTP headers that need to be added are added here including:
// 1. Custom User agent
// 2. Authorization Headers
// 3. Any other header requested
func addHTTPHeaders(ro *RequestOptions, req *http.Request) {
for key, value := range ro.Headers {
req.Header.Set(key, value)
}
if ro.UserAgent != "" {
req.Header.Set("User-Agent", ro.UserAgent)
} else {
req.Header.Set("User-Agent", localUserAgent)
}
if ro.Host != "" {
req.Host = ro.Host
}
if ro.Auth != nil {
req.SetBasicAuth(ro.Auth[0], ro.Auth[1])
}
if ro.IsAjax == true {
req.Header.Set("X-Requested-With", "XMLHttpRequest")
}
}
func addCookies(ro *RequestOptions, req *http.Request) {
for _, c := range ro.Cookies {
req.AddCookie(c)
}
}
func addQueryParams(parsedURL *url.URL, parsedQuery url.Values) string {
return strings.Join([]string{strings.Replace(parsedURL.String(), "?"+parsedURL.RawQuery, "", -1), parsedQuery.Encode()}, "?")
}
func buildURLStruct(userURL string, URLStruct interface{}) (string, error) {
parsedURL, err := url.Parse(userURL)
if err != nil {
return "", err
}
parsedQuery, err := url.ParseQuery(parsedURL.RawQuery)
if err != nil {
return "", err
}
queryStruct, err := query.Values(URLStruct)
if err != nil {
return "", err
}
for key, value := range queryStruct {
for _, v := range value {
parsedQuery.Add(key, v)
}
}
return addQueryParams(parsedURL, parsedQuery), nil
}

215
vendor/github.com/levigross/grequests/response.go generated vendored Normal file
View File

@@ -0,0 +1,215 @@
package grequests
import (
"bytes"
"encoding/json"
"encoding/xml"
"io"
"io/ioutil"
"net/http"
"os"
)
// Response is what is returned to a user when they fire off a request
type Response struct {
// Ok is a boolean flag that validates that the server returned a 2xx code
Ok bool
// This is the Go error flag if something went wrong within the request, this flag will be set.
Error error
// We want to abstract (at least at the moment) the Go http.Response object away. So we are going to make use of it
// internal but not give the user access
RawResponse *http.Response
// StatusCode is the HTTP Status Code returned by the HTTP Response. Taken from resp.StatusCode
StatusCode int
// Header is a net/http/Header structure
Header http.Header
internalByteBuffer *bytes.Buffer
}
func buildResponse(resp *http.Response, err error) (*Response, error) {
// If the connection didn't succeed we just return a blank response
if err != nil {
return &Response{Error: err}, err
}
goodResp := &Response{
// If your code is within the 2xx range the response is considered `Ok`
Ok: resp.StatusCode >= 200 && resp.StatusCode < 300,
Error: nil,
RawResponse: resp,
StatusCode: resp.StatusCode,
Header: resp.Header,
internalByteBuffer: bytes.NewBuffer([]byte{}),
}
// EnsureResponseFinalized(goodResp) This will come back in 1.0
return goodResp, nil
}
// Read is part of our ability to support io.ReadCloser if someone wants to make use of the raw body
func (r *Response) Read(p []byte) (n int, err error) {
if r.Error != nil {
return -1, r.Error
}
return r.RawResponse.Body.Read(p)
}
// Close is part of our ability to support io.ReadCloser if someone wants to make use of the raw body
func (r *Response) Close() error {
if r.Error != nil {
return r.Error
}
io.Copy(ioutil.Discard, r)
return r.RawResponse.Body.Close()
}
// DownloadToFile allows you to download the contents of the response to a file
func (r *Response) DownloadToFile(fileName string) error {
if r.Error != nil {
return r.Error
}
fd, err := os.Create(fileName)
if err != nil {
return err
}
defer r.Close() // This is a noop if we use the internal ByteBuffer
defer fd.Close()
if _, err := io.Copy(fd, r.getInternalReader()); err != nil && err != io.EOF {
return err
}
return nil
}
// getInternalReader because we implement io.ReadCloser and optionally hold a large buffer of the response (created by
// the user's request)
func (r *Response) getInternalReader() io.Reader {
if r.internalByteBuffer.Len() != 0 {
return r.internalByteBuffer
}
return r
}
// XML is a method that will populate a struct that is provided `userStruct` with the XML returned within the
// response body
func (r *Response) XML(userStruct interface{}, charsetReader XMLCharDecoder) error {
if r.Error != nil {
return r.Error
}
xmlDecoder := xml.NewDecoder(r.getInternalReader())
if charsetReader != nil {
xmlDecoder.CharsetReader = charsetReader
}
defer r.Close()
if err := xmlDecoder.Decode(&userStruct); err != nil && err != io.EOF {
return err
}
return nil
}
// JSON is a method that will populate a struct that is provided `userStruct` with the JSON returned within the
// response body
func (r *Response) JSON(userStruct interface{}) error {
if r.Error != nil {
return r.Error
}
jsonDecoder := json.NewDecoder(r.getInternalReader())
defer r.Close()
if err := jsonDecoder.Decode(&userStruct); err != nil && err != io.EOF {
return err
}
return nil
}
// createResponseBytesBuffer is a utility method that will populate the internal byte reader this is largely used for .String()
// and .Bytes()
func (r *Response) populateResponseByteBuffer() {
// Have I done this already?
if r.internalByteBuffer.Len() != 0 {
return
}
defer r.Close()
// Is there any content?
if r.RawResponse.ContentLength == 0 {
return
}
// Did the server tell us how big the response is going to be?
if r.RawResponse.ContentLength > 0 {
r.internalByteBuffer.Grow(int(r.RawResponse.ContentLength))
}
if _, err := io.Copy(r.internalByteBuffer, r); err != nil && err != io.EOF {
r.Error = err
r.RawResponse.Body.Close()
}
}
// Bytes returns the response as a byte array
func (r *Response) Bytes() []byte {
if r.Error != nil {
return nil
}
r.populateResponseByteBuffer()
// Are we still empty?
if r.internalByteBuffer.Len() == 0 {
return nil
}
return r.internalByteBuffer.Bytes()
}
// String returns the response as a string
func (r *Response) String() string {
if r.Error != nil {
return ""
}
r.populateResponseByteBuffer()
return r.internalByteBuffer.String()
}
// ClearInternalBuffer is a function that will clear the internal buffer that we use to hold the .String() and .Bytes()
// data. Once you have used these functions you may want to free up the memory.
func (r *Response) ClearInternalBuffer() {
if r == nil || r.internalByteBuffer == nil {
return
}
r.internalByteBuffer.Reset()
}

136
vendor/github.com/levigross/grequests/session.go generated vendored Normal file
View File

@@ -0,0 +1,136 @@
package grequests
import "net/http"
// Session allows a user to make use of persistent cookies in between
// HTTP requests
type Session struct {
// RequestOptions is global options
RequestOptions *RequestOptions
// HTTPClient is the client that we will use to request the resources
HTTPClient *http.Client
}
// NewSession returns a session struct which enables can be used to maintain establish a persistent state with the
// server
// This function will set UseCookieJar to true as that is the purpose of using the session
func NewSession(ro *RequestOptions) *Session {
if ro == nil {
ro = &RequestOptions{}
}
ro.UseCookieJar = true
return &Session{RequestOptions: ro, HTTPClient: BuildHTTPClient(*ro)}
}
// Combine session options and request options
// 1. UserAgent
// 2. Host
// 3. Auth
// 4. Headers
func (s *Session) combineRequestOptions(ro *RequestOptions) *RequestOptions {
if ro == nil {
ro = &RequestOptions{}
}
if ro.UserAgent == "" && s.RequestOptions.UserAgent != "" {
ro.UserAgent = s.RequestOptions.UserAgent
}
if ro.Host == "" && s.RequestOptions.Host != "" {
ro.Host = s.RequestOptions.Host
}
if ro.Auth == nil && s.RequestOptions.Auth != nil {
ro.Auth = s.RequestOptions.Auth
}
if len(s.RequestOptions.Headers) > 0 || len(ro.Headers) > 0 {
headers := make(map[string]string)
for k, v := range s.RequestOptions.Headers {
headers[k] = v
}
for k, v := range ro.Headers {
headers[k] = v
}
ro.Headers = headers
}
return ro
}
// Get takes 2 parameters and returns a Response Struct. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
// A new session is created by calling NewSession with a request options struct
func (s *Session) Get(url string, ro *RequestOptions) (*Response, error) {
ro = s.combineRequestOptions(ro)
return doSessionRequest("GET", url, ro, s.HTTPClient)
}
// Put takes 2 parameters and returns a Response struct. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
// A new session is created by calling NewSession with a request options struct
func (s *Session) Put(url string, ro *RequestOptions) (*Response, error) {
ro = s.combineRequestOptions(ro)
return doSessionRequest("PUT", url, ro, s.HTTPClient)
}
// Patch takes 2 parameters and returns a Response struct. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
// A new session is created by calling NewSession with a request options struct
func (s *Session) Patch(url string, ro *RequestOptions) (*Response, error) {
ro = s.combineRequestOptions(ro)
return doSessionRequest("PATCH", url, ro, s.HTTPClient)
}
// Delete takes 2 parameters and returns a Response struct. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
// A new session is created by calling NewSession with a request options struct
func (s *Session) Delete(url string, ro *RequestOptions) (*Response, error) {
ro = s.combineRequestOptions(ro)
return doSessionRequest("DELETE", url, ro, s.HTTPClient)
}
// Post takes 2 parameters and returns a Response channel. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
// A new session is created by calling NewSession with a request options struct
func (s *Session) Post(url string, ro *RequestOptions) (*Response, error) {
ro = s.combineRequestOptions(ro)
return doSessionRequest("POST", url, ro, s.HTTPClient)
}
// Head takes 2 parameters and returns a Response channel. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
// A new session is created by calling NewSession with a request options struct
func (s *Session) Head(url string, ro *RequestOptions) (*Response, error) {
ro = s.combineRequestOptions(ro)
return doSessionRequest("HEAD", url, ro, s.HTTPClient)
}
// Options takes 2 parameters and returns a Response struct. These two options are:
// 1. A URL
// 2. A RequestOptions struct
// If you do not intend to use the `RequestOptions` you can just pass nil
// A new session is created by calling NewSession with a request options struct
func (s *Session) Options(url string, ro *RequestOptions) (*Response, error) {
ro = s.combineRequestOptions(ro)
return doSessionRequest("OPTIONS", url, ro, s.HTTPClient)
}
// CloseIdleConnections closes the idle connections that a session client may make use of
func (s *Session) CloseIdleConnections() {
s.HTTPClient.Transport.(*http.Transport).CloseIdleConnections()
}

102
vendor/github.com/levigross/grequests/utils.go generated vendored Normal file
View File

@@ -0,0 +1,102 @@
package grequests
import (
"errors"
"io"
"net/http"
"runtime"
"time"
)
const (
localUserAgent = "GRequests/0.10"
// Default value for net.Dialer Timeout
dialTimeout = 30 * time.Second
// Default value for net.Dialer KeepAlive
dialKeepAlive = 30 * time.Second
// Default value for http.Transport TLSHandshakeTimeout
tlsHandshakeTimeout = 10 * time.Second
// Default value for Request Timeout
requestTimeout = 90 * time.Second
)
var (
// ErrRedirectLimitExceeded is the error returned when the request responded
// with too many redirects
ErrRedirectLimitExceeded = errors.New("grequests: Request exceeded redirect count")
// RedirectLimit is a tunable variable that specifies how many times we can
// redirect in response to a redirect. This is the global variable, if you
// wish to set this on a request by request basis, set it within the
// `RequestOptions` structure
RedirectLimit = 30
// SensitiveHTTPHeaders is a map of sensitive HTTP headers that a user
// doesn't want passed on a redirect. This is the global variable, if you
// wish to set this on a request by request basis, set it within the
// `RequestOptions` structure
SensitiveHTTPHeaders = map[string]struct{}{
"Www-Authenticate": {},
"Authorization": {},
"Proxy-Authorization": {},
}
)
// XMLCharDecoder is a helper type that takes a stream of bytes (not encoded in
// UTF-8) and returns a reader that encodes the bytes into UTF-8. This is done
// because Go's XML library only supports XML encoded in UTF-8
type XMLCharDecoder func(charset string, input io.Reader) (io.Reader, error)
func addRedirectFunctionality(client *http.Client, ro *RequestOptions) {
if client.CheckRedirect != nil {
return
}
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
if ro.RedirectLimit == 0 {
ro.RedirectLimit = RedirectLimit
}
if len(via) >= ro.RedirectLimit {
return ErrRedirectLimitExceeded
}
if ro.SensitiveHTTPHeaders == nil {
ro.SensitiveHTTPHeaders = SensitiveHTTPHeaders
}
for k, vv := range via[0].Header {
// Is this a sensitive header?
if _, found := ro.SensitiveHTTPHeaders[k]; found {
continue
}
for _, v := range vv {
req.Header.Add(k, v)
}
}
return nil
}
}
// EnsureTransporterFinalized will ensure that when the HTTP client is GCed
// the runtime will close the idle connections (so that they won't leak)
// this function was adopted from Hashicorp's go-cleanhttp package
func EnsureTransporterFinalized(httpTransport *http.Transport) {
runtime.SetFinalizer(&httpTransport, func(transportInt **http.Transport) {
(*transportInt).CloseIdleConnections()
})
}
// EnsureResponseFinalized will ensure that when the Response is GCed
// the request body is closed so we aren't leaking fds
// func EnsureResponseFinalized(httpResp *Response) {
// runtime.SetFinalizer(&httpResp, func(httpResponseInt **Response) {
// (*httpResponseInt).RawResponse.Body.Close()
// })
// }
// This will come back in 1.0