313 lines
7.6 KiB
Go
313 lines
7.6 KiB
Go
/*
|
||
* @FileName: simpleRequest.go
|
||
* @Author: JJXu
|
||
* @CreateTime: 2022/3/2 上午12:33
|
||
* @Description:
|
||
*/
|
||
|
||
package simpleRequest
|
||
|
||
import (
|
||
"bytes"
|
||
"crypto/tls"
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"io/ioutil"
|
||
"mime/multipart"
|
||
"net/http"
|
||
"net/url"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
func NewRequest() *SimpleRequest {
|
||
var (
|
||
hd = http.Header{}
|
||
qp = url.Values{}
|
||
)
|
||
|
||
return &SimpleRequest{
|
||
//headers: make(map[string]string),
|
||
//cookies: make(map[string]string),
|
||
timeout: time.Second * 7,
|
||
queryParams: qp,
|
||
headers: hd,
|
||
tempBody: make(map[string]interface{}),
|
||
}
|
||
}
|
||
|
||
type SimpleRequest struct {
|
||
url string
|
||
queryParams url.Values
|
||
body io.Reader
|
||
headers http.Header
|
||
transport *http.Transport
|
||
|
||
tempBody map[string]interface{}
|
||
timeout time.Duration
|
||
|
||
Response http.Response //用于获取完整的返回内容。请注意要在请求之后才能获取
|
||
Request http.Request //用于获取完整的请求内容。请注意要在请求之后才能获取
|
||
//cookies map[string]string
|
||
//data interface{}
|
||
//cli *http.Client
|
||
//debug bool
|
||
//method string
|
||
//time int64
|
||
//disableKeepAlives bool
|
||
//tlsClientConfig *tls.Config
|
||
//jar http.CookieJar
|
||
//proxy func(*http.Request) (*url.URL, error)
|
||
//checkRedirect func(req *http.Request, via []*http.Request) error
|
||
}
|
||
|
||
func (s *SimpleRequest) NewRequest() *SimpleRequest {
|
||
var qp = url.Values{}
|
||
return &SimpleRequest{
|
||
//headers: make(map[string]string),
|
||
//cookies: make(map[string]string),
|
||
timeout: time.Second * 7,
|
||
queryParams: qp,
|
||
tempBody: make(map[string]interface{}),
|
||
}
|
||
}
|
||
|
||
//------------------------------------------------------
|
||
//
|
||
// 数据准备
|
||
|
||
//Authorization 添加令牌的方法集合
|
||
func (s *SimpleRequest) Authorization() *Authorization {
|
||
return &Authorization{
|
||
simpleReq: s,
|
||
}
|
||
}
|
||
|
||
//Headers 添加请求头
|
||
func (s *SimpleRequest) Headers() *HeadersConf {
|
||
return &HeadersConf{
|
||
simpleReq: s,
|
||
}
|
||
}
|
||
|
||
//Body 添加请求体
|
||
func (s *SimpleRequest) Body() *BodyConf {
|
||
return &BodyConf{
|
||
simpleReq: s,
|
||
}
|
||
}
|
||
|
||
//QueryParams 添加url后面的参数
|
||
func (s *SimpleRequest) QueryParams() *QueryParams {
|
||
return &QueryParams{
|
||
simpleReq: s,
|
||
}
|
||
}
|
||
|
||
//跳过证书验证
|
||
func (s *SimpleRequest) SkipCertVerify() *SimpleRequest {
|
||
|
||
s.transport = &http.Transport{
|
||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||
}
|
||
return s
|
||
}
|
||
|
||
//设置超时时间
|
||
func (s *SimpleRequest) TimeOut(t time.Duration) *SimpleRequest {
|
||
s.timeout = t
|
||
return s
|
||
}
|
||
|
||
//------------------------------------------------------
|
||
//
|
||
// 发送请求
|
||
//
|
||
//发送postt请求
|
||
func (s *SimpleRequest) do(request *http.Request) (body []byte, err error) {
|
||
//3. 建立http客户端
|
||
client := &http.Client{
|
||
Timeout: s.timeout,
|
||
}
|
||
if s.transport != nil {
|
||
client.Transport = s.transport
|
||
}
|
||
//3.1 发送数据
|
||
resp, err := client.Do(request)
|
||
if err != nil {
|
||
fmt.Println("【Request Error】:", err.Error())
|
||
return
|
||
}
|
||
|
||
//v0.0.2更新,将request和response内容返回,便于用户进行分析 JJXu 03-11-2022
|
||
if resp != nil {
|
||
s.Response = *resp
|
||
}
|
||
if request != nil {
|
||
s.Request = *request
|
||
}
|
||
|
||
defer resp.Body.Close()
|
||
//3.2 获取数据
|
||
body, err = ioutil.ReadAll(resp.Body)
|
||
return
|
||
}
|
||
|
||
// POST method does POST HTTP request. It's defined in section 2 of RFC5789.
|
||
func (s *SimpleRequest) POST(urls string) (body []byte, err error) {
|
||
s.initBody()
|
||
r, err := http.NewRequest(http.MethodPost, urls, s.body)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
//headers
|
||
for k := range s.headers {
|
||
r.Header[k] = append(r.Header[k], s.headers[k]...)
|
||
s.headers.Del(k)
|
||
}
|
||
|
||
//queryParams
|
||
r.URL.RawQuery = s.queryParams.Encode()
|
||
|
||
body, err = s.do(r)
|
||
|
||
return
|
||
}
|
||
|
||
// GET method does GET HTTP request. It's defined in section 2 of RFC5789.
|
||
func (s *SimpleRequest) GET(urls string) (body []byte, err error) {
|
||
// body
|
||
s.initBody()
|
||
r, err := http.NewRequest(http.MethodGet, urls, s.body)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
//headers
|
||
for k := range s.headers {
|
||
r.Header[k] = append(r.Header[k], s.headers[k]...)
|
||
s.headers.Del(k)
|
||
}
|
||
//queryParams
|
||
r.URL.RawQuery = s.queryParams.Encode()
|
||
|
||
body, err = s.do(r)
|
||
return
|
||
}
|
||
|
||
//通用的请求方法
|
||
func (s *SimpleRequest) LaunchTo(urls, method string) (body []byte, err error) {
|
||
// body
|
||
s.initBody()
|
||
r, err := http.NewRequest(method, urls, s.body)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
//headers
|
||
for k := range s.headers {
|
||
r.Header[k] = append(r.Header[k], s.headers[k]...)
|
||
s.headers.Del(k)
|
||
}
|
||
//queryParams
|
||
r.URL.RawQuery = s.queryParams.Encode()
|
||
|
||
body, err = s.do(r)
|
||
return
|
||
}
|
||
|
||
// PUT method does PUT HTTP request. It's defined in section 4.3.4 of RFC7231.
|
||
func (s *SimpleRequest) PUT(url string) (body []byte, err error) {
|
||
return s.LaunchTo(url, http.MethodPut)
|
||
}
|
||
|
||
// DELETE method does DELETE HTTP request. It's defined in section 2 of RFC5789.
|
||
func (s *SimpleRequest) DELETE(url string) (body []byte, err error) {
|
||
return s.LaunchTo(url, http.MethodDelete)
|
||
}
|
||
|
||
// Patch method does Patch HTTP request. It's defined in section 2 of RFC5789.
|
||
func (s *SimpleRequest) PATCH(url string) (body []byte, err error) {
|
||
return s.LaunchTo(url, http.MethodPatch)
|
||
}
|
||
|
||
// HEAD method does HEAD HTTP request. It's defined in section 2 of RFC5789.
|
||
func (s *SimpleRequest) HEAD(url string) (body []byte, err error) {
|
||
return s.LaunchTo(url, http.MethodHead)
|
||
}
|
||
|
||
// CONNECT method does CONNECT HTTP request. It's defined in section 2 of RFC5789.
|
||
func (s *SimpleRequest) CONNECT(url string) (body []byte, err error) {
|
||
return s.LaunchTo(url, http.MethodConnect)
|
||
}
|
||
|
||
// OPTIONS method does OPTIONS HTTP request. It's defined in section 2 of RFC5789.
|
||
func (s *SimpleRequest) OPTIONS(url string) (body []byte, err error) {
|
||
return s.LaunchTo(url, http.MethodOptions)
|
||
}
|
||
|
||
// TRACE method does TRACE HTTP request. It's defined in section 2 of RFC5789.
|
||
func (s *SimpleRequest) TRACE(url string) (body []byte, err error) {
|
||
return s.LaunchTo(url, http.MethodTrace)
|
||
}
|
||
|
||
//------------------------------------------------------
|
||
//
|
||
// 这里数据
|
||
//
|
||
func (s *SimpleRequest) initBody() {
|
||
contentTypeData := s.headers.Get(hdrContentTypeKey)
|
||
switch {
|
||
case IsJSONType(contentTypeData):
|
||
jsonData, err := json.Marshal(s.tempBody)
|
||
if err == nil {
|
||
s.body = bytes.NewReader(jsonData)
|
||
} else {
|
||
s.body = bytes.NewReader([]byte("{}"))
|
||
}
|
||
case strings.Contains(contentTypeData, "multipart/form-data"):
|
||
body := &bytes.Buffer{}
|
||
writer := multipart.NewWriter(body)
|
||
//data := url.Values{}
|
||
for k, sv := range s.tempBody {
|
||
switch sv.(type) {
|
||
case string:
|
||
strSv, _ := sv.(string)
|
||
_ = writer.WriteField(k, strSv)
|
||
case []string:
|
||
sss, _ := sv.([]string)
|
||
for _, v := range sss {
|
||
_ = writer.WriteField(k, v)
|
||
}
|
||
}
|
||
}
|
||
err := writer.Close()
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
s.headers.Set("Content-Type", writer.FormDataContentType())
|
||
s.body = body
|
||
case IsXMLType(contentTypeData):
|
||
//application/soap+xml ,application/xml
|
||
data, _ := s.tempBody[stringBodyType].(string)
|
||
s.body = strings.NewReader(data)
|
||
case strings.Contains(contentTypeData, "text") || strings.Contains(contentTypeData, javaScriptType):
|
||
data, _ := s.tempBody[stringBodyType].(string)
|
||
s.body = strings.NewReader(data)
|
||
case contentTypeData == "" || strings.Contains(contentTypeData, "form-urlencoded"):
|
||
//默认为x-www-form-urlencoded格式
|
||
tmpData := url.Values{}
|
||
for k, v := range s.tempBody {
|
||
tmpData.Set(k, fmt.Sprintf("%v", v))
|
||
}
|
||
s.body = strings.NewReader(tmpData.Encode())
|
||
s.Headers().ConentType_formUrlencoded()
|
||
default:
|
||
//todo 自动判断数据类型
|
||
tmpData := url.Values{}
|
||
for k, v := range tmpData {
|
||
tmpData.Set(k, fmt.Sprintf("%v", v))
|
||
}
|
||
s.body = strings.NewReader(tmpData.Encode())
|
||
}
|
||
}
|