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