github.com/orangebees/go-oneutils@v0.0.10/Fetch/func.go (about)

     1  package Fetch
     2  
     3  import (
     4  	"encoding/json"
     5  	"github.com/valyala/fasthttp"
     6  	"sync"
     7  )
     8  
     9  type EasyJsonSerialization interface {
    10  	MarshalJSON() ([]byte, error)
    11  	UnmarshalJSON(data []byte) error
    12  }
    13  type Client struct {
    14  	proxy   string
    15  	options []Option
    16  }
    17  
    18  func NewClient(proxy string, options ...Option) *Client {
    19  	return &Client{
    20  		proxy:   proxy,
    21  		options: options,
    22  	}
    23  }
    24  
    25  type Ctx struct {
    26  	req  *fasthttp.Request
    27  	resp *fasthttp.Response
    28  }
    29  
    30  var ctxpool = sync.Pool{New: func() any {
    31  	return &Ctx{
    32  		req:  fasthttp.AcquireRequest(),
    33  		resp: fasthttp.AcquireResponse(),
    34  	}
    35  }}
    36  
    37  func AcquireCtx() *Ctx {
    38  	return ctxpool.Get().(*Ctx)
    39  }
    40  func ReleaseRequest(ctx *Ctx) {
    41  	ctx.Reset()
    42  	ctxpool.Put(ctx)
    43  }
    44  func (c *Ctx) Reset() {
    45  	c.req.Reset()
    46  	c.resp.Reset()
    47  }
    48  
    49  func (c *Client) Json(ctx *Ctx, endpoint string, reqData any, respData any, options ...Option) error {
    50  	ctx.Reset()
    51  	ctx.req.Header.SetMethod("POST")
    52  	ctx.req.SetRequestURI(endpoint)
    53  	if reqData != nil {
    54  		jsonbytes, err := json.Marshal(reqData)
    55  		if err != nil {
    56  			return err
    57  		}
    58  		ctx.req.SetBody(jsonbytes)
    59  	}
    60  	if c.proxy != "" {
    61  		ctx.req.Header.SetHostBytes(ctx.req.URI().Host())
    62  		ctx.req.URI().SetHost(c.proxy)
    63  	}
    64  	for i := 0; i < len(c.options); i++ {
    65  		options[i](ctx.req)
    66  	}
    67  	for i := 0; i < len(options); i++ {
    68  		options[i](ctx.req)
    69  	}
    70  	if err := fasthttp.Do(ctx.req, ctx.resp); err != nil {
    71  		return err
    72  	}
    73  	body, err := ctx.resp.BodyUncompressed()
    74  	if err != nil {
    75  		return err
    76  	}
    77  	err = json.Unmarshal(body, respData)
    78  	if err != nil {
    79  		return err
    80  	}
    81  	return nil
    82  }
    83  
    84  type Option func(req *fasthttp.Request)
    85  
    86  // UseGetOption 设置GET请求
    87  func UseGetOption(req *fasthttp.Request) {
    88  	req.Header.SetMethod("GET")
    89  }
    90  
    91  // UseCompressOption 设置请求优先使用压缩
    92  func UseCompressOption(req *fasthttp.Request) {
    93  	req.Header.Set("Accept-Encoding", "gzip, deflate, br")
    94  }
    95  
    96  // SetHostHeadOption 设置host头
    97  func SetHostHeadOption(req *fasthttp.Request) {
    98  	req.Header.SetHostBytes(req.URI().Host())
    99  }
   100  
   101  // SetCustomHostHeadOption  设置用户自定义host头
   102  func SetCustomHostHeadOption(host string) Option {
   103  	return func(req *fasthttp.Request) {
   104  		req.Header.SetHost(host)
   105  	}
   106  }
   107  
   108  // Json  json请求与响应
   109  func Json(endpoint string, reqData any, respData any, options ...Option) error {
   110  	req := fasthttp.AcquireRequest()
   111  	defer fasthttp.ReleaseRequest(req)
   112  	req.Header.SetMethod("POST")
   113  	req.SetRequestURI(endpoint)
   114  	if reqData != nil {
   115  		jsonbytes, err := json.Marshal(reqData)
   116  		if err != nil {
   117  			return err
   118  		}
   119  		req.SetBody(jsonbytes)
   120  	}
   121  	for i := 0; i < len(options); i++ {
   122  		options[i](req)
   123  	}
   124  	resp := fasthttp.AcquireResponse()
   125  	defer fasthttp.ReleaseResponse(resp)
   126  	if err := fasthttp.Do(req, resp); err != nil {
   127  		return err
   128  	}
   129  	body, err := resp.BodyUncompressed()
   130  	if err != nil {
   131  		return err
   132  	}
   133  	err = json.Unmarshal(body, respData)
   134  	if err != nil {
   135  		return err
   136  	}
   137  	return nil
   138  }
   139  
   140  // Text text请求与响应
   141  func Text(endpoint string, reqData string, options ...Option) (string, error) {
   142  	req := fasthttp.AcquireRequest()
   143  	defer fasthttp.ReleaseRequest(req)
   144  	req.Header.SetMethod("POST")
   145  	req.SetRequestURI(endpoint)
   146  	req.SetBodyString(reqData)
   147  	for i := 0; i < len(options); i++ {
   148  		options[i](req)
   149  	}
   150  	resp := fasthttp.AcquireResponse()
   151  	defer fasthttp.ReleaseResponse(resp)
   152  	if err := fasthttp.Do(req, resp); err != nil {
   153  		return "", err
   154  	}
   155  	body, err := resp.BodyUncompressed()
   156  	if err != nil {
   157  		return "", err
   158  	}
   159  	return string(body), nil
   160  }
   161  
   162  // Query 查询请求与响应
   163  func Query(endpoint string, reqData *fasthttp.Args, options ...Option) (string, error) {
   164  	req := fasthttp.AcquireRequest()
   165  	defer fasthttp.ReleaseRequest(req)
   166  	req.Header.SetMethod("GET")
   167  	req.SetRequestURI(endpoint)
   168  	if reqData != nil {
   169  		reqData.CopyTo(req.URI().QueryArgs())
   170  	}
   171  	for i := 0; i < len(options); i++ {
   172  		options[i](req)
   173  	}
   174  	resp := fasthttp.AcquireResponse()
   175  	defer fasthttp.ReleaseResponse(resp)
   176  	if err := fasthttp.Do(req, resp); err != nil {
   177  		return "", err
   178  	}
   179  	body, err := resp.BodyUncompressed()
   180  	if err != nil {
   181  		return "", err
   182  	}
   183  	return string(body), nil
   184  }
   185  
   186  // EasyJson 使用easyJson接口的json请求与响应
   187  func EasyJson(endpoint string, reqData EasyJsonSerialization, respData EasyJsonSerialization, options ...Option) error {
   188  	jsonbytes, err := reqData.MarshalJSON()
   189  	if err != nil {
   190  		return err
   191  	}
   192  	req := fasthttp.AcquireRequest()
   193  	defer fasthttp.ReleaseRequest(req)
   194  	req.Header.SetMethod("POST")
   195  	req.SetRequestURI(endpoint)
   196  	req.SetBody(jsonbytes)
   197  	for i := 0; i < len(options); i++ {
   198  		options[i](req)
   199  	}
   200  	resp := fasthttp.AcquireResponse()
   201  	defer fasthttp.ReleaseResponse(resp)
   202  	if err = fasthttp.Do(req, resp); err != nil {
   203  		return err
   204  	}
   205  	body, err := resp.BodyUncompressed()
   206  	if err != nil {
   207  		return err
   208  	}
   209  	err = respData.UnmarshalJSON(body)
   210  	if err != nil {
   211  		return err
   212  	}
   213  	return nil
   214  }