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 }