package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "net/http/httputil" "time" "k8s.io/klog" ) type OptionsRetryRequest struct { Retry int `json:"retry"` Throtle int64 `json:"throtle"` Body interface{} `json:"body"` Headers map[string]string `json:"headers"` } func HttpRetryRequest(url string, method string, IsJson bool, options *OptionsRetryRequest) ([]byte, error) { var ( count int = 1 res *http.Response = &http.Response{} err error = nil body []byte = nil blocking chan bool = make(chan bool, 1) client *http.Client = &http.Client{} ) tick := time.NewTicker(time.Duration(options.Throtle/1000) * time.Second) if IsJson && options.Body != nil { bodyByte, err := json.Marshal(&options.Body) if err != nil { return nil, err } body = bodyByte } else if !IsJson && options.Body != nil { body = []byte(fmt.Sprintf("%s", options.Body)) } for range tick.C { req, err := http.NewRequest(method, url, bytes.NewReader(body)) if err != nil { return nil, err } if _, err := httpDumpReq(req); err != nil { return nil, err } if options.Headers != nil { for k, v := range options.Headers { req.Header.Set(k, v) } } res, err = client.Do(req) if err != nil { return nil, err } if _, err := httpDumpRes(res); err != nil { return nil, err } if count == options.Retry { blocking <- true tick.Stop() break } count++ } if err != nil { return nil, err } resByte, err := io.ReadAll(res.Body) defer res.Body.Close() if err != nil { return nil, err } <-blocking return resByte, nil } func httpDumpReq(req *http.Request) ([]byte, error) { reqDump, err := httputil.DumpRequest(req, true) if err != nil { return nil, err } klog.Info("====================== HTTP DUMP REQUEST START ======================") klog.Infof("====================== HTTP DUMP REQUEST OUTPUT ==================== \n\n%s", string(reqDump)) klog.Info("====================== HTTP DUMP REQUEST END ========================") return reqDump, nil } func httpDumpRes(res *http.Response) ([]byte, error) { resDump, err := httputil.DumpResponse(res, true) if err != nil { return nil, err } klog.Info("====================== HTTP DUMP RESPONSE START ======================") klog.Infof("===================== HTTP DUMP RESPONSE OUTPUT ====================== \n\n%s", string(resDump)) klog.Info("====================== HTTP DUMP RESPONSE END ========================") return resDump, nil }