You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gorequest/http.go

384 lines
10 KiB

2 years ago
package gorequest
import (
2 years ago
"bytes"
5 months ago
"compress/flate"
"compress/gzip"
2 years ago
"context"
"crypto/tls"
2 years ago
"errors"
"fmt"
5 months ago
cookiemonster "github.com/MercuryEngineering/CookieMonster"
"go.dtapp.net/gojson"
2 years ago
"go.dtapp.net/gotime"
2 years ago
"go.dtapp.net/gotrace_id"
2 years ago
"io"
"log"
2 years ago
"net/http"
"net/url"
"strings"
2 years ago
"time"
2 years ago
)
// Response 返回内容
type Response struct {
1 year ago
RequestId string //【请求】编号
2 years ago
RequestUri string //【请求】链接
2 years ago
RequestParams Params //【请求】参数
2 years ago
RequestMethod string //【请求】方式
2 years ago
RequestHeader Headers //【请求】头部
5 months ago
RequestCookie string //【请求】Cookie
2 years ago
RequestTime time.Time //【请求】时间
2 years ago
ResponseHeader http.Header //【返回】头部
ResponseStatus string //【返回】状态
ResponseStatusCode int //【返回】状态码
ResponseBody []byte //【返回】内容
ResponseContentLength int64 //【返回】大小
2 years ago
ResponseTime time.Time //【返回】时间
2 years ago
}
2 years ago
// App 实例
2 years ago
type App struct {
5 months ago
Uri string // 全局请求地址没有设置url才会使用
Error error // 错误
httpUri string // 请求地址
httpMethod string // 请求方法
httpHeader Headers // 请求头
httpParams Params // 请求参数
httpCookie string // Cookie
responseContent Response // 返回内容
httpContentType string // 请求内容类型
debug bool // 是否开启调试模式
p12Cert *tls.Certificate // p12证书内容
tlsMinVersion, tlsMaxVersion uint16 // TLS版本
2 years ago
}
// NewHttp 实例化
2 years ago
func NewHttp() *App {
5 months ago
app := &App{
2 years ago
httpHeader: NewHeaders(),
httpParams: NewParams(),
}
5 months ago
return app
2 years ago
}
2 years ago
// SetDebug 设置调试模式
func (app *App) SetDebug() {
app.debug = true
}
// SetUri 设置请求地址
func (app *App) SetUri(uri string) {
3 months ago
if uri != "" {
app.httpUri = uri
}
2 years ago
}
2 years ago
// SetMethod 设置请求方式
2 years ago
func (app *App) SetMethod(method string) {
3 months ago
if method != "" {
app.httpMethod = method
}
2 years ago
}
// SetHeader 设置请求头
2 years ago
func (app *App) SetHeader(key, value string) {
2 years ago
app.httpHeader.Set(key, value)
}
// SetHeaders 批量设置请求头
2 years ago
func (app *App) SetHeaders(headers Headers) {
2 years ago
for key, value := range headers {
app.httpHeader.Set(key, value)
}
}
5 months ago
// SetTlsVersion 设置TLS版本
func (app *App) SetTlsVersion(minVersion, maxVersion uint16) {
app.tlsMinVersion = minVersion
app.tlsMaxVersion = maxVersion
}
2 years ago
// SetAuthToken 设置身份验证令牌
2 years ago
func (app *App) SetAuthToken(token string) {
3 months ago
if token != "" {
app.httpHeader.Set("Authorization", fmt.Sprintf("Bearer %s", token))
}
2 years ago
}
4 months ago
// SetUserAgent 设置用户代理,传空字符串就随机设置
2 years ago
func (app *App) SetUserAgent(ua string) {
3 months ago
if ua != "" {
app.httpHeader.Set("User-Agent", ua)
2 years ago
}
}
// SetContentTypeJson 设置JSON格式
2 years ago
func (app *App) SetContentTypeJson() {
2 years ago
app.httpContentType = httpParamsModeJson
2 years ago
}
// SetContentTypeForm 设置FORM格式
2 years ago
func (app *App) SetContentTypeForm() {
2 years ago
app.httpContentType = httpParamsModeForm
2 years ago
}
// SetContentTypeXml 设置XML格式
func (app *App) SetContentTypeXml() {
app.httpContentType = httpParamsModeXml
}
2 years ago
// SetParam 设置请求参数
2 years ago
func (app *App) SetParam(key string, value interface{}) {
2 years ago
app.httpParams.Set(key, value)
}
// SetParams 批量设置请求参数
2 years ago
func (app *App) SetParams(params Params) {
2 years ago
for key, value := range params {
app.httpParams.Set(key, value)
}
}
5 months ago
// SetCookie 设置Cookie
3 months ago
func (app *App) SetCookie(cookie string) {
if cookie != "" {
app.httpCookie = cookie
}
5 months ago
}
2 years ago
// SetP12Cert 设置证书
func (app *App) SetP12Cert(content *tls.Certificate) {
app.p12Cert = content
}
2 years ago
// Get 发起GET请求
2 years ago
func (app *App) Get(ctx context.Context, uri ...string) (httpResponse Response, err error) {
2 years ago
if len(uri) == 1 {
app.Uri = uri[0]
}
2 years ago
// 设置请求方法
app.httpMethod = http.MethodGet
2 years ago
return request(app, ctx)
2 years ago
}
// Post 发起POST请求
2 years ago
func (app *App) Post(ctx context.Context, uri ...string) (httpResponse Response, err error) {
2 years ago
if len(uri) == 1 {
app.Uri = uri[0]
}
2 years ago
// 设置请求方法
app.httpMethod = http.MethodPost
2 years ago
return request(app, ctx)
2 years ago
}
// Request 发起请求
2 years ago
func (app *App) Request(ctx context.Context) (httpResponse Response, err error) {
return request(app, ctx)
2 years ago
}
2 years ago
// 请求接口
2 years ago
func request(app *App, ctx context.Context) (httpResponse Response, err error) {
2 years ago
2 years ago
// 赋值
httpResponse.RequestTime = gotime.Current().Time
2 years ago
httpResponse.RequestUri = app.httpUri
httpResponse.RequestMethod = app.httpMethod
httpResponse.RequestParams = app.httpParams.DeepCopy()
2 years ago
httpResponse.RequestHeader = app.httpHeader.DeepCopy()
5 months ago
httpResponse.RequestCookie = app.httpCookie
2 years ago
2 years ago
// 判断网址
2 years ago
if httpResponse.RequestUri == "" {
httpResponse.RequestUri = app.Uri
2 years ago
}
2 years ago
if httpResponse.RequestUri == "" {
app.Error = errors.New("没有设置Uri")
5 months ago
if app.debug {
log.Printf("{%s}------------------------\n", gotrace_id.GetTraceIdContext(ctx))
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
2 years ago
}
2 years ago
// 创建 http 客户端
client := &http.Client{}
5 months ago
transportStatus := false
transport := &http.Transport{}
transportTls := &tls.Config{}
if app.p12Cert != nil {
5 months ago
transportStatus = true
// 配置
transportTls.Certificates = []tls.Certificate{*app.p12Cert}
transport.DisableCompression = true
}
if app.tlsMinVersion != 0 && app.tlsMaxVersion != 0 {
transportStatus = true
// 配置
transportTls.MinVersion = app.tlsMinVersion
transportTls.MaxVersion = app.tlsMaxVersion
}
if transportStatus {
transport.TLSClientConfig = transportTls
client = &http.Client{
Transport: transport,
}
}
2 years ago
// 请求类型
5 months ago
if app.httpContentType == "" {
app.httpContentType = httpParamsModeJson
}
2 years ago
switch app.httpContentType {
case httpParamsModeJson:
httpResponse.RequestHeader.Set("Content-Type", "application/json")
case httpParamsModeForm:
httpResponse.RequestHeader.Set("Content-Type", "application/x-www-form-urlencoded")
case httpParamsModeXml:
httpResponse.RequestHeader.Set("Content-Type", "text/xml")
}
2 years ago
// 跟踪编号
1 year ago
httpResponse.RequestId = gotrace_id.GetTraceIdContext(ctx)
3 months ago
if httpResponse.RequestId != "" {
httpResponse.RequestHeader.Set("X-Request-Id", httpResponse.RequestId)
2 years ago
}
2 years ago
// 请求内容
2 years ago
var reqBody io.Reader
2 years ago
if httpResponse.RequestMethod == http.MethodPost && app.httpContentType == httpParamsModeJson {
5 months ago
jsonStr, err := gojson.Marshal(httpResponse.RequestParams)
2 years ago
if err != nil {
app.Error = errors.New(fmt.Sprintf("解析出错 %s", err))
5 months ago
if app.debug {
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
2 years ago
}
// 赋值
reqBody = bytes.NewBuffer(jsonStr)
}
2 years ago
2 years ago
if httpResponse.RequestMethod == http.MethodPost && app.httpContentType == httpParamsModeForm {
2 years ago
// 携带 form 参数
form := url.Values{}
5 months ago
for k, v := range httpResponse.RequestParams {
form.Add(k, GetParamsString(v))
2 years ago
}
2 years ago
// 赋值
reqBody = strings.NewReader(form.Encode())
2 years ago
}
if app.httpContentType == httpParamsModeXml {
5 months ago
reqBody, err = ToXml(httpResponse.RequestParams)
if err != nil {
app.Error = errors.New(fmt.Sprintf("解析XML出错 %s", err))
5 months ago
if app.debug {
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
}
}
2 years ago
// 创建请求
2 years ago
req, err := http.NewRequest(httpResponse.RequestMethod, httpResponse.RequestUri, reqBody)
2 years ago
if err != nil {
app.Error = errors.New(fmt.Sprintf("创建请求出错 %s", err))
5 months ago
if app.debug {
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
2 years ago
}
// GET 请求携带查询参数
2 years ago
if httpResponse.RequestMethod == http.MethodGet {
5 months ago
q := req.URL.Query()
for k, v := range httpResponse.RequestParams {
q.Add(k, GetParamsString(v))
2 years ago
}
5 months ago
req.URL.RawQuery = q.Encode()
2 years ago
}
// 设置请求头
2 years ago
if len(httpResponse.RequestHeader) > 0 {
for key, value := range httpResponse.RequestHeader {
5 months ago
req.Header.Set(key, fmt.Sprintf("%v", value))
}
}
// 设置Cookie
if httpResponse.RequestCookie != "" {
cookies, _ := cookiemonster.ParseString(httpResponse.RequestCookie)
if len(cookies) > 0 {
for _, c := range cookies {
req.AddCookie(c)
}
} else {
req.Header.Set("Cookie", httpResponse.RequestCookie)
2 years ago
}
}
5 months ago
if app.debug {
log.Printf("{%s}请求Uri%s %s\n", httpResponse.RequestId, httpResponse.RequestMethod, httpResponse.RequestUri)
log.Printf("{%s}请求Params Get%+v\n", httpResponse.RequestId, req.URL.RawQuery)
log.Printf("{%s}请求Params Post%+v\n", httpResponse.RequestId, reqBody)
log.Printf("{%s}请求Header%+v\n", httpResponse.RequestId, req.Header)
}
2 years ago
// 发送请求
resp, err := client.Do(req)
if err != nil {
app.Error = errors.New(fmt.Sprintf("请求出错 %s", err))
5 months ago
if app.debug {
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
2 years ago
}
// 最后关闭连接
defer resp.Body.Close()
5 months ago
var reader io.ReadCloser
switch resp.Header.Get("Content-Encoding") {
case "gzip":
reader, _ = gzip.NewReader(resp.Body)
case "deflate":
reader = flate.NewReader(resp.Body)
default:
reader = resp.Body
}
defer reader.Close() // nolint
2 years ago
// 读取内容
5 months ago
body, err := io.ReadAll(reader)
2 years ago
if err != nil {
app.Error = errors.New(fmt.Sprintf("解析内容出错 %s", err))
5 months ago
if app.debug {
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
2 years ago
}
// 赋值
2 years ago
httpResponse.ResponseTime = gotime.Current().Time
2 years ago
httpResponse.ResponseStatus = resp.Status
httpResponse.ResponseStatusCode = resp.StatusCode
httpResponse.ResponseHeader = resp.Header
httpResponse.ResponseBody = body
httpResponse.ResponseContentLength = resp.ContentLength
5 months ago
if app.debug {
log.Printf("{%s}返回Status%s\n", httpResponse.RequestId, httpResponse.ResponseStatus)
log.Printf("{%s}返回Header%+v\n", httpResponse.RequestId, httpResponse.ResponseHeader)
log.Printf("{%s}返回Body%s\n", httpResponse.RequestId, httpResponse.ResponseBody)
log.Printf("{%s}------------------------\n", gotrace_id.GetTraceIdContext(ctx))
2 years ago
}
2 years ago
return httpResponse, err
}