func (gr *GoReq) queryStruct(content interface{}) *GoReq {
	if marshalContent, err := json.Marshal(content); err != nil {
		gr.Errors = append(gr.Errors, err)
	} else {
		var val map[string]interface{}
		if err := json.Unmarshal(marshalContent, &val); err != nil {
			gr.Errors = append(gr.Errors, err)
		} else {
			for k, v := range val {
				gr.QueryData.Add(k, v.(string))
			}
		}
	}
	return gr
}
create queryData by parsing structs.
package goreq
import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net"
	"net/http"
	"net/http/cookiejar"
	"net/http/httputil"
	"net/url"
	"os"
	"reflect"
	"strings"
	"time"
	"github.com/moul/http2curl"
	"golang.org/x/net/proxy"
	"golang.org/x/net/publicsuffix"
)
type Request *http.Request
type Response *http.Response
const (
	POST    = "POST"
	GET     = "GET"
	HEAD    = "HEAD"
	PUT     = "PUT"
	DELETE  = "DELETE"
	PATCH   = "PATCH"
	OPTIONS = "OPTIONS"
)
type GoReq struct {
	URL              string
	Host             string
	Method           string
	Header           map[string]string
	Data             map[string]interface{}
	FormData         url.Values
	QueryData        url.Values
	RawStringData    string
	RawBytesData     []byte
	FilePath         string
	FileParam        string
	Client           *http.Client
	CheckRedirect    func(r *http.Request, v []*http.Request) error
	Transport        *http.Transport
	Cookies          []*http.Cookie
	Errors           []error
	BasicAuth        struct{ Username, Password string }
	Debug            bool
	CurlCommand      bool
	logger           *log.Logger
	retry            *RetryConfig
	bindResponseBody interface{}
}
type RetryConfig struct {
	RetryCount int
	RetryTimeout int
	RetryOnHTTPStatus []int
}
func New() *GoReq {
	gr := &GoReq{
		Data:             make(map[string]interface{}),
		Header:           make(map[string]string),
		FormData:         url.Values{},
		QueryData:        url.Values{},
		Client:           nil,
		Transport:        &http.Transport{},
		Cookies:          make([]*http.Cookie, 0),
		Errors:           nil,
		BasicAuth:        struct{ Username, Password string }{},
		Debug:            false,
		CurlCommand:      false,
		logger:           log.New(os.Stderr, "[goreq]", log.LstdFlags),
		retry:            &RetryConfig{RetryCount: 0, RetryTimeout: 0, RetryOnHTTPStatus: nil},
		bindResponseBody: nil,
	}
	return gr
}
func (gr *GoReq) SetDebug(enable bool) *GoReq {
	gr.Debug = enable
	return gr
}
func (gr *GoReq) SetCurlCommand(enable bool) *GoReq {
	gr.CurlCommand = enable
	return gr
}
func (gr *GoReq) SetLogger(logger *log.Logger) *GoReq {
	gr.logger = logger
	return gr
}
func (gr *GoReq) SetClient(client *http.Client) *GoReq {
	gr.Client = client
	return gr
}
func (gr *GoReq) setDefaultClient() *GoReq {
	cookiejarOptions := cookiejar.Options{
		PublicSuffixList: publicsuffix.List,
	}
	jar, _ := cookiejar.New(&cookiejarOptions)
	client := &http.Client{Jar: jar}
	gr.Client = client
	return gr
}
func (gr *GoReq) Reset() *GoReq {
	gr.URL = ""
	gr.Method = ""
	gr.Header = make(map[string]string)
	gr.Data = make(map[string]interface{})
	gr.FormData = url.Values{}
	gr.QueryData = url.Values{}
	gr.RawStringData = ""
	gr.RawBytesData = make([]byte, 0)
	gr.FilePath = ""
	gr.FileParam = ""
	gr.Cookies = make([]*http.Cookie, 0)
	gr.Errors = nil
	gr.retry = &RetryConfig{RetryCount: 0, RetryTimeout: 0, RetryOnHTTPStatus: nil}
	gr.bindResponseBody = nil
	return gr
}
func (gr *GoReq) Get(targetURL string) *GoReq {
	gr.Method = GET
	gr.URL = targetURL
	gr.Errors = nil
	return gr
}
func (gr *GoReq) Post(targetURL string) *GoReq {
	gr.Method = POST
	gr.URL = targetURL
	gr.Errors = nil
	return gr
}
func (gr *GoReq) Head(targetURL string) *GoReq {
	gr.Method = HEAD
	gr.URL = targetURL
	gr.Errors = nil
	return gr
}
func (gr *GoReq) Put(targetURL string) *GoReq {
	gr.Method = PUT
	gr.URL = targetURL
	gr.Errors = nil
	return gr
}
func (gr *GoReq) Delete(targetURL string) *GoReq {
	gr.Method = DELETE
	gr.URL = targetURL
	gr.Errors = nil
	return gr
}
func (gr *GoReq) Patch(targetURL string) *GoReq {
	gr.Method = PATCH
	gr.URL = targetURL
	gr.Errors = nil
	return gr
}
func (gr *GoReq) Options(targetURL string) *GoReq {
	gr.Method = OPTIONS
	gr.URL = targetURL
	gr.Errors = nil
	return gr
}
func (gr *GoReq) SetHeader(param string, value string) *GoReq {
	gr.Header[param] = value
	return gr
}
func (gr *GoReq) SetHeaders(headers interface{}) *GoReq {
	switch v := reflect.ValueOf(headers); v.Kind() {
	case reflect.String:
		gr.setJSONHeaders(v.String())
	case reflect.Struct:
		gr.setStructHeaders(v.Interface())
	default:
	}
	return gr
}
func (gr *GoReq) setStructHeaders(headers interface{}) *GoReq {
	if marshalContent, err := json.Marshal(headers); err != nil {
		gr.Errors = append(gr.Errors, err)
	} else {
		var val map[string]string
		if err := json.Unmarshal(marshalContent, &val); err != nil {
			gr.Errors = append(gr.Errors, err)
		} else {
			for k, v := range val {
				gr.Header[k] = v
			}
		}
	}
	return gr
}
func (gr *GoReq) setJSONHeaders(headers string) *GoReq {
	var val map[string]string
	if err := json.Unmarshal([]byte(headers), &val); err == nil {
		for k, v := range val {
			gr.Header[k] = v
		}
	} else {
		gr.Errors = append(gr.Errors, err)
	}
	return gr
}
func (gr *GoReq) SetBasicAuth(username string, password string) *GoReq {
	gr.BasicAuth = struct{ Username, Password string }{username, password}
	return gr
}
func (gr *GoReq) AddCookie(c *http.Cookie) *GoReq {
	gr.Cookies = append(gr.Cookies, c)
	return gr
}
func (gr *GoReq) AddCookies(cookies []*http.Cookie) *GoReq {
	gr.Cookies = append(gr.Cookies, cookies...)
	return gr
}
var ShortContentTypes = map[string]string{
	"html":       "text/html",
	"text":       "text/plain",
	"json":       "application/json",
	"xml":        "application/xml",
	"urlencoded": "application/x-www-form-urlencoded",
	"form":       "application/x-www-form-urlencoded",
	"form-data":  "application/x-www-form-urlencoded",
	"stream":     "application/octet-stream",
}
func (gr *GoReq) ContentType(typeStr string) *GoReq {
	if ShortContentTypes[typeStr] != "" {
		typeStr = ShortContentTypes[typeStr]
	}
	gr.Header["Content-Type"] = typeStr
	return gr
}
func (gr *GoReq) Query(content interface{}) *GoReq {
	switch v := reflect.ValueOf(content); v.Kind() {
	case reflect.String:
		gr.queryString(v.String())
	case reflect.Struct:
		gr.queryStruct(v.Interface())
	default:
	}
	return gr
}
func (gr *GoReq) BindHost(host string) *GoReq {
	gr.Host = host
	return gr
}