first push
This commit is contained in:
commit
a11cc05a9d
|
@ -0,0 +1,25 @@
|
|||
## 安装
|
||||
|
||||
```bash
|
||||
$ go get -u gitea.cdlsxd.cn/rzy_tools/request/tags
|
||||
```
|
||||
|
||||
|
||||
## 正常使用
|
||||
```go
|
||||
req := request.Request{
|
||||
Method: "POST",
|
||||
Url: reqUrl,
|
||||
Json: RequestBody,
|
||||
Headers: header,
|
||||
}
|
||||
resp, _ := req.Send()
|
||||
```
|
||||
|
||||
## 同时大量请求或者在协程中使用建议使用
|
||||
|
||||
```go
|
||||
r := RequestPools.Get()
|
||||
defer RequestPools.ClearAndPut(r)
|
||||
...
|
||||
```
|
|
@ -0,0 +1,43 @@
|
|||
package l_request
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type RequestPool struct {
|
||||
pool sync.Pool
|
||||
}
|
||||
|
||||
var RequestPools = &RequestPool{
|
||||
pool: sync.Pool{
|
||||
New: func() interface{} {
|
||||
return new(Request)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func (re *RequestPool) Get() *Request {
|
||||
return re.pool.Get().(*Request)
|
||||
}
|
||||
|
||||
func (re *RequestPool) Put(r *Request) {
|
||||
re.pool.Put(r)
|
||||
}
|
||||
|
||||
func (re *RequestPool) Reset(r *Request) {
|
||||
r.Method = ""
|
||||
r.Url = ""
|
||||
r.Params = nil
|
||||
r.Headers = nil
|
||||
r.Cookies = nil
|
||||
r.Data = nil
|
||||
r.Json = nil
|
||||
r.Files = nil
|
||||
r.Raw = ""
|
||||
r.JsonByte = nil
|
||||
}
|
||||
|
||||
func (re *RequestPool) ClearAndPut(r *Request) {
|
||||
re.Reset(r)
|
||||
re.Put(r)
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package l_request
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestPool(t *testing.T) {
|
||||
r := RequestPools.Get()
|
||||
r.Url = "http://www.baidu.com"
|
||||
RequestPools.ClearAndPut(r)
|
||||
a := RequestPools.Get()
|
||||
t.Log(a.Url)
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
package l_request
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 请求结构体
|
||||
type Request struct {
|
||||
Method string `json:"method"` // 请求方法
|
||||
Url string `json:"url"` // 请求url
|
||||
Params map[string]string `json:"params"` // Query参数
|
||||
Headers map[string]string `json:"headers"` // 请求头
|
||||
Cookies map[string]string `json:"cookies"` // todo 处理 Cookies
|
||||
Data map[string]string `json:"data"` // 表单格式请求数据
|
||||
Json map[string]interface{} `json:"json"` // JSON格式请求数据 todo 多层 嵌套
|
||||
Files map[string]string `json:"files"` // todo 处理 Files
|
||||
Raw string `json:"raw"` // 原始请求数据
|
||||
JsonByte []byte `json:"json_raw"` // JSON格式请求数据 todo 多层 嵌套
|
||||
}
|
||||
|
||||
// 响应结构体
|
||||
type Response struct {
|
||||
StatusCode int `json:"status_code"` // 状态码
|
||||
Reason string `json:"reason"` // 状态码说明
|
||||
Elapsed float64 `json:"elapsed"` // 请求耗时(秒)
|
||||
Content []byte `json:"content"` // 响应二进制内容
|
||||
Text string `json:"text"` // 响应文本
|
||||
Headers map[string]string `json:"headers"` // 响应头
|
||||
Cookies map[string]string `json:"cookies"` // todo 添加响应Cookies
|
||||
Request *Request `json:"request"` // 原始请求
|
||||
}
|
||||
|
||||
// 处理请求方法
|
||||
func (r *Request) getMethod() string {
|
||||
return strings.ToUpper(r.Method) // 必须转为全部大写
|
||||
}
|
||||
|
||||
// 组装URL
|
||||
func (r *Request) getUrl() string {
|
||||
if r.Params != nil {
|
||||
urlValues := url.Values{}
|
||||
Url, _ := url.Parse(r.Url) // todo 处理err
|
||||
for key, value := range r.Params {
|
||||
urlValues.Set(key, value)
|
||||
}
|
||||
Url.RawQuery = urlValues.Encode()
|
||||
return Url.String()
|
||||
}
|
||||
return r.Url
|
||||
}
|
||||
|
||||
// 组装请求数据
|
||||
func (r *Request) getData() io.Reader {
|
||||
var reqBody string
|
||||
if r.Headers == nil {
|
||||
r.Headers = make(map[string]string, 1)
|
||||
}
|
||||
if r.Raw != "" {
|
||||
reqBody = r.Raw
|
||||
} else if r.Data != nil {
|
||||
urlValues := url.Values{}
|
||||
for key, value := range r.Data {
|
||||
urlValues.Add(key, value)
|
||||
}
|
||||
reqBody = urlValues.Encode()
|
||||
r.Headers["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
} else if r.Json != nil {
|
||||
bytesData, _ := json.Marshal(r.Json)
|
||||
reqBody = string(bytesData)
|
||||
r.Headers["Content-Type"] = "application/json"
|
||||
} else if r.JsonByte != nil {
|
||||
reqBody = string(r.JsonByte)
|
||||
r.Headers["Content-Type"] = "application/json"
|
||||
}
|
||||
return strings.NewReader(reqBody)
|
||||
}
|
||||
|
||||
// 添加请求头-需要在getData后使用
|
||||
func (r *Request) addHeaders(req *http.Request) {
|
||||
if r.Headers != nil {
|
||||
for key, value := range r.Headers {
|
||||
req.Header.Add(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 准备请求
|
||||
func (r *Request) prepare() *http.Request {
|
||||
Method := r.getMethod()
|
||||
Url := r.getUrl()
|
||||
Data := r.getData()
|
||||
req, _ := http.NewRequest(Method, Url, Data)
|
||||
r.addHeaders(req)
|
||||
return req
|
||||
}
|
||||
|
||||
// 组装响应对象
|
||||
func (r *Request) packResponse(res *http.Response, elapsed float64) Response {
|
||||
var resp Response
|
||||
resBody, _ := io.ReadAll(res.Body)
|
||||
resp.Content = resBody
|
||||
resp.Text = string(resBody)
|
||||
resp.StatusCode = res.StatusCode
|
||||
resp.Reason = strings.Split(res.Status, " ")[1]
|
||||
resp.Elapsed = elapsed
|
||||
resp.Headers = map[string]string{}
|
||||
for key, value := range res.Header {
|
||||
resp.Headers[key] = strings.Join(value, ";")
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
// 发送请求
|
||||
func (r *Request) Send() (Response, error) {
|
||||
req := r.prepare()
|
||||
client := &http.Client{}
|
||||
start := time.Now()
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return Response{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
elapsed := time.Since(start).Seconds()
|
||||
return r.packResponse(res, elapsed), nil
|
||||
}
|
Loading…
Reference in New Issue