- request:合并http

master
李光春 2 years ago
parent 7c13b8e2c9
commit 9c6861a559

@ -13,6 +13,7 @@
- files更新
- ip更新
- storage增加存储功能
- request合并http
## v1.0.39 / 2021-12-27

@ -1,281 +0,0 @@
package gohttp
import (
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"go.dtapp.net/library/utils/goheader"
"go.dtapp.net/library/utils/gorequest"
"io"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"strings"
)
type Response struct {
Status string
StatusCode int
Header http.Header
Body []byte
ContentLength int64
}
func Get(url string, params map[string]interface{}) (httpResponse Response, err error) {
// 创建 http 客户端
client := &http.Client{}
// 创建请求
req, _ := http.NewRequest(http.MethodGet, url, nil)
if len(params) > 0 {
// GET 请求携带查询参数
q := req.URL.Query()
for k, v := range params {
q.Add(k, getString(v))
}
req.URL.RawQuery = q.Encode()
}
// 设置请求头
req.Header.Set("User-Agent", gorequest.GetRandomUserAgent())
// 发送请求
resp, err := client.Do(req)
if err != nil {
// 格式化返回错误
return httpResponse, errors.New(fmt.Sprintf("请求出错 %s", err))
}
// 最后关闭连接
defer resp.Body.Close()
// 读取内容
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return httpResponse, errors.New(fmt.Sprintf("解析内容出错 %s", err))
}
httpResponse.Status = resp.Status
httpResponse.StatusCode = resp.StatusCode
httpResponse.Header = resp.Header
httpResponse.Body = respBody
httpResponse.ContentLength = resp.ContentLength
return httpResponse, err
}
func GetJsonHeader(url string, params map[string]interface{}, headers goheader.Headers) (httpResponse Response, err error) {
// 创建 http 客户端
client := &http.Client{}
// 创建请求
req, _ := http.NewRequest(http.MethodGet, url, nil)
if len(params) > 0 {
// GET 请求携带查询参数
q := req.URL.Query()
for k, v := range params {
q.Add(k, getString(v))
}
req.URL.RawQuery = q.Encode()
}
// 设置请求头
req.Header.Set("User-Agent", gorequest.GetRandomUserAgent())
req.Header.Set("Content-Type", "application/json")
for key, value := range headers {
req.Header.Set(key, value.(string))
}
// 发送请求
resp, err := client.Do(req)
if err != nil {
// 格式化返回错误
return httpResponse, errors.New(fmt.Sprintf("请求出错 %s", err))
}
// 最后关闭连接
defer resp.Body.Close()
// 读取内容
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return httpResponse, errors.New(fmt.Sprintf("解析内容出错 %s", err))
}
httpResponse.Status = resp.Status
httpResponse.StatusCode = resp.StatusCode
httpResponse.Header = resp.Header
httpResponse.Body = respBody
httpResponse.ContentLength = resp.ContentLength
return httpResponse, err
}
func PostForm(targetUrl string, params map[string]interface{}) (httpResponse Response, err error) {
// 创建 http 客户端
client := &http.Client{}
// 携带 form 参数
form := url.Values{}
if len(params) > 0 {
for k, v := range params {
form.Add(k, getString(v))
}
}
// 创建请求
req, _ := http.NewRequest(http.MethodPost, targetUrl, strings.NewReader(form.Encode()))
// 设置请求头
req.Header.Set("User-Agent", gorequest.GetRandomUserAgent())
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// 发送请求
resp, err := client.Do(req)
if err != nil {
// 格式化返回错误
return httpResponse, errors.New(fmt.Sprintf("请求出错 %s", err))
}
// 最后关闭连接
defer resp.Body.Close()
// 读取内容
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return httpResponse, errors.New(fmt.Sprintf("解析内容出错 %s", err))
}
httpResponse.Status = resp.Status
httpResponse.StatusCode = resp.StatusCode
httpResponse.Header = resp.Header
httpResponse.Body = respBody
httpResponse.ContentLength = resp.ContentLength
return httpResponse, err
}
func PostJson(targetUrl string, paramsStr []byte) (httpResponse Response, err error) {
// 创建请求
req, _ := http.NewRequest(http.MethodPost, targetUrl, bytes.NewBuffer(paramsStr))
// 设置请求头
req.Header.Set("User-Agent", gorequest.GetRandomUserAgent())
req.Header.Set("Content-Type", "application/json")
// 创建 http 客户端
client := &http.Client{}
// 发送请求
resp, err := client.Do(req)
if err != nil {
// 格式化返回错误
return httpResponse, errors.New(fmt.Sprintf("请求出错 %s", err))
}
// 最后关闭连接
defer resp.Body.Close()
// 读取内容
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return httpResponse, errors.New(fmt.Sprintf("解析内容出错 %s", err))
}
httpResponse.Status = resp.Status
httpResponse.StatusCode = resp.StatusCode
httpResponse.Header = resp.Header
httpResponse.Body = respBody
httpResponse.ContentLength = resp.ContentLength
return httpResponse, err
}
func PostXml(targetUrl string, paramsStr []byte) (httpResponse Response, err error) {
// 创建请求
req, _ := http.NewRequest(http.MethodPost, targetUrl, bytes.NewReader(paramsStr))
// 设置请求头
req.Header.Set("User-Agent", gorequest.GetRandomUserAgent())
// 创建 http 客户端
client := &http.Client{}
// 发送请求
resp, err := client.Do(req)
if err != nil {
// 格式化返回错误
return httpResponse, errors.New(fmt.Sprintf("请求出错 %s", err))
}
// 最后关闭连接
defer resp.Body.Close()
// 读取内容
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return httpResponse, errors.New(fmt.Sprintf("解析内容出错 %s", err))
}
httpResponse.Status = resp.Status
httpResponse.StatusCode = resp.StatusCode
httpResponse.Header = resp.Header
httpResponse.Body = respBody
httpResponse.ContentLength = resp.ContentLength
return httpResponse, err
}
func PostJsonHeader(targetUrl string, paramsStr []byte, headers goheader.Headers) (httpResponse Response, err error) {
// 创建请求
req, _ := http.NewRequest(http.MethodPost, targetUrl, bytes.NewBuffer(paramsStr))
// 设置请求头
req.Header.Set("User-Agent", gorequest.GetRandomUserAgent())
req.Header.Set("Content-Type", "application/json")
for key, value := range headers {
req.Header.Set(key, value.(string))
}
// 创建 http 客户端
client := &http.Client{}
// 发送请求
resp, err := client.Do(req)
if err != nil {
// 格式化返回错误
return httpResponse, errors.New(fmt.Sprintf("请求出错 %s", err))
}
// 最后关闭连接
defer resp.Body.Close()
// 读取内容
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return httpResponse, errors.New(fmt.Sprintf("解析内容出错 %s", err))
}
httpResponse.Status = resp.Status
httpResponse.StatusCode = resp.StatusCode
httpResponse.Header = resp.Header
httpResponse.Body = respBody
httpResponse.ContentLength = resp.ContentLength
return httpResponse, err
}
func PostCert(targetUrl string, params io.Reader, p12Cert *tls.Certificate) (httpResponse Response, err error) {
if p12Cert == nil {
return httpResponse, errors.New("need p12Cert")
}
transport := &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{*p12Cert},
},
DisableCompression: true,
}
// 创建请求
req, _ := http.NewRequest(http.MethodPost, targetUrl, params)
// 设置请求头
req.Header.Set("User-Agent", gorequest.GetRandomUserAgent())
// 创建 http 客户端
client := &http.Client{
Transport: transport,
}
// 发送请求
resp, err := client.Do(req)
if err != nil {
// 格式化返回错误
return httpResponse, errors.New(fmt.Sprintf("请求出错 %s", err))
}
// 最后关闭连接
defer resp.Body.Close()
// 读取内容
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return httpResponse, errors.New(fmt.Sprintf("解析内容出错 %s", err))
}
httpResponse.Status = resp.Status
httpResponse.StatusCode = resp.StatusCode
httpResponse.Header = resp.Header
httpResponse.Body = respBody
httpResponse.ContentLength = resp.ContentLength
return httpResponse, err
}
func getString(i interface{}) string {
switch v := i.(type) {
case string:
return v
case []byte:
return string(v)
case int:
return strconv.Itoa(v)
case bool:
return strconv.FormatBool(v)
default:
marshal, _ := json.Marshal(v)
return string(marshal)
}
}

@ -1,114 +0,0 @@
package gorequest
import (
"errors"
"math/rand"
"net"
"net/http"
"runtime"
"strings"
"time"
)
// ClientIp 尽最大努力实现获取客户端 IP 的算法。
// 解析 X-Real-IP 和 X-Forwarded-For 以便于反向代理nginx 或 haproxy可以正常工作。
func ClientIp(r *http.Request) string {
// xForwardedFor
xForwardedFor := r.Header.Get("X-Forwarded-For")
ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
if ip != "" {
return ip
}
// xRealIp
ip = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
if ip != "" {
return ip
}
// HTTPCLIENTIP
HTTPCLIENTIP := r.Header.Get("HTTP_CLIENT_IP")
ip = strings.TrimSpace(strings.Split(HTTPCLIENTIP, ",")[0])
if ip != "" {
return ip
}
// HTTPXFORWARDEDFOR
HTTPXFORWARDEDFOR := r.Header.Get("HTTP_X_FORWARDED_FOR")
ip = strings.TrimSpace(strings.Split(HTTPXFORWARDEDFOR, ",")[0])
if ip != "" {
return ip
}
// system
if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil {
return ip
}
return ""
}
// GetRandomUserAgent 获取用户UA
func GetRandomUserAgent() string {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
switch runtime.GOOS {
case "linux":
return userAgentListLinux[r.Intn(len(userAgentListLinux))]
case "windows":
return userAgentListWindows[r.Intn(len(userAgentListWindows))]
default:
return userAgentListMac[r.Intn(len(userAgentListMac))]
}
}
var userAgentListWindows = []string{
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36", // Chrome 2022-02-14
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0", // Firefox 2022-02-14
"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko", // IE 2022-02-14
}
var userAgentListLinux = []string{
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36 HeyTapBrowser/40.7.35.1", // Chrome 2022-02-14
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 OnePlusBrowser/30.5.0.8", // Chrome 2022-02-14
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9a1) Gecko/20060814 Firefox/51.0", // Firefox 2022-02-14
}
var userAgentListMac = []string{
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15", // Safari 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36 Edg/98.0.1108.51", // Edge 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36", // Chrome 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0", // Firefox 2022-02-14
}
func ExternalIp() (string, error) {
faces, err := net.Interfaces()
if err != nil {
return "", err
}
for _, iface := range faces {
if iface.Flags&net.FlagUp == 0 {
continue // interface down
}
if iface.Flags&net.FlagLoopback != 0 {
continue // loopback interface
}
adders, err := iface.Addrs()
if err != nil {
return "", err
}
for _, addr := range adders {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
if ip == nil || ip.IsLoopback() {
continue
}
ip = ip.To4()
if ip == nil {
continue // not an ipv4 address
}
return ip.String(), nil
}
}
return "", errors.New("are you connected to the network")
}

@ -0,0 +1,58 @@
package gorequest
import (
"net/url"
)
// Headers 头部信息
type Headers map[string]string
// NewHeaders 新建头部信息
func NewHeaders() Headers {
P := make(Headers)
return P
}
// NewNewHeadersWith 头部信息使用
func NewNewHeadersWith(headers ...Headers) Headers {
p := make(Headers)
for _, v := range headers {
p.SetHeaders(v)
}
return p
}
// Set 设置头部信息
func (p Headers) Set(key, value string) {
p[key] = value
}
// SetHeaders 批量设置头部信息
func (p Headers) SetHeaders(headers Headers) {
for key, value := range headers {
p[key] = value
}
}
// GetQuery 获取头部信息
func (p Headers) GetQuery() string {
u := url.Values{}
for k, v := range p {
u.Set(k, v)
}
return u.Encode()
}
// DeepCopy 深度复制
func (p *Headers) DeepCopy() map[string]string {
targetMap := make(map[string]string)
// 从原始复制到目标
for key, value := range *p {
targetMap[key] = value
}
// 重新申请一个新的map
*p = map[string]string{}
return targetMap
}

@ -0,0 +1,301 @@
package gorequest
import (
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"go.dtapp.net/gotime"
"io"
"io/ioutil"
"net/http"
"net/url"
"runtime"
"strings"
"time"
)
var userAgentFormat = "DtApp-Request/%s GO/%s"
// Response 返回内容
type Response struct {
RequestUri string //【请求】链接
RequestParams Params //【请求】参数
RequestMethod string //【请求】方式
RequestHeader Headers //【请求】头部
RequestTime time.Time //【请求】时间
ResponseHeader http.Header //【返回】头部
ResponseStatus string //【返回】状态
ResponseStatusCode int //【返回】状态码
ResponseBody []byte //【返回】内容
ResponseContentLength int64 //【返回】大小
ResponseTime time.Time //【返回】时间
}
// App 实例
type App struct {
Uri string // 全局请求地址没有设置url才会使用
Error error // 错误
httpUri string // 请求地址
httpMethod string // 请求方法
httpHeader Headers // 请求头
httpParams Params // 请求参数
responseContent Response // 返回内容
httpContentType string // 请求内容类型
debug bool // 是否开启调试模式
p12Cert *tls.Certificate // p12证书内容
}
// 定义
var (
httpParamsModeJson = "JSON"
httpParamsModeXml = "XML"
httpParamsModeForm = "FORM"
)
// NewHttp 实例化
func NewHttp() *App {
return &App{
httpHeader: NewHeaders(),
httpParams: NewParams(),
}
}
// SetDebug 设置调试模式
func (app *App) SetDebug() {
app.debug = true
}
// SetUri 设置请求地址
func (app *App) SetUri(uri string) {
app.httpUri = uri
}
// SetMethod 设置请求方式
func (app *App) SetMethod(method string) {
app.httpMethod = method
}
// SetHeader 设置请求头
func (app *App) SetHeader(key, value string) {
if key == "" {
panic("url is empty")
}
app.httpHeader.Set(key, value)
}
// SetHeaders 批量设置请求头
func (app *App) SetHeaders(headers Headers) {
for key, value := range headers {
app.httpHeader.Set(key, value)
}
}
// SetAuthToken 设置身份验证令牌
func (app *App) SetAuthToken(token string) {
app.httpHeader.Set("Authorization", fmt.Sprintf("Bearer %s", token))
}
// SetUserAgent 设置用户代理,空字符串就随机设置
func (app *App) SetUserAgent(ua string) {
if ua == "" {
ua = GetRandomUserAgent()
}
app.httpHeader.Set("User-Agent", ua)
}
// SetContentTypeJson 设置JSON格式
func (app *App) SetContentTypeJson() {
app.httpContentType = httpParamsModeJson
}
// SetContentTypeForm 设置FORM格式
func (app *App) SetContentTypeForm() {
app.httpContentType = httpParamsModeForm
}
// SetContentTypeXml 设置XML格式
func (app *App) SetContentTypeXml() {
app.httpContentType = httpParamsModeXml
}
// SetParam 设置请求参数
func (app *App) SetParam(key string, value interface{}) {
if key == "" {
panic("url is empty")
}
app.httpParams.Set(key, value)
}
// SetParams 批量设置请求参数
func (app *App) SetParams(params Params) {
for key, value := range params {
app.httpParams.Set(key, value)
}
}
// SetP12Cert 设置证书
func (app *App) SetP12Cert(content *tls.Certificate) {
app.p12Cert = content
}
// Get 发起GET请求
func (app *App) Get(uri ...string) (httpResponse Response, err error) {
if len(uri) == 1 {
app.Uri = uri[0]
}
// 设置请求方法
app.httpMethod = http.MethodGet
return request(app)
}
// Post 发起POST请求
func (app *App) Post(uri ...string) (httpResponse Response, err error) {
if len(uri) == 1 {
app.Uri = uri[0]
}
// 设置请求方法
app.httpMethod = http.MethodPost
return request(app)
}
// Request 发起请求
func (app *App) Request() (httpResponse Response, err error) {
return request(app)
}
// 请求接口
func request(app *App) (httpResponse Response, err error) {
// 赋值
httpResponse.RequestTime = gotime.Current().Time
httpResponse.RequestUri = app.httpUri
httpResponse.RequestMethod = app.httpMethod
httpResponse.RequestParams = app.httpParams.DeepCopy()
httpResponse.RequestHeader = app.httpHeader.DeepCopy()
// 判断网址
if httpResponse.RequestUri == "" {
httpResponse.RequestUri = app.Uri
}
if httpResponse.RequestUri == "" {
app.Error = errors.New("没有设置Uri")
return httpResponse, app.Error
}
// 创建 http 客户端
client := &http.Client{}
if app.p12Cert != nil {
transport := &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{*app.p12Cert},
},
DisableCompression: true,
}
client = &http.Client{
Transport: transport,
}
}
httpResponse.RequestHeader.Set("Sdk-User-Agent", fmt.Sprintf(userAgentFormat, runtime.GOOS, runtime.Version()))
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")
}
// 请求内容
var reqBody io.Reader
if httpResponse.RequestMethod == http.MethodPost && app.httpContentType == httpParamsModeJson {
jsonStr, err := json.Marshal(httpResponse.RequestParams)
if err != nil {
app.Error = errors.New(fmt.Sprintf("解析出错 %s", err))
return httpResponse, app.Error
}
// 赋值
reqBody = bytes.NewBuffer(jsonStr)
}
if httpResponse.RequestMethod == http.MethodPost && app.httpContentType == httpParamsModeForm {
// 携带 form 参数
form := url.Values{}
if len(httpResponse.RequestParams) > 0 {
for k, v := range httpResponse.RequestParams {
form.Add(k, GetParamsString(v))
}
}
// 赋值
reqBody = strings.NewReader(form.Encode())
}
if app.httpContentType == httpParamsModeXml {
reqBody, err = httpResponse.RequestParams.MarshalXML()
if err != nil {
app.Error = errors.New(fmt.Sprintf("解析XML出错 %s", err))
return httpResponse, app.Error
}
}
// 创建请求
req, err := http.NewRequest(httpResponse.RequestMethod, httpResponse.RequestUri, reqBody)
if err != nil {
app.Error = errors.New(fmt.Sprintf("创建请求出错 %s", err))
return httpResponse, app.Error
}
// GET 请求携带查询参数
if httpResponse.RequestMethod == http.MethodGet {
if len(httpResponse.RequestParams) > 0 {
q := req.URL.Query()
for k, v := range httpResponse.RequestParams {
q.Add(k, GetParamsString(v))
}
req.URL.RawQuery = q.Encode()
}
}
// 设置请求头
if len(httpResponse.RequestHeader) > 0 {
for key, value := range httpResponse.RequestHeader {
req.Header.Set(key, value)
}
}
// 发送请求
resp, err := client.Do(req)
if err != nil {
app.Error = errors.New(fmt.Sprintf("请求出错 %s", err))
return httpResponse, app.Error
}
// 最后关闭连接
defer resp.Body.Close()
// 读取内容
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
app.Error = errors.New(fmt.Sprintf("解析内容出错 %s", err))
return httpResponse, app.Error
}
// 赋值
httpResponse.ResponseTime = gotime.Current().Time
httpResponse.ResponseStatus = resp.Status
httpResponse.ResponseStatusCode = resp.StatusCode
httpResponse.ResponseHeader = resp.Header
httpResponse.ResponseBody = body
httpResponse.ResponseContentLength = resp.ContentLength
if app.debug == true {
fmt.Printf("gorequest%+v\n", httpResponse)
fmt.Printf("gorequest.body%s\n", httpResponse.ResponseBody)
}
return httpResponse, err
}

@ -0,0 +1,46 @@
package gorequest
import (
"net"
"net/http"
"strings"
)
// ClientIp 尽最大努力实现获取客户端 IP 的算法。
// 解析 X-Real-IP 和 X-Forwarded-For 以便于反向代理nginx 或 haproxy可以正常工作。
func ClientIp(r *http.Request) string {
// 转发IP
xForwardedFor := r.Header.Get("X-Forwarded-For")
ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
if ip != "" {
return ip
}
// 真实Ip
ip = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
if ip != "" {
return ip
}
// HTTP客户端IP
httpClientIp := r.Header.Get("HTTP_CLIENT_IP")
ip = strings.TrimSpace(strings.Split(httpClientIp, ",")[0])
if ip != "" {
return ip
}
// HTTP转发IP
HttpXForwardedFor := r.Header.Get("HTTP_X_FORWARDED_FOR")
ip = strings.TrimSpace(strings.Split(HttpXForwardedFor, ",")[0])
if ip != "" {
return ip
}
// 系统
if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil {
return ip
}
return ""
}

@ -0,0 +1,68 @@
package gorequest
import (
"encoding/json"
"go.dtapp.net/gostring"
"log"
)
// Params 参数
type Params map[string]interface{}
// NewParams 新建参数
func NewParams() Params {
P := make(Params)
return P
}
// NewParamsWith 参数使用
func NewParamsWith(params ...Params) Params {
p := make(Params)
for _, v := range params {
p.SetParams(v)
}
return p
}
// Set 设置参数
func (p Params) Set(key string, value interface{}) {
p[key] = value
}
// SetParams 批量设置参数
func (p Params) SetParams(params Params) {
for key, value := range params {
p[key] = value
}
}
// GetParamsString 获取参数字符串
func GetParamsString(src interface{}) string {
switch src.(type) {
case string:
return src.(string)
case int, int8, int32, int64:
case uint8, uint16, uint32, uint64:
case float32, float64:
return gostring.ToString(src)
}
data, err := json.Marshal(src)
if err != nil {
log.Fatal(err)
}
return string(data)
}
// DeepCopy 深度复制
func (p *Params) DeepCopy() map[string]interface{} {
targetMap := make(map[string]interface{})
// 从原始复制到目标
for key, value := range *p {
targetMap[key] = value
}
// 重新申请一个新的map
*p = map[string]interface{}{}
return targetMap
}

@ -0,0 +1,70 @@
package gorequest
import (
"net/url"
"strings"
)
// ResponseUrlParse 返回参数
type ResponseUrlParse struct {
Uri string `json:"uri"` // URI
Urn string `json:"urn"` // URN
Url string `json:"url"` // URL
Scheme string `json:"scheme"` // 协议
Host string `json:"host"` // 主机
Hostname string `json:"hostname"` // 主机名
Port string `json:"port"` // 端口
Path string `json:"path"` // 路径
RawQuery string `json:"raw_query"` // 参数 ?
Fragment string `json:"fragment"` // 片段 #
}
// UriParse 解析URl
func UriParse(input string) (resp ResponseUrlParse) {
parse, err := url.Parse(input)
if err != nil {
return
}
resp.Uri = input
resp.Urn = parse.Host + parse.Path
resp.Url = parse.Scheme + "://" + parse.Host + parse.Path
resp.Scheme = parse.Scheme
resp.Host = parse.Host
resp.Hostname = parse.Hostname()
resp.Port = parse.Port()
resp.Path = parse.Path
resp.RawQuery = parse.RawQuery
resp.Fragment = parse.Fragment
return
}
// UriFilterExcludeQueryString 过滤掉url中的参数
func UriFilterExcludeQueryString(uri string) string {
URL, _ := url.Parse(uri)
clearUri := strings.ReplaceAll(uri, URL.RawQuery, "")
clearUri = strings.TrimRight(clearUri, "?")
return strings.TrimRight(clearUri, "/")
}
// LenCode 编码
func LenCode(s string) string {
escape := url.QueryEscape(s)
return escape
}
// DeCode 解码
func DeCode(s string) string {
unescape, _ := url.QueryUnescape(s)
return unescape
}
// ParseQuery 获取URL参数 https://studygolang.com/articles/2876
func ParseQuery(s string) map[string][]string {
u, err := url.Parse(s)
if err != nil {
return nil
}
urlParam := u.RawQuery
m, _ := url.ParseQuery(urlParam)
return m
}

@ -0,0 +1,73 @@
package gorequest
import (
"fmt"
"math/rand"
"runtime"
"time"
)
// GetRandomUserAgent 获取随机UA
func GetRandomUserAgent() string {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
return userAgentList[r.Intn(len(userAgentList))]
}
var userAgentList = []string{
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36", // Chrome 2022-02-14
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0", // Firefox 2022-02-14
"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko", // IE 2022-02-14
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36 HeyTapBrowser/40.7.35.1", // Chrome 2022-02-14
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 OnePlusBrowser/30.5.0.8", // Chrome 2022-02-14
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9a1) Gecko/20060814 Firefox/51.0", // Firefox 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15", // Safari 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15", // Safari 2022-04-18
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36 Edg/98.0.1108.51", // Edge 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44", // Chrome 2022-04-18
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36", // Chrome 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36", // Chrome 2022-04-18
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0", // Firefox 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:99.0) Gecko/20100101 Firefox/99.0", // Firefox 2022-04-18
}
// GetRandomUserAgentSystem 获取系统随机UA
func GetRandomUserAgentSystem() string {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
switch runtime.GOOS {
case "linux":
return userAgentListLinux[r.Intn(len(userAgentListLinux))]
case "windows":
return userAgentListWindows[r.Intn(len(userAgentListWindows))]
default:
return userAgentListMac[r.Intn(len(userAgentListMac))]
}
}
var userAgentListWindows = []string{
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36", // Chrome 2022-02-14
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0", // Firefox 2022-02-14
"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko", // IE 2022-02-14
}
var userAgentListLinux = []string{
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36 HeyTapBrowser/40.7.35.1", // Chrome 2022-02-14
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 OnePlusBrowser/30.5.0.8", // Chrome 2022-02-14
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9a1) Gecko/20060814 Firefox/51.0", // Firefox 2022-02-14
}
var userAgentListMac = []string{
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15", // Safari 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15", // Safari 2022-04-18
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36 Edg/98.0.1108.51", // Edge 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44", // Chrome 2022-04-18
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36", // Chrome 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36", // Chrome 2022-04-18
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0", // Firefox 2022-02-14
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:99.0) Gecko/20100101 Firefox/99.0", // Firefox 2022-04-18
}
func DtaUa() string {
str := runtime.Version()
content := str[2 : len(str)-0]
return fmt.Sprintf("Go-dta-request/%v", content)
}

@ -0,0 +1,47 @@
package gorequest
import (
"bytes"
"encoding/xml"
"fmt"
"io"
)
// MarshalXML 结构体转xml
func (p Params) MarshalXML() (reader io.Reader, err error) {
buffer := bytes.NewBuffer(make([]byte, 0))
if _, err = io.WriteString(buffer, "<xml>"); err != nil {
return
}
for k, v := range p {
switch {
case k == "detail":
if _, err = io.WriteString(buffer, "<detail><![CDATA["); err != nil {
return
}
if _, err = io.WriteString(buffer, fmt.Sprintf("%v", v)); err != nil {
return
}
if _, err = io.WriteString(buffer, "]]></detail>"); err != nil {
return
}
default:
if _, err = io.WriteString(buffer, "<"+k+">"); err != nil {
return
}
if err = xml.EscapeText(buffer, []byte(fmt.Sprintf("%v", v))); err != nil {
return
}
if _, err = io.WriteString(buffer, "</"+k+">"); err != nil {
return
}
}
}
if _, err = io.WriteString(buffer, "</xml>"); err != nil {
return
}
return buffer, nil
}
Loading…
Cancel
Save