Compare commits

...

61 Commits

Author SHA1 Message Date
dtapps 930757d4ba - update vendor
1 month ago
dtapps 4e5e283452 - update ua
1 month ago
dtapps b7bd629099 - add vendor
2 months ago
dtapps 6e875ca329 - update
2 months ago
dtapps 6e2dd699ff - update
2 months ago
dtapps b7c59eeabe - update
2 months ago
dtapps 82bbdc22d3 - update `http`
4 months ago
dtapps 235c59150f - update `is`
4 months ago
dtapps 754b5c0b2b - update `is`
4 months ago
dtapps df7b50a63a - update version
4 months ago
dtapps ad80d76806 - update ua
5 months ago
dtapps adb44efa4a - update ua
5 months ago
dtapps a37b40e400 - update
5 months ago
dtapps 295ba66e98 - 增加 `ip` 方法
5 months ago
dtapps 1e0bfa1027 update
5 months ago
dtapps 9c3c444997 update
5 months ago
李光春 a17d560d7d - update
1 year ago
李光春 ad0965336d - update
1 year ago
李光春 3270d719a4 - update
1 year ago
李光春 f29f4585db - update
2 years ago
李光春 08e4aec244 - update
2 years ago
李光春 672f58c1f1 - update ua
2 years ago
李光春 c537a026c8 - update ua
2 years ago
李光春 a5dec87d88 - update user_agent
2 years ago
李光春 57494caea7 - update userAgentFormat
2 years ago
李光春 e030ebb553 - update userAgentFormat
2 years ago
李光春 f4f8a0fd31 - update vendor
2 years ago
李光春 96d8e4d1fd - add url
2 years ago
李光春 cbf953049e - add header.type
2 years ago
李光春 f1590dfdcb - update ctx
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details
2 years ago
李光春 cd4feb9864 - update
continuous-integration/drone/push Build is failing Details
2 years ago
李光春 bf6ddfa970 - update
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details
2 years ago
李光春 c29fa9c0bb - update
continuous-integration/drone/push Build is failing Details
2 years ago
李光春 d2b64554fc - add context
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details
2 years ago
李光春 c423c38c2e - update ip
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 2dc3acfcc2 - update
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 e4ff609f99 - update
2 years ago
李光春 83b89ed0c6 - update
2 years ago
李光春 4cf6724421 - update
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 21362ffcb4 - update url
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 1b52cc3467 update
continuous-integration/drone/push Build is passing Details
2 years ago
李光春 d0e213b417 update header
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 c7d8b79c28 update
continuous-integration/drone/push Build is failing Details
2 years ago
李光春 049e76402b update
continuous-integration/drone/push Build is failing Details
2 years ago
李光春 cecf41595c update
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details
2 years ago
李光春 55fabac5cc update
2 years ago
李光春 e1ccdce4d4 update
continuous-integration/drone/push Build is passing Details
2 years ago
李光春 2bea297a16 update
2 years ago
李光春 af1042d743 update headers
2 years ago
李光春 77f5d6f430 update params
2 years ago
李光春 c0d41d3d81 update params
2 years ago
李光春 856939f68c update params
2 years ago
李光春 6fd594b366 update params
2 years ago
李光春 b7d40443d4 update
2 years ago
李光春 be01fcc7d3 update
2 years ago
李光春 af5cd686ff update url
2 years ago
李光春 c4331869fa add http p12Cert
2 years ago
李光春 492cd3b737 update http
2 years ago
李光春 db9dbded65 update url parse
2 years ago
李光春 8da9001d8f update url parse
2 years ago
李光春 9dd267c12f add xml
2 years ago

@ -0,0 +1,17 @@
kind: pipeline
type: docker
name: clone
steps:
- name: Test
image: golang:1.18
commands:
- go env -w GO111MODULE=on
- go env -w GOPROXY=https://goproxy.cn,direct
- go test -v ./...
- name: Benchmark
image: golang:1.18
commands:
- go env -w GO111MODULE=on
- go env -w GOPROXY=https://goproxy.cn,direct
- go test -bench=. -benchmem

5
.gitignore vendored

@ -4,5 +4,6 @@
.idea
.vscode
*.log
gitmod.sh
*_test.go
*_test.go
go_mod.sh
#/vendor/

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2018 茂名聚合科技有限公司
Copyright (c) 2018 李光春
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

@ -1,25 +1,17 @@
<h1>
<a href="https://www.dtapp.net/">Golang Request</a>
<a href="https://www.dtapp.net/">Golang</a>
</h1>
📦 Golang 请求组件
📦 Golang 请求
[comment]: <> (go)
[![godoc](https://pkg.go.dev/badge/github.com/dtapps/gorequest?status.svg)](https://pkg.go.dev/github.com/dtapps/gorequest)
[![goproxy.cn](https://goproxy.cn/stats/github.com/dtapps/gorequest/badges/download-count.svg)](https://goproxy.cn/stats/github.com/dtapps/gorequest)
[![goreportcard.com](https://goreportcard.com/badge/github.com/dtapps/gorequest)](https://goreportcard.com/report/github.com/dtapps/gorequest)
[![deps.dev](https://img.shields.io/badge/deps-go-red.svg)](https://deps.dev/go/github.com%2Fdtapps%2Fgorequest)
[![godoc](https://pkg.go.dev/badge/go.dtapp.net/gorequest?status.svg)](https://pkg.go.dev/go.dtapp.net/gorequest)
[![goproxy.cn](https://goproxy.cn/stats/go.dtapp.net/gorequest/badges/download-count.svg)](https://goproxy.cn/stats/go.dtapp.net/gorequest)
[![goreportcard.com](https://goreportcard.com/badge/go.dtapp.net/gorequest)](https://goreportcard.com/report/go.dtapp.net/gorequest)
[![deps.dev](https://img.shields.io/badge/deps-go-red.svg)](https://deps.dev/go/go.dtapp.net%2Fgorequest)
#### 安装使用
#### 安装
```go
go get -v -u github.com/dtapps/gorequest
```shell
go get -v -u go.dtapp.net/gorequest@v1.0.49
```
#### 导入
```go
import (
"github.com/dtapps/gorequest"
)
```

@ -0,0 +1,20 @@
package gorequest
import (
"go.dtapp.net/gojson"
"go.dtapp.net/gostring"
)
// 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, _ := gojson.Marshal(src)
return string(data)
}

@ -0,0 +1,8 @@
package gorequest
// 定义请求类型
var (
httpParamsModeJson = "JSON"
httpParamsModeXml = "XML"
httpParamsModeForm = "FORM"
)

@ -1,8 +1,44 @@
module github.com/dtapps/gorequest
module go.dtapp.net/gorequest
go 1.18
go 1.22
require (
github.com/dtapps/gostring v1.0.1
github.com/dtapps/gotime v1.0.0
github.com/MercuryEngineering/CookieMonster v0.0.0-20180304172713-1584578b3403
go.dtapp.net/gojson v1.0.4
go.dtapp.net/gostring v1.0.14
go.dtapp.net/gotime v1.0.8
go.dtapp.net/gotrace_id v1.0.12
)
require (
github.com/basgys/goxml2json v1.1.0 // indirect
github.com/bytedance/sonic v1.11.3 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.9.1 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.19.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
go.dtapp.net/gorandom v1.0.3 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

116
go.sum

@ -1,4 +1,112 @@
github.com/dtapps/gostring v1.0.1 h1:J04kndQ08LOqb+H41s8PbMEgNtpheV9iTTl7DSPIZVk=
github.com/dtapps/gostring v1.0.1/go.mod h1:BYYnZHrmwpFXkLpd9rQyV5YcChovVreacfcjyMKEwoU=
github.com/dtapps/gotime v1.0.0 h1:VqmkEeKZOJMF7BePotcVvcCJgsIc9TB+OJlysxpDoBk=
github.com/dtapps/gotime v1.0.0/go.mod h1:lbp8pG/8aV3O+t7IuAjasL2WLBsZqLZG6Uw6KqSnox8=
github.com/MercuryEngineering/CookieMonster v0.0.0-20180304172713-1584578b3403 h1:EtZwYyLbkEcIt+B//6sujwRCnHuTEK3qiSypAX5aJeM=
github.com/MercuryEngineering/CookieMonster v0.0.0-20180304172713-1584578b3403/go.mod h1:mM6WvakkX2m+NgMiPCfFFjwfH4KzENC07zeGEqq9U7s=
github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUKVw=
github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw=
github.com/bitly/go-simplejson v0.5.1 h1:xgwPbetQScXt1gh9BmoJ6j9JMr3TElvuIyjR8pgdoow=
github.com/bitly/go-simplejson v0.5.1/go.mod h1:YOPVLzCfwK14b4Sff3oP1AmGhI9T9Vsg84etUnlyp+Q=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
github.com/bytedance/sonic v1.11.3 h1:jRN+yEjakWh8aK5FzrciUHG8OFXK+4/KrAX/ysEtHAA=
github.com/bytedance/sonic v1.11.3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo=
github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
go.dtapp.net/gojson v1.0.4 h1:9en9iyOOLWoEIo2eKhqt3/Djh/3HhwsTpXxgI9efPRo=
go.dtapp.net/gojson v1.0.4/go.mod h1:G9CMVzNSRkbNzIic/vJqHCOyKtw6BW2YM8Vyn64zfM0=
go.dtapp.net/gorandom v1.0.3 h1:6RNDFMJfLlHFR98c2tbecaMzg4vEIHyEpduMBUdd0jc=
go.dtapp.net/gorandom v1.0.3/go.mod h1:Qd6ywCSrk7sCkh9OdR0wygcbQBFt53WDIrx8rqGBvis=
go.dtapp.net/gostring v1.0.14 h1:N/2d0F6uUlLB2Co6pEAEyVvhHtoNutG5/J9XLsk6lFs=
go.dtapp.net/gostring v1.0.14/go.mod h1:vYgxkyKONIIeUpPkcMCK+1p66AcIe4xeSysSU2R6ysA=
go.dtapp.net/gotime v1.0.8 h1:ngKBp7j3Ime1t2jU94gUeshPX1StV5E2x4STlzDMmLU=
go.dtapp.net/gotime v1.0.8/go.mod h1:BQT911XSfaJDBYPiEKGFwMjvgnZtx1F3nWu4GTg5ISY=
go.dtapp.net/gotrace_id v1.0.12 h1:rUN5RrxGh4rEH87Lfv3Klx+ulZfuv5SYyX7j12Mj8ns=
go.dtapp.net/gotrace_id v1.0.12/go.mod h1:brcZxFisvGdeXrHJ9IDJwpDITi4m5Z9sDd9OvGdQHAo=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

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

@ -0,0 +1,65 @@
package gorequest
// HeaderIsImg 判断是否为图片
func (r *Response) HeaderIsImg() bool {
if r.ResponseHeader.Get("Content-Type") == "image/jpeg" || r.ResponseHeader.Get("Content-Type") == "image/png" || r.ResponseHeader.Get("Content-Type") == "image/jpg" {
return true
}
return false
}
// HeaderIsJpeg 判断是否为jpeg图片
func (r *Response) HeaderIsJpeg() bool {
if r.ResponseHeader.Get("Content-Type") == "image/jpeg" {
return true
}
return false
}
// HeaderIsPng 判断是否为Png图片
func (r *Response) HeaderIsPng() bool {
if r.ResponseHeader.Get("Content-Type") == "image/png" {
return true
}
return false
}
// HeaderIsJpg 判断是否为Jpg图片
func (r *Response) HeaderIsJpg() bool {
if r.ResponseHeader.Get("Content-Type") == "image/jpg" {
return true
}
return false
}
// HeaderJson 判断是否为Json数据
func (r *Response) HeaderJson() bool {
if r.ResponseHeader.Get("Content-Type") == "application/json" {
return true
}
return false
}
// HeaderHtml 判断是否为Html
func (r *Response) HeaderHtml() bool {
if r.ResponseHeader.Get("Content-Type") == "text/html" || r.ResponseHeader.Get("Content-Type") == "application/xhtml+xml" {
return true
}
return false
}
// HeaderTextHtml 判断是否为Html
func (r *Response) HeaderTextHtml() bool {
if r.ResponseHeader.Get("Content-Type") == "text/html" {
return true
}
return false
}
// HeaderXHtml 判断是否为Html
func (r *Response) HeaderXHtml() bool {
if r.ResponseHeader.Get("Content-Type") == "application/xhtml+xml" {
return true
}
return false
}

@ -2,26 +2,32 @@ package gorequest
import (
"bytes"
"encoding/json"
"compress/flate"
"compress/gzip"
"context"
"crypto/tls"
"errors"
"fmt"
"github.com/dtapps/gotime"
cookiemonster "github.com/MercuryEngineering/CookieMonster"
"go.dtapp.net/gojson"
"go.dtapp.net/gotime"
"go.dtapp.net/gotrace_id"
"io"
"io/ioutil"
"log"
"net/http"
"net/url"
"strings"
"time"
)
const Version = "1.0.7"
// Response 返回内容
type Response struct {
RequestUrl string //【请求】链接
RequestId string //【请求】编号
RequestUri string //【请求】链接
RequestParams Params //【请求】参数
RequestMethod string //【请求】方式
RequestHeader Headers //【请求】头部
RequestCookie string //【请求】Cookie
RequestTime time.Time //【请求】时间
ResponseHeader http.Header //【返回】头部
ResponseStatus string //【返回】状态
@ -31,45 +37,52 @@ type Response struct {
ResponseTime time.Time //【返回】时间
}
// App 实例
type App struct {
Url string // 全局请求地址没有设置url才会使用
httpUrl string // 请求地址
httpMethod string // 请求方法
httpHeader Headers // 请求头
httpParams Params // 请求参数
responseContent Response // 返回内容
httpContentType string // 请求内容类型
Error error // 错误
}
var (
httpParamsModeJson = "JSON"
httpParamsModeForm = "FORM"
)
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版本
}
// NewHttp 实例化
func NewHttp() *App {
return &App{
app := &App{
httpHeader: NewHeaders(),
httpParams: NewParams(),
}
return app
}
// SetDebug 设置调试模式
func (app *App) SetDebug() {
app.debug = true
}
// SetUrl 设置请求地址
func (app *App) SetUrl(url string) {
app.httpUrl = url
// SetUri 设置请求地址
func (app *App) SetUri(uri string) {
if uri != "" {
app.httpUri = uri
}
}
// SetMethod 设置请求方式
func (app *App) SetMethod(method string) {
app.httpMethod = method
if method != "" {
app.httpMethod = method
}
}
// SetHeader 设置请求头
func (app *App) SetHeader(key, value string) {
if key == "" {
panic("url is empty")
}
app.httpHeader.Set(key, value)
}
@ -80,17 +93,24 @@ func (app *App) SetHeaders(headers Headers) {
}
}
// SetTlsVersion 设置TLS版本
func (app *App) SetTlsVersion(minVersion, maxVersion uint16) {
app.tlsMinVersion = minVersion
app.tlsMaxVersion = maxVersion
}
// SetAuthToken 设置身份验证令牌
func (app *App) SetAuthToken(token string) {
app.httpHeader.Set("Authorization", fmt.Sprintf("Bearer %s", token))
if token != "" {
app.httpHeader.Set("Authorization", fmt.Sprintf("Bearer %s", token))
}
}
// SetUserAgent 设置用户代理,空字符串就随机设置
// SetUserAgent 设置用户代理,空字符串就随机设置
func (app *App) SetUserAgent(ua string) {
if ua == "" {
ua = GetRandomUserAgent()
if ua != "" {
app.httpHeader.Set("User-Agent", ua)
}
app.httpHeader.Set("User-Agent", ua)
}
// SetContentTypeJson 设置JSON格式
@ -103,11 +123,13 @@ 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)
}
@ -118,112 +140,228 @@ func (app *App) SetParams(params Params) {
}
}
// SetCookie 设置Cookie
func (app *App) SetCookie(cookie string) {
if cookie != "" {
app.httpCookie = cookie
}
}
// SetP12Cert 设置证书
func (app *App) SetP12Cert(content *tls.Certificate) {
app.p12Cert = content
}
// Get 发起GET请求
func (app *App) Get() (httpResponse Response, err error) {
func (app *App) Get(ctx context.Context, uri ...string) (httpResponse Response, err error) {
if len(uri) == 1 {
app.Uri = uri[0]
}
// 设置请求方法
app.httpMethod = http.MethodGet
return request(app)
return request(app, ctx)
}
// Post 发起POST请求
func (app *App) Post() (httpResponse Response, err error) {
func (app *App) Post(ctx context.Context, uri ...string) (httpResponse Response, err error) {
if len(uri) == 1 {
app.Uri = uri[0]
}
// 设置请求方法
app.httpMethod = http.MethodPost
return request(app)
return request(app, ctx)
}
// Request 发起请求
func (app *App) Request() (httpResponse Response, err error) {
return request(app)
func (app *App) Request(ctx context.Context) (httpResponse Response, err error) {
return request(app, ctx)
}
// 请求
func request(app *App) (httpResponse Response, err error) {
// 请求接口
func request(app *App, ctx context.Context) (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()
httpResponse.RequestCookie = app.httpCookie
// 判断网址
if app.httpUrl == "" {
app.httpUrl = app.Url
if httpResponse.RequestUri == "" {
httpResponse.RequestUri = app.Uri
}
if app.httpUrl == "" {
return httpResponse, errors.New("没有设置Url")
if httpResponse.RequestUri == "" {
app.Error = errors.New("没有设置Uri")
if app.debug {
log.Printf("{%s}------------------------\n", gotrace_id.GetTraceIdContext(ctx))
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
}
// 创建 http 客户端
client := &http.Client{}
// 赋值
httpResponse.RequestUrl = app.httpUrl
httpResponse.RequestMethod = app.httpMethod
httpResponse.RequestParams = app.httpParams
transportStatus := false
transport := &http.Transport{}
transportTls := &tls.Config{}
if app.p12Cert != nil {
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,
}
}
// 请求类型
if app.httpContentType == "" {
app.httpContentType = httpParamsModeJson
}
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")
}
// 跟踪编号
httpResponse.RequestId = gotrace_id.GetTraceIdContext(ctx)
if httpResponse.RequestId != "" {
httpResponse.RequestHeader.Set("X-Request-Id", httpResponse.RequestId)
}
// 请求内容
var reqBody io.Reader
if app.httpMethod == http.MethodPost && app.httpContentType == httpParamsModeJson {
app.httpHeader.Set("Content-Type", "application/json")
jsonStr, err := json.Marshal(app.httpParams)
if httpResponse.RequestMethod == http.MethodPost && app.httpContentType == httpParamsModeJson {
jsonStr, err := gojson.Marshal(httpResponse.RequestParams)
if err != nil {
return httpResponse, errors.New(fmt.Sprintf("解析出错 %s", err))
app.Error = errors.New(fmt.Sprintf("解析出错 %s", err))
if app.debug {
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
}
// 赋值
reqBody = bytes.NewBuffer(jsonStr)
}
if app.httpMethod == http.MethodPost && app.httpContentType == httpParamsModeForm {
if httpResponse.RequestMethod == http.MethodPost && app.httpContentType == httpParamsModeForm {
// 携带 form 参数
form := url.Values{}
app.httpHeader.Set("Content-Type", "application/x-www-form-urlencoded")
if len(app.httpParams) > 0 {
for k, v := range app.httpParams {
form.Add(k, GetParamsString(v))
}
for k, v := range httpResponse.RequestParams {
form.Add(k, GetParamsString(v))
}
// 赋值
reqBody = strings.NewReader(form.Encode())
}
if app.httpContentType == httpParamsModeXml {
reqBody, err = ToXml(httpResponse.RequestParams)
if err != nil {
app.Error = errors.New(fmt.Sprintf("解析XML出错 %s", err))
if app.debug {
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
}
}
// 创建请求
req, err := http.NewRequest(app.httpMethod, app.httpUrl, reqBody)
req, err := http.NewRequest(httpResponse.RequestMethod, httpResponse.RequestUri, reqBody)
if err != nil {
return httpResponse, errors.New(fmt.Sprintf("创建请求出错 %s", err))
app.Error = errors.New(fmt.Sprintf("创建请求出错 %s", err))
if app.debug {
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
}
// GET 请求携带查询参数
if app.httpMethod == http.MethodGet {
if len(app.httpParams) > 0 {
q := req.URL.Query()
for k, v := range app.httpParams {
q.Add(k, GetParamsString(v))
}
req.URL.RawQuery = q.Encode()
if httpResponse.RequestMethod == http.MethodGet {
q := req.URL.Query()
for k, v := range httpResponse.RequestParams {
q.Add(k, GetParamsString(v))
}
req.URL.RawQuery = q.Encode()
}
// 设置请求头
if len(app.httpHeader) > 0 {
for key, value := range app.httpHeader {
req.Header.Set(key, value)
if len(httpResponse.RequestHeader) > 0 {
for key, value := range httpResponse.RequestHeader {
req.Header.Set(key, fmt.Sprintf("%v", value))
}
}
// 赋值
httpResponse.RequestHeader = app.httpHeader
// 设置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)
}
}
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)
}
// 发送请求
resp, err := client.Do(req)
if err != nil {
return httpResponse, errors.New(fmt.Sprintf("请求出错 %s", err))
app.Error = errors.New(fmt.Sprintf("请求出错 %s", err))
if app.debug {
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
}
// 最后关闭连接
defer resp.Body.Close()
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
// 读取内容
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(reader)
if err != nil {
return httpResponse, errors.New(fmt.Sprintf("解析内容出错 %s", err))
app.Error = errors.New(fmt.Sprintf("解析内容出错 %s", err))
if app.debug {
log.Printf("{%s}请求异常:%v\n", httpResponse.RequestId, app.Error)
}
return httpResponse, app.Error
}
// 赋值
@ -234,5 +372,12 @@ func request(app *App) (httpResponse Response, err error) {
httpResponse.ResponseBody = body
httpResponse.ResponseContentLength = resp.ContentLength
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))
}
return httpResponse, err
}

@ -0,0 +1,49 @@
package gorequest
import (
"errors"
"net/http"
)
// IsWechatMiniProgramRequest 判断是否是微信小程序
func IsWechatMiniProgramRequest(r *http.Request, appid string) error {
referer := r.Referer()
userAgent := r.UserAgent()
if referer == "" {
return errors.New("网络请求没有达到要求")
}
return isWechatMiniProgramRequestReferer(userAgent, referer, appid)
}
// GinIsWechatMiniProgramRequest Gin框架 -> 判断是否是微信小程序
// https://gin-gonic.com/zh-cn/docs/
//func GinIsWechatMiniProgramRequest(ctx *gin.Context, appid string) error {
// referer := ctx.Request.Referer()
// userAgent := ctx.Request.UserAgent()
// if referer == "" {
// return errors.New("网络请求没有达到要求")
// }
// return isWechatMiniProgramRequestReferer(userAgent, referer, appid)
//}
// IrisIsWechatMiniProgramRequest Iris框架 -> 判断是否是微信小程序
// https://www.iris-go.com/docs/
//func IrisIsWechatMiniProgramRequest(ctx iris.Context, appid string) error {
// referer := ctx.Request().Referer()
// userAgent := ctx.Request().UserAgent()
// if referer == "" {
// return errors.New("网络请求没有达到要求")
// }
// return isWechatMiniProgramRequestReferer(userAgent, referer, appid)
//}
// EchoIsWechatMiniProgramRequest Echo框架 -> 判断是否是微信小程序
// https://echo.labstack.com/docs/
//func EchoIsWechatMiniProgramRequest(ctx echo.Context, appid string) error {
// referer := ctx.Request().Referer()
// userAgent := ctx.Request().UserAgent()
// if referer == "" {
// return errors.New("网络请求没有达到要求")
// }
// return isWechatMiniProgramRequestReferer(userAgent, referer, appid)
//}

@ -0,0 +1,33 @@
package gorequest
import (
"errors"
"strings"
)
// https://developers.weixin.qq.com/miniprogram/dev/framework/ability/network.html#%E4%BD%BF%E7%94%A8%E9%99%90%E5%88%B6
func isWechatMiniProgramRequestReferer(userAgent, referer string, appid string) error {
// 判断结尾
suffix := strings.HasSuffix(referer, "/page-frame.html")
if suffix {
// 判断开头
prefix := strings.HasPrefix(referer, "https://servicewechat.com/")
if prefix {
// 判断加上appid
prefixAppid := strings.HasPrefix(referer, "https://servicewechat.com/"+appid)
if prefixAppid {
return isWechatMiniProgramRequestUserAgent(userAgent)
}
return isWechatMiniProgramRequestUserAgent(userAgent)
}
return errors.New("格式固定不对2")
}
return errors.New("格式固定不对1")
}
func isWechatMiniProgramRequestUserAgent(userAgent string) error {
if strings.Contains(userAgent, "MicroMessenger") {
return nil
}
return errors.New("伪装数据")
}

126
ip.go

@ -1,6 +1,8 @@
package gorequest
import (
"context"
"go.dtapp.net/gojson"
"net"
"net/http"
"strings"
@ -10,37 +12,129 @@ import (
// 解析 X-Real-IP 和 X-Forwarded-For 以便于反向代理nginx 或 haproxy可以正常工作。
func ClientIp(r *http.Request) string {
// CloudFlare
CfConnectingIp := strings.TrimSpace(r.Header.Get("Cf-Connecting-Ip"))
if CfConnectingIp != "" {
return CfConnectingIp
}
// 转发IP
xForwardedFor := r.Header.Get("X-Forwarded-For")
ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
if ip != "" {
return ip
xForwardedFor := strings.TrimSpace(strings.Split(r.Header.Get("X-Forwarded-For"), ",")[0])
if xForwardedFor != "" {
return xForwardedFor
}
// 真实Ip
ip = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
if ip != "" {
return ip
XRealIp := strings.TrimSpace(r.Header.Get("X-Real-Ip"))
if XRealIp != "" {
return XRealIp
}
// HTTP客户端IP
httpClientIp := r.Header.Get("HTTP_CLIENT_IP")
ip = strings.TrimSpace(strings.Split(httpClientIp, ",")[0])
if ip != "" {
return ip
HttpClientIp := strings.TrimSpace(strings.Split(r.Header.Get("HTTP_CLIENT_IP"), ",")[0])
if HttpClientIp != "" {
return HttpClientIp
}
// HTTP转发IP
HttpXForwardedFor := r.Header.Get("HTTP_X_FORWARDED_FOR")
ip = strings.TrimSpace(strings.Split(HttpXForwardedFor, ",")[0])
if ip != "" {
return ip
HttpXForwardedFor := strings.TrimSpace(strings.Split(r.Header.Get("HTTP_X_FORWARDED_FOR"), ",")[0])
if HttpXForwardedFor != "" {
return HttpXForwardedFor
}
// 系统
if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil {
ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr))
if err == nil {
return ip
}
return ""
}
// GetInsideIp 内网ip
func GetInsideIp(ctx context.Context) string {
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
panic(err)
}
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP.String()
}
// Ips 获取全部网卡的全部IP
func Ips(ctx context.Context) (map[string]string, error) {
ips := make(map[string]string)
//返回 interface 结构体对象的列表,包含了全部网卡信息
interfaces, err := net.Interfaces()
if err != nil {
return nil, err
}
//遍历全部网卡
for _, i := range interfaces {
// Addrs() 方法返回一个网卡上全部的IP列表
address, err := i.Addrs()
if err != nil {
return nil, err
}
//遍历一个网卡上全部的IP列表组合为一个字符串放入对应网卡名称的map中
for _, v := range address {
ips[i.Name] += v.String() + " "
}
}
return ips, nil
}
// GetOutsideIp 外网ip
func GetOutsideIp(ctx context.Context) string {
// 返回结果
type respGetOutsideIp struct {
Data struct {
Ip string `json:"ip,omitempty"`
} `json:"data"`
}
// 请求
getHttp := NewHttp()
getHttp.SetUri("https://api.dtapp.net/ip")
getHttp.SetUserAgent(GetRandomUserAgentSystem())
response, err := getHttp.Get(ctx)
if err != nil {
return "0.0.0.0"
}
// 解析
var responseJson respGetOutsideIp
err = gojson.Unmarshal(response.ResponseBody, &responseJson)
if err != nil {
return "0.0.0.0"
}
if responseJson.Data.Ip == "" {
responseJson.Data.Ip = "0.0.0.0"
}
return responseJson.Data.Ip
}
// GetMacAddr 获取Mac地址
func GetMacAddr(ctx context.Context) (arrays []string) {
netInterfaces, err := net.Interfaces()
if err != nil {
return arrays
}
for _, netInterface := range netInterfaces {
addr := netInterface.HardwareAddr.String()
if len(addr) == 0 {
continue
}
arrays = append(arrays, addr)
}
return arrays
}

@ -1,40 +1,50 @@
package gorequest
import (
"encoding/json"
"github.com/dtapps/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
}
}
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)
// Get 获取参数
func (p Params) Get(key string) interface{} {
return p[key]
}
// DeepCopy 深度复制
func (p *Params) DeepCopy() map[string]interface{} {
targetMap := make(map[string]interface{})
// 从原始复制到目标
for key, value := range *p {
targetMap[key] = value
}
return string(data)
// 重新申请一个新的map
*p = map[string]interface{}{}
return targetMap
}

@ -2,10 +2,24 @@ package gorequest
import (
"net/url"
"strings"
)
type UriParse struct {
uri string
}
func NewUri(uri string) *UriParse {
return &UriParse{uri: uri}
}
// 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"` // 路径
@ -13,13 +27,17 @@ type ResponseUrlParse struct {
Fragment string `json:"fragment"` // 片段 #
}
// UrlParse 解析URl
func UrlParse(inputUrl string) (resp ResponseUrlParse) {
parse, err := url.Parse(inputUrl)
// Parse 解析URl
func (u *UriParse) Parse() (resp ResponseUrlParse) {
parse, err := url.Parse(u.uri)
if err != nil {
return
}
resp.Uri = u.uri
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
@ -27,3 +45,34 @@ func UrlParse(inputUrl string) (resp ResponseUrlParse) {
resp.Fragment = parse.Fragment
return
}
// UriFilterExcludeQueryString 过滤掉url中的参数
func (u *UriParse) 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
}

@ -1,12 +1,17 @@
package gorequest
import (
"fmt"
"math/rand"
"runtime"
"time"
)
const (
linux = "linux"
windows = "windows"
mac = "mac"
)
// GetRandomUserAgent 获取随机UA
func GetRandomUserAgent() string {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
@ -14,60 +19,73 @@ func GetRandomUserAgent() string {
}
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
"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko", // IE浏览器 2023-12-30 http://api.dtapp.net/ip?ua=widows_ie
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", // Chrome浏览器 2023-12-30 http://api.dtapp.net/ip?ua=widows_chrome
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0", // Edge浏览器 2023-12-30 http://api.dtapp.net/ip?ua=widows_edge
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0", // Firefox浏览器 2023-12-30 http://api.dtapp.net/ip?ua=widows_firefox
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.218.400 QQBrowser/12.1.5496.400", // QQ浏览器 2023-12-30 http://api.dtapp.net/ip?ua=widows_qq
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/537.36", // 360浏览器 2023-12-30 http://api.dtapp.net/ip?ua=widows_360
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.160 Safari/537.36", // 360极速浏览器 2023-12-30 http://api.dtapp.net/ip?ua=widows_360js
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 SE 2.X MetaSr 1.0", // 搜狗浏览器 2023-12-30 http://api.dtapp.net/ip?ua=widows_sg
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", // Chrome 2023-03-22
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51", // Edge 2023-03-22
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0", // Firefox 2023-03-22
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3 Safari/605.1.15", // Safari浏览器 2023-12-30 https://api.dtapp.net/ip?ua=mac_safari
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", // Chrome浏览器 2023-12-30 https://api.dtapp.net/ip?ua=mac_chrome
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0", // Edge浏览器 2023-12-30 https://api.dtapp.net/ip?ua=mac_edge
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0", // Firefox浏览器 2023-12-30 http://api.dtapp.net/ip?ua=mac_firefox
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 QQBrowser/5.0.4.209", // QQ浏览器 2023-12-30 http://api.dtapp.net/ip?ua=mac_qq
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.95 Safari/537.36", // 360极速浏览器 2023-12-30 http://api.dtapp.net/ip?ua=mac_360js
}
// GetRandomUserAgentSystem 获取系统随机UA
func GetRandomUserAgentSystem() string {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
switch runtime.GOOS {
case "linux":
case linux:
return userAgentListLinux[r.Intn(len(userAgentListLinux))]
case "windows":
case windows:
return userAgentListWindows[r.Intn(len(userAgentListWindows))]
case mac:
return userAgentListMac[r.Intn(len(userAgentListMac))]
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
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", // Chrome浏览器 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0", // Edge浏览器 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0", // Firefox浏览器 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.236.400 QQBrowser/12.4.5604.400", // QQ浏览器 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/537.36", // 360安全浏览器 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36", // 360极速浏览器 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 SE 2.X MetaSr 1.0", // 搜狗浏览器 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36", // 360极速浏览器X 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/537.36", // 360Ai浏览器 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 OPR/109.0.0.0", // Opera浏览器 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36", // Cent浏览器 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", // 傲游浏览器 2024-04-12
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", // Vivaldi浏览器 2024-04-12
}
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
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", // Chrome 2023-03-22
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51", // Edge 2023-03-22
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0", // Firefox 2023-03-22
}
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/%s/%v", Version, content)
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3 Safari/605.1.15", // Safari浏览器 2024-04-12
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", // Chrome浏览器 2024-04-12
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0", // Edge浏览器 2024-04-12
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:124.0) Gecko/20100101 Firefox/124.0", // Firefox浏览器 2024-04-12
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 QQBrowser/5.0.4.211", // QQ浏览器 2024-04-12
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.95 Safari/537.36", // 360极速浏览器Pro 2024-04-12
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 OPR/109.0.0.0", // Opera浏览器 2024-04-12
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", // 傲游浏览器 2024-04-12
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", // Vivaldi浏览器 2024-04-12
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", // Arc浏览器 2024-04-12
}

@ -1,8 +0,0 @@
.env
.git
.svn
.idea
.vscode
*.log
gitmod.sh
*_test.go

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018 茂名聚合科技有限公司
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,25 +0,0 @@
<h1>
<a href="https://www.dtapp.net/">Golang String</a>
</h1>
📦 Golang 字符串组件
[comment]: <> (go)
[![godoc](https://pkg.go.dev/badge/github.com/dtapps/gostring?status.svg)](https://pkg.go.dev/github.com/dtapps/gostring)
[![goproxy.cn](https://goproxy.cn/stats/github.com/dtapps/gostring/badges/download-count.svg)](https://goproxy.cn/stats/github.com/dtapps/gostring)
[![goreportcard.com](https://goreportcard.com/badge/github.com/dtapps/gostring)](https://goreportcard.com/report/github.com/dtapps/gostring)
[![deps.dev](https://img.shields.io/badge/deps-go-red.svg)](https://deps.dev/go/github.com%2Fdtapps%2Fgostring)
#### 安装使用
```go
go get -v -u github.com/dtapps/gostring
```
#### 导入
```go
import (
"github.com/dtapps/gostring"
)
```

@ -1,151 +0,0 @@
package gostring
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"strconv"
"strings"
"unicode/utf8"
)
const Version = "1.0.1"
// ToString 转换成string
func ToString(value interface{}) string {
if value == nil {
return ""
}
return fmt.Sprint(value)
}
// ToFloat64 string到float64
func ToFloat64(s string) float64 {
i, _ := strconv.ParseFloat(s, 64)
return i
}
// ToInt string到int
func ToInt(s string) int {
i, _ := strconv.Atoi(s)
return i
}
// ToInt64 string到int64
func ToInt64(s string) int64 {
i, err := strconv.ParseInt(s, 10, 64)
if err == nil {
return i
}
return int64(ToFloat64(s))
}
// ToUint string到uint64
func ToUint(s string) uint {
i, err := strconv.ParseUint(s, 10, 64)
if err == nil {
return uint(i)
}
return 0
}
// ToUint64 string到uint64
func ToUint64(s string) uint64 {
i, err := strconv.ParseUint(s, 10, 64)
if err == nil {
return i
}
return 0
}
// Replace 字符串替换
func Replace(str, old, new string) string {
return strings.Replace(str, old, new, -1)
}
func HmacSha256Hex(key, strToSign string) string {
hasHer := hmac.New(sha256.New, []byte(key))
hasHer.Write([]byte(strToSign))
return hex.EncodeToString(hasHer.Sum(nil))
}
// Space 去除空格
func Space(str string) string {
return strings.Replace(str, " ", "", -1)
}
// LineBreak 去除换行符
func LineBreak(str string) string {
return strings.Replace(str, "\n", "", -1)
}
// SpaceAndLineBreak 去除空格和去除换行符
func SpaceAndLineBreak(str string) string {
return LineBreak(Space(str))
}
// TrimLastChar 删除字符串中的最后一个
func TrimLastChar(s string) string {
r, size := utf8.DecodeLastRuneInString(s)
if r == utf8.RuneError && (size == 0 || size == 1) {
size = 0
}
return s[:len(s)-size]
}
// Split 字符串分隔
func Split(s string, sep string) []string {
return strings.Split(s, sep)
}
// Contains 判断字符串是否包含某个字符
func Contains(s, substr string) bool {
return strings.Contains(s, substr)
}
func NumericalToString(value interface{}) (string, bool) {
var val string
switch value.(type) {
default:
return "0", false
case int:
intVal, _ := value.(int)
val = strconv.FormatInt(int64(intVal), 10)
case int8:
intVal, _ := value.(int8)
val = strconv.FormatInt(int64(intVal), 10)
case int16:
intVal, _ := value.(int16)
val = strconv.FormatInt(int64(intVal), 10)
case int32:
intVal, _ := value.(int32)
val = strconv.FormatInt(int64(intVal), 10)
case int64:
intVal, _ := value.(int64)
val = strconv.FormatInt(int64(intVal), 10)
case uint:
intVal, _ := value.(uint)
val = strconv.FormatUint(uint64(intVal), 10)
case uint8:
intVal, _ := value.(uint8)
val = strconv.FormatUint(uint64(intVal), 10)
case uint16:
intVal, _ := value.(uint16)
val = strconv.FormatUint(uint64(intVal), 10)
case uint32:
intVal, _ := value.(uint32)
val = strconv.FormatUint(uint64(intVal), 10)
case uint64:
intVal, _ := value.(uint64)
val = strconv.FormatUint(intVal, 10)
case float32:
floatVal, _ := value.(float32)
val = strconv.FormatFloat(float64(floatVal), 'f', -1, 32)
case float64:
floatVal, _ := value.(float64)
val = strconv.FormatFloat(floatVal, 'f', -1, 64)
}
return val, true
}

@ -1,6 +0,0 @@
.env
.git
.svn
.idea
.vscode
.log

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018 茂名聚合科技有限公司
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,25 +0,0 @@
<h1>
<a href="https://www.dtapp.net/">Golang Time</a>
</h1>
📦 Golang 时间组件
[comment]: <> (go)
[![godoc](https://pkg.go.dev/badge/github.com/dtapps/gotime?status.svg)](https://pkg.go.dev/github.com/dtapps/gotime)
[![goproxy.cn](https://goproxy.cn/stats/github.com/dtapps/gotime/badges/download-count.svg)](https://goproxy.cn/stats/github.com/dtapps/gotime)
[![goreportcard.com](https://goreportcard.com/badge/github.com/dtapps/gotime)](https://goreportcard.com/report/github.com/dtapps/gotime)
[![deps.dev](https://img.shields.io/badge/deps-go-red.svg)](https://deps.dev/go/github.com%2Fdtapps%2Fgotime)
#### 安装使用
```go
go get -v -u github.com/dtapps/gotime
```
#### 导入
```go
import (
"github.com/dtapps/gotime"
)
```

@ -1,15 +0,0 @@
package gotime
import "time"
// Tomorrow 明天
func Tomorrow() Pro {
p := NewPro()
location, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
p.Time = time.Now().Add(time.Hour*8).AddDate(0, 0, +1)
} else {
p.Time = time.Now().In(location).AddDate(0, 0, +1)
}
return p
}

@ -1,105 +0,0 @@
package gotime
import (
"fmt"
"time"
)
// 时间格式化常量
const (
RFC3339Format = time.RFC3339
Iso8601Format = "2006-01-02T15:04:05-07:00"
CookieFormat = "Monday, 02-Jan-2006 15:04:05 MST"
RFC1036Format = "Mon, 02 Jan 06 15:04:05 -0700"
RFC7231Format = "Mon, 02 Jan 2006 15:04:05 GMT"
DayDateTimeFormat = "Mon, Jan 2, 2006 3:04 PM"
DateTimeFormat = "2006-01-02 15:04:05"
DateFormat = "2006-01-02"
TimeFormat = "15:04:05"
ShortDateTimeFormat = "20060102150405"
ShortDateFormat = "20060102"
ShortTimeFormat = "150405"
)
// Pro 结构体
type Pro struct {
Time time.Time
loc *time.Location
Error error
}
// NewPro 初始化结构体
func NewPro() Pro {
return Pro{
Time: time.Now(),
}
}
// BeforeSeconds 获取n秒前的时间
func (p Pro) BeforeSeconds(seconds int) Pro {
st, _ := time.ParseDuration(fmt.Sprintf("-%ds", seconds))
p.Time = p.Time.Add(st)
return p
}
// AfterSeconds 获取n秒后的时间
func (p Pro) AfterSeconds(seconds int) Pro {
st, _ := time.ParseDuration(fmt.Sprintf("+%ds", seconds))
p.Time = p.Time.Add(st)
return p
}
// BeforeMinute 获取n分钟前的时间
func (p Pro) BeforeMinute(seconds int) Pro {
st, _ := time.ParseDuration(fmt.Sprintf("-%dm", seconds))
p.Time = p.Time.Add(st)
return p
}
// AfterMinute 获取n分钟后的时间
func (p Pro) AfterMinute(seconds int) Pro {
st, _ := time.ParseDuration(fmt.Sprintf("+%dm", seconds))
p.Time = p.Time.Add(st)
return p
}
// BeforeHour 获取n小时前的时间
func (p Pro) BeforeHour(hour int) Pro {
st, _ := time.ParseDuration(fmt.Sprintf("-%dh", hour))
p.Time = p.Time.Add(st)
return p
}
// AfterHour 获取n小时后的时间
func (p Pro) AfterHour(hour int) Pro {
st, _ := time.ParseDuration(fmt.Sprintf("+%dh", hour))
p.Time = p.Time.Add(st)
return p
}
// BeforeDay 获取n天前的时间
func (p Pro) BeforeDay(day int) Pro {
p.Time = p.Time.AddDate(0, 0, -day)
return p
}
// AfterDay 获取n天后的时间
func (p Pro) AfterDay(day int) Pro {
p.Time = p.Time.AddDate(0, 0, day)
return p
}
// SetFormat 格式化
func (p Pro) SetFormat(layout string) string {
return p.Time.Format(layout)
}
// Month 获取当前月
func (p Pro) Month() int {
return p.MonthOfYear()
}
// MonthOfYear 获取本年的第几月
func (p Pro) MonthOfYear() int {
return int(p.Time.In(p.loc).Month())
}

@ -1,65 +0,0 @@
package gotime
import "time"
// Gt 是否大于
func (p Pro) Gt(t2 time.Time) bool {
return p.Time.After(t2)
}
// Lt 是否小于
func (p Pro) Lt(t2 time.Time) bool {
return p.Time.Before(t2)
}
// Eq 是否等于
func (p Pro) Eq(t2 time.Time) bool {
return p.Time.Equal(t2)
}
// Ne 是否不等于
func (p Pro) Ne(t2 time.Time) bool {
return !p.Eq(t2)
}
// Gte 是否大于等于
func (p Pro) Gte(t2 time.Time) bool {
return p.Gt(t2) || p.Eq(t2)
}
// Lte 是否小于等于
func (p Pro) Lte(t2 time.Time) bool {
return p.Lt(t2) || p.Eq(t2)
}
// Between 是否在两个时间之间(不包括这两个时间)
func (p Pro) Between(start time.Time, end time.Time) bool {
if p.Gt(start) && p.Lt(end) {
return true
}
return false
}
// BetweenIncludedStart 是否在两个时间之间(包括开始时间)
func (p Pro) BetweenIncludedStart(start time.Time, end time.Time) bool {
if p.Gte(start) && p.Lt(end) {
return true
}
return false
}
// BetweenIncludedEnd 是否在两个时间之间(包括结束时间)
func (p Pro) BetweenIncludedEnd(start time.Time, end time.Time) bool {
if p.Gt(start) && p.Lte(end) {
return true
}
return false
}
// BetweenIncludedBoth 是否在两个时间之间(包括这两个时间)
func (p Pro) BetweenIncludedBoth(start time.Time, end time.Time) bool {
if p.Gte(start) && p.Lte(end) {
return true
}
return false
}

@ -1,69 +0,0 @@
package gotime
import "time"
// DiffInHour 相差多少小时
func (p Pro) DiffInHour(t2 time.Time) (hour int64) {
t2.Before(p.Time)
diff := p.Time.Unix() - t2.Unix()
hour = diff / 3600
return hour
}
// DiffInHourWithAbs 相差多少小时(绝对值)
func (p Pro) DiffInHourWithAbs(t2 time.Time) (hour int64) {
p.Time.Before(t2)
diff := t2.Unix() - p.Time.Unix()
hour = diff / 3600
if hour > 0 {
return hour
}
t2.Before(p.Time)
diff = p.Time.Unix() - t2.Unix()
hour = diff / 3600
return hour
}
// DiffInMinutes 相差多少分钟
func (p Pro) DiffInMinutes(t2 time.Time) (hour int64) {
t2.Before(p.Time)
diff := p.Time.Unix() - t2.Unix()
hour = diff / 60
return hour
}
// DiffInMinutesWithAbs 相差多少分钟(绝对值)
func (p Pro) DiffInMinutesWithAbs(t2 time.Time) (hour int64) {
p.Time.Before(t2)
diff := t2.Unix() - p.Time.Unix()
hour = diff / 60
if hour > 0 {
return hour
}
t2.Before(p.Time)
diff = p.Time.Unix() - t2.Unix()
hour = diff / 60
return hour
}
// DiffInSecond 相差多少秒
func (p Pro) DiffInSecond(t2 time.Time) (hour int64) {
t2.Before(p.Time)
diff := p.Time.Unix() - t2.Unix()
hour = diff
return hour
}
// DiffInSecondWithAbs 相差多少秒(绝对值)
func (p Pro) DiffInSecondWithAbs(t2 time.Time) (hour int64) {
p.Time.Before(t2)
diff := t2.Unix() - p.Time.Unix()
hour = diff
if hour > 0 {
return hour
}
t2.Before(p.Time)
diff = p.Time.Unix() - t2.Unix()
hour = diff
return hour
}

@ -1,8 +0,0 @@
package gotime
import "fmt"
// invalidTimezoneError 无效的时区错误
var invalidTimezoneError = func(timezone string) error {
return fmt.Errorf("invalid timezone %q, please see the file %q for all valid timezones", timezone, "$GOROOT/lib/time/zoneinfo.zip")
}

@ -1,14 +0,0 @@
package gotime
import (
"time"
)
// 通过时区获取 Location 实例
func getLocationByTimezone(timezone string) (*time.Location, error) {
loc, err := time.LoadLocation(timezone)
if err != nil {
err = invalidTimezoneError(timezone)
}
return loc, err
}

@ -1,124 +0,0 @@
package gotime
import "time"
// 数字常量
const (
YearsPerMillennium = 1000 // 每千年1000年
YearsPerCentury = 100 // 每世纪100年
YearsPerDecade = 10 // 每十年10年
QuartersPerYear = 4 // 每年4季度
MonthsPerYear = 12 // 每年12月
MonthsPerQuarter = 3 // 每季度3月
WeeksPerNormalYear = 52 // 每常规年52周
weeksPerLongYear = 53 // 每长年53周
WeeksPerMonth = 4 // 每月4周
DaysPerLeapYear = 366 // 每闰年366天
DaysPerNormalYear = 365 // 每常规年365天
DaysPerWeek = 7 // 每周7天
HoursPerWeek = 168 // 每周168小时
HoursPerDay = 24 // 每天24小时
MinutesPerDay = 1440 // 每天1440分钟
MinutesPerHour = 60 // 每小时60分钟
SecondsPerWeek = 604800 // 每周604800秒
SecondsPerDay = 86400 // 每天86400秒
SecondsPerHour = 3600 // 每小时3600秒
SecondsPerMinute = 60 // 每分钟60秒
MillisecondsPerSecond = 1000 // 每秒1000毫秒
MicrosecondsPerMillisecond = 1000 // 每毫秒1000微秒
MicrosecondsPerSecond = 1000000 // 每秒1000000微秒
)
// StartOfCentury 本世纪开始时间
func (p Pro) StartOfCentury() Pro {
p.Time = time.Date(p.Time.Year()/YearsPerCentury*YearsPerCentury, 1, 1, 0, 0, 0, 0, p.Time.Location())
return p
}
// EndOfCentury 本世纪结束时间
func (p Pro) EndOfCentury() Pro {
p.Time = time.Date(p.Time.Year()/YearsPerCentury*YearsPerCentury+99, 12, 31, 23, 59, 59, 999999999, p.Time.Location())
return p
}
// StartOfDecade 本年代开始时间
func (p Pro) StartOfDecade() Pro {
p.Time = time.Date(p.Time.Year()/YearsPerDecade*YearsPerDecade, 1, 1, 0, 0, 0, 0, p.Time.Location())
return p
}
// EndOfDecade 本年代结束时间
func (p Pro) EndOfDecade() Pro {
p.Time = time.Date(p.Time.Year()/YearsPerDecade*YearsPerDecade+9, 12, 31, 23, 59, 59, 999999999, p.Time.Location())
return p
}
// StartOfYear 本年开始时间
func (p Pro) StartOfYear() Pro {
p.Time = time.Date(p.Time.Year(), 1, 1, 0, 0, 0, 0, p.Time.Location())
return p
}
// EndOfYear 本年结束时间
func (p Pro) EndOfYear() Pro {
p.Time = time.Date(p.Time.Year(), 12, 31, 23, 59, 59, 999999999, p.Time.Location())
return p
}
// Quarter 获取当前季度
func (p Pro) Quarter() (quarter int) {
switch {
case p.Time.Month() >= 10:
quarter = 4
case p.Time.Month() >= 7:
quarter = 3
case p.Time.Month() >= 4:
quarter = 2
case p.Time.Month() >= 1:
quarter = 1
}
return
}
// StartOfQuarter 本季度开始时间
func (p Pro) StartOfQuarter() Pro {
p.Time = time.Date(p.Time.Year(), time.Month(3*p.Quarter()-2), 1, 0, 0, 0, 0, p.Time.Location())
return p
}
// EndOfQuarter 本季度结束时间
func (p Pro) EndOfQuarter() Pro {
quarter, day := p.Quarter(), 30
switch quarter {
case 1, 4:
day = 31
case 2, 3:
day = 30
}
p.Time = time.Date(p.Time.Year(), time.Month(3*quarter), day, 23, 59, 59, 999999999, p.Time.Location())
return p
}
// StartOfMonth 本月开始时间
func (p Pro) StartOfMonth() Pro {
p.Time = time.Date(p.Time.Year(), time.Month(p.Month()), 1, 0, 0, 0, 0, p.Time.Location())
return p
}
// EndOfMonth 本月结束时间
func (p Pro) EndOfMonth() Pro {
p.Time = time.Date(p.Time.Year(), time.Month(p.Month()), 1, 23, 59, 59, 999999999, p.Time.Location())
return p
}
// StartOfDay 本日开始时间
func (p Pro) StartOfDay() Pro {
p.Time = time.Date(p.Time.Year(), p.Time.Month(), p.Time.Day(), 0, 0, 0, 0, p.Time.Location())
return p
}
// EndOfDay 本日结束时间
func (p Pro) EndOfDay() Pro {
p.Time = time.Date(p.Time.Year(), p.Time.Month(), p.Time.Day(), 23, 59, 59, 0, p.Time.Location())
return p
}

@ -1,112 +0,0 @@
package gotime
import (
"log"
"strconv"
"strings"
"time"
)
// Current 获取当前的时间
func Current() Pro {
p := NewPro()
p.loc, p.Error = time.LoadLocation("Asia/Shanghai")
if p.Error != nil {
// Docker部署golang应用时时区问题 https://www.ddhigh.com/2018/03/01/golang-docker-timezone.html
log.Printf("【gotime】时区错误%v\n", p.Error)
p.Time = time.Now().Add(time.Hour * 8)
} else {
p.Time = time.Now().In(p.loc)
}
return p
}
// SetCurrent 设置当前的时间
func SetCurrent(sTime time.Time) Pro {
p := NewPro()
p.Time = sTime
return p
}
// SetCurrentParse 设置当前的时间
func SetCurrentParse(str string) Pro {
p := NewPro()
p.loc, p.Error = time.LoadLocation("Asia/Shanghai")
layout := DateTimeFormat
if str == "" || str == "0" || str == "0000-00-00 00:00:00" || str == "0000-00-00" || str == "00:00:00" {
return p
}
if len(str) == 10 && strings.Count(str, "-") == 2 {
layout = DateFormat
}
if strings.Index(str, "T") == 10 {
layout = RFC3339Format
}
if _, err := strconv.ParseInt(str, 10, 64); err == nil {
switch len(str) {
case 8:
layout = ShortDateFormat
case 14:
layout = ShortDateTimeFormat
}
}
location, _ := time.ParseInLocation(layout, str, p.loc)
p.Time = location
return p
}
// SetCurrentUnix 设置当前的时间 Unix时间戳
func SetCurrentUnix(ts int64) Pro {
p := NewPro()
p.Time = time.Unix(ts, 0)
return p
}
// Now 今天此刻
func (p Pro) Now() time.Time {
return p.Time
}
// Format 今天此刻格式化
func (p Pro) Format() string {
return p.Time.Format(DateTimeFormat)
}
// ToDateFormat 今天此刻日期
func (p Pro) ToDateFormat() string {
return p.Time.Format(DateFormat)
}
// ToTimeFormat 今天此刻时间
func (p Pro) ToTimeFormat() string {
return p.Time.Format(TimeFormat)
}
// Timestamp 今天此刻时间戳
func (p Pro) Timestamp() int64 {
return p.Time.Unix()
}
// TimestampWithSecond 今天此刻时间戳
func (p Pro) TimestampWithSecond() int64 {
return p.Time.Unix()
}
// TimestampWithMillisecond 今天毫秒级时间戳
func (p Pro) TimestampWithMillisecond() int64 {
return p.Time.UnixNano() / int64(time.Millisecond)
}
// TimestampWithMicrosecond 今天微秒级时间戳
func (p Pro) TimestampWithMicrosecond() int64 {
return p.Time.UnixNano() / int64(time.Microsecond)
}
// TimestampWithNanosecond 今天纳秒级时间戳
func (p Pro) TimestampWithNanosecond() int64 {
return p.Time.UnixNano()
}

@ -1,17 +0,0 @@
package gotime
import (
"time"
)
// Yesterday 昨天
func Yesterday() Pro {
p := NewPro()
location, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
p.Time = time.Now().Add(time.Hour*8).AddDate(0, 0, -1)
} else {
p.Time = time.Now().In(location).AddDate(0, 0, -1)
}
return p
}

@ -1,6 +0,0 @@
# github.com/dtapps/gostring v1.0.1
## explicit
github.com/dtapps/gostring
# github.com/dtapps/gotime v1.0.0
## explicit; go 1.18
github.com/dtapps/gotime

@ -0,0 +1,3 @@
package gorequest
const Version = "1.0.49"

@ -0,0 +1,46 @@
package gorequest
import (
"bytes"
"encoding/xml"
"fmt"
"io"
)
func ToXml(params map[string]interface{}) (reader io.Reader, err error) {
buffer := bytes.NewBuffer(make([]byte, 0))
if _, err = io.WriteString(buffer, "<xml>"); err != nil {
return
}
for k, v := range params {
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