func (r Request) Do() (*Response, error) {
	return Global.doRequest(r, "")
}
Do sends request and process response
package req
import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"
)
const (
	ERROR_BODY_ENCODE    = 1
	ERROR_CREATE_REQUEST = 2
	ERROR_SEND_REQUEST   = 3
)
const (
	POST   = "POST"
	GET    = "GET"
	PUT    = "PUT"
	HEAD   = "HEAD"
	DELETE = "DELETE"
	PATCH  = "PATCH"
)
const (
	CONTENT_TYPE_ATOM         = "application/atom+xml"
	CONTENT_TYPE_EDI          = "application/EDI-X12"
	CONTENT_TYPE_EDIFACT      = "application/EDIFACT"
	CONTENT_TYPE_JSON         = "application/json"
	CONTENT_TYPE_JAVASCRIPT   = "application/javascript"
	CONTENT_TYPE_OCTET_STREAM = "application/octet-stream"
	CONTENT_TYPE_PDF          = "application/pdf"
	CONTENT_TYPE_POSTSCRIPT   = "application/postscript"
	CONTENT_TYPE_SOAP         = "application/soap+xml"
	CONTENT_TYPE_WOFF         = "application/font-woff"
	CONTENT_TYPE_XHTML        = "application/xhtml+xml"
	CONTENT_TYPE_DTD          = "application/xml-dtd"
	CONTENT_TYPE_XOP          = "application/xop+xml"
	CONTENT_TYPE_ZIP          = "application/zip"
	CONTENT_TYPE_GZIP         = "application/gzip"
	CONTENT_TYPE_BITTORRENT   = "application/x-bittorrent"
	CONTENT_TYPE_TEX          = "application/x-tex"
	CONTENT_TYPE_BASIC        = "audio/basic"
	CONTENT_TYPE_L24          = "audio/L24"
	CONTENT_TYPE_MP4_AUDIO    = "audio/mp4"
	CONTENT_TYPE_AAC          = "audio/aac"
	CONTENT_TYPE_MPEG_AUDIO   = "audio/mpeg"
	CONTENT_TYPE_OGG_AUDIO    = "audio/ogg"
	CONTENT_TYPE_VORBIS       = "audio/vorbis"
	CONTENT_TYPE_WMA          = "audio/x-ms-wma"
	CONTENT_TYPE_WAX          = "audio/x-ms-wax"
	CONTENT_TYPE_REALAUDIO    = "audio/vnd.rn-realaudio"
	CONTENT_TYPE_WAV          = "audio/vnd.wave"
	CONTENT_TYPE_WEBM_AUDIO   = "audio/webm"
	CONTENT_TYPE_GIF          = "image/gif"
	CONTENT_TYPE_JPEG         = "image/jpeg"
	CONTENT_TYPE_PJPEG        = "image/pjpeg"
	CONTENT_TYPE_PNG          = "image/png"
	CONTENT_TYPE_SVG          = "image/svg+xml"
	CONTENT_TYPE_TIFF         = "image/tiff"
	CONTENT_TYPE_ICON         = "image/vnd.microsoft.icon"
	CONTENT_TYPE_WBMP         = "image/vnd.wap.wbmp"
	CONTENT_TYPE_HTTP         = "message/http"
	CONTENT_TYPE_IMDN         = "message/imdn+xml"
	CONTENT_TYPE_PARTIAL      = "message/partial"
	CONTENT_TYPE_RFC822       = "message/rfc822"
	CONTENT_TYPE_EXAMPLE      = "model/example"
	CONTENT_TYPE_IGES         = "model/iges"
	CONTENT_TYPE_MESH         = "model/mesh"
	CONTENT_TYPE_VRML         = "model/vrml"
	CONTENT_TYPE_MIXED        = "multipart/mixed"
	CONTENT_TYPE_ALTERNATIVE  = "multipart/alternative"
	CONTENT_TYPE_RELATED      = "multipart/related"
	CONTENT_TYPE_FORM_DATA    = "multipart/form-data"
	CONTENT_TYPE_SIGNED       = "multipart/signed"
	CONTENT_TYPE_ENCRYPTED    = "multipart/encrypted"
	CONTENT_TYPE_CSS          = "text/css"
	CONTENT_TYPE_CSV          = "text/csv"
	CONTENT_TYPE_HTML         = "text/html"
	CONTENT_TYPE_PLAIN        = "text/plain"
	CONTENT_TYPE_PHP          = "text/php"
	CONTENT_TYPE_XML          = "text/xml"
	CONTENT_TYPE_MPEG_VIDEO   = "video/mpeg"
	CONTENT_TYPE_MP4_VIDEO    = "video/mp4"
	CONTENT_TYPE_OGG_VIDEO    = "video/ogg"
	CONTENT_TYPE_QUICKTIME    = "video/quicktime"
	CONTENT_TYPE_WEBM_VIDEO   = "video/webm"
	CONTENT_TYPE_WMV          = "video/x-ms-wmv"
	CONTENT_TYPE_FLV          = "video/x-flv"
	CONTENT_TYPE_3GPP         = "video/3gpp"
	CONTENT_TYPE_3GPP2        = "video/3gpp2"
)
const (
	STATUS_CONTINUE                        = 100  
	STATUS_SWITCHING_PROTOCOLS             = 101  
	STATUS_PROCESSING                      = 102  
	STATUS_OK                              = 200  
	STATUS_CREATED                         = 201  
	STATUS_ACCEPTED                        = 202  
	STATUS_NON_AUTHORITATIVE_INFO          = 203  
	STATUS_NO_CONTENT                      = 204  
	STATUS_RESET_CONTENT                   = 205  
	STATUS_PARTIAL_CONTENT                 = 206  
	STATUS_MULTI_STATUS                    = 207  
	STATUS_ALREADY_REPORTED                = 208  
	STATUS_IMUSED                          = 226  
	STATUS_MULTIPLE_CHOICES                = 300  
	STATUS_MOVED_PERMANENTLY               = 301  
	STATUS_FOUND                           = 302  
	STATUS_SEE_OTHER                       = 303  
	STATUS_NOT_MODIFIED                    = 304  
	STATUS_USE_PROXY                       = 305  
	STATUS_TEMPORARY_REDIRECT              = 307  
	STATUS_PERMANENT_REDIRECT              = 308  
	STATUS_BAD_REQUEST                     = 400  
	STATUS_UNAUTHORIZED                    = 401  
	STATUS_PAYMENT_REQUIRED                = 402  
	STATUS_FORBIDDEN                       = 403  
	STATUS_NOT_FOUND                       = 404  
	STATUS_METHOD_NOT_ALLOWED              = 405  
	STATUS_NOT_ACCEPTABLE                  = 406  
	STATUS_PROXY_AUTH_REQUIRED             = 407  
	STATUS_REQUEST_TIMEOUT                 = 408  
	STATUS_CONFLICT                        = 409  
	STATUS_GONE                            = 410  
	STATUS_LENGTH_REQUIRED                 = 411  
	STATUS_PRECONDITION_FAILED             = 412  
	STATUS_REQUEST_ENTITY_TOO_LARGE        = 413  
	STATUS_REQUEST_URITOO_LONG             = 414  
	STATUS_UNSUPPORTED_MEDIA_TYPE          = 415  
	STATUS_REQUESTED_RANGE_NOT_SATISFIABLE = 416  
	STATUS_EXPECTATION_FAILED              = 417  
	STATUS_TEAPOT                          = 418  
	STATUS_UNPROCESSABLE_ENTITY            = 422  
	STATUS_LOCKED                          = 423  
	STATUS_FAILED_DEPENDENCY               = 424  
	STATUS_UPGRADE_REQUIRED                = 426  
	STATUS_PRECONDITION_REQUIRED           = 428  
	STATUS_TOO_MANY_REQUESTS               = 429  
	STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431  
	STATUS_UNAVAILABLE_FOR_LEGAL_REASONS   = 451  
	STATUS_INTERNAL_SERVER_ERROR           = 500  
	STATUS_NOT_IMPLEMENTED                 = 501  
	STATUS_BAD_GATEWAY                     = 502  
	STATUS_SERVICE_UNAVAILABLE             = 503  
	STATUS_GATEWAY_TIMEOUT                 = 504  
	STATUS_HTTPVERSION_NOT_SUPPORTED       = 505  
	STATUS_VARIANT_ALSO_NEGOTIATES         = 506  
	STATUS_INSUFFICIENT_STORAGE            = 507  
	STATUS_LOOP_DETECTED                   = 508  
	STATUS_NOT_EXTENDED                    = 510  
	STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511  
)
const USER_AGENT = "go-ek-req"
type Query map[string]interface{}
type Headers map[string]string
type Request struct {
	Method            string       
	URL               string       
	Query             Query        
	Body              interface{}  
	Headers           Headers      
	ContentType       string       
	Accept            string       
	BasicAuthUsername string       
	BasicAuthPassword string       
	AutoDiscard       bool         
	FollowRedirect    bool         
	Close             bool         
}
type Response struct {
	*http.Response
	URL string
}
type RequestError struct {
	class int
	desc  string
}
type Engine struct {
	UserAgent string  
	Dialer    *net.Dialer      
	Transport *http.Transport  
	Client    *http.Client     
	dialTimeout    float64  
	requestTimeout float64  
	initialized bool
}
var (
	ErrEngineIsNil = RequestError{ERROR_CREATE_REQUEST, "Engine is nil"}
	ErrClientIsNil = RequestError{ERROR_CREATE_REQUEST, "Engine.Client is nil"}
	ErrTransportIsNil = RequestError{ERROR_CREATE_REQUEST, "Engine.Transport is nil"}
	ErrDialerIsNil = RequestError{ERROR_CREATE_REQUEST, "Engine.Dialer is nil"}
	ErrEmptyURL = RequestError{ERROR_CREATE_REQUEST, "URL property can't be empty and must be set"}
	ErrUnsupportedScheme = RequestError{ERROR_CREATE_REQUEST, "Unsupported scheme in URL"}
)
var Global = &Engine{
	dialTimeout: 10.0,
}
var ioCopyFunc = io.Copy
var useFakeFormGenerator = false
func SetUserAgent(app, version string, subs ...string) {
	Global.SetUserAgent(app, version, subs...)
}
func SetDialTimeout(timeout float64) {
	Global.SetDialTimeout(timeout)
}
func SetRequestTimeout(timeout float64) {
	Global.SetRequestTimeout(timeout)
}
func (e *Engine) Init() *Engine {
	if e.initialized {
		return e
	}
	if e.Dialer == nil {
		e.Dialer = &net.Dialer{}
	}
	if e.Transport == nil {
		e.Transport = &http.Transport{
			Dial:  e.Dialer.Dial,
			Proxy: http.ProxyFromEnvironment,
		}
	} else {
		e.Transport.Dial = e.Dialer.Dial
	}
	if e.Client == nil {
		e.Client = &http.Client{
			Transport: e.Transport,
		}
	}
	if e.dialTimeout > 0 {
		e.SetDialTimeout(e.dialTimeout)
	}
	if e.requestTimeout > 0 {
		e.SetRequestTimeout(e.requestTimeout)
	}
	if e.UserAgent == "" {
		e.SetUserAgent(USER_AGENT, "10")
	}
	e.dialTimeout = 0
	e.requestTimeout = 0
	e.initialized = true
	return e
}
func (e *Engine) Do(r Request) (*Response, error) {
	return e.doRequest(r, "")
}
func (e *Engine) Get(r Request) (*Response, error) {
	return e.doRequest(r, GET)
}
func (e *Engine) Post(r Request) (*Response, error) {
	return e.doRequest(r, POST)
}
func (e *Engine) Put(r Request) (*Response, error) {
	return e.doRequest(r, PUT)
}
func (e *Engine) Head(r Request) (*Response, error) {
	return e.doRequest(r, HEAD)
}
func (e *Engine) Patch(r Request) (*Response, error) {
	return e.doRequest(r, PATCH)
}
func (e *Engine) PostFile(r Request, file, fieldName string, extraFields map[string]string) (*Response, error) {
	err := configureMultipartRequest(&r, file, fieldName, extraFields)
	if err != nil {
		return nil, err
	}
	return e.doRequest(r, POST)
}
func (e *Engine) Delete(r Request) (*Response, error) {
	return e.doRequest(r, DELETE)
}
func (e *Engine) SetUserAgent(app, version string, subs ...string) {
	if e != nil {
		e.UserAgent = fmt.Sprintf(
			"%s/%s (go; %s; %s-%s)",
			app, version, runtime.Version(),
			runtime.GOARCH, runtime.GOOS,
		)
		if len(subs) != 0 {
			e.UserAgent += " " + strings.Join(subs, " ")
		}
	}
}
func (e *Engine) SetDialTimeout(timeout float64) {
	if e != nil && timeout > 0 {
		if e.Dialer == nil {
			e.dialTimeout = timeout
		} else {
			e.Dialer.Timeout = time.Duration(timeout * float64(time.Second))
		}
	}
}
func (e *Engine) SetRequestTimeout(timeout float64) {
	if e != nil && timeout > 0 {
		if e.Dialer == nil {
			e.requestTimeout = timeout
		} else {
			e.Client.Timeout = time.Duration(timeout * float64(time.Second))
		}
	}
}