// Package curl ... // // Author: go_developer@163.com<白茶清欢> // // Description: // // File: request.go // // Version: 1.0.0 // // Date: 2022/05/01 21:25:03 package curl import ( "bytes" "encoding/json" "fmt" "net/http" "strings" "time" "github.com/ddliu/go-httpclient" ) // Request 发送请求 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/05/01 21:26:02 func Request(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse { apiConfig.Method = strings.ToUpper(apiConfig.Method) switch apiConfig.Method { case http.MethodGet: return GET(apiConfig, header, param) case http.MethodPost: return POST(apiConfig, header, param) case http.MethodPut: return PUT(apiConfig, header, param) case http.MethodDelete: return DELETE(apiConfig, header, param) case http.MethodConnect: return Connect(apiConfig, header, param) case http.MethodOptions: return OPTION(apiConfig, header, param) case http.MethodTrace: return Trace(apiConfig, header, param) case http.MethodPatch: return Patch(apiConfig, header, param) default: return &ApiResponse{ RequestConfig: apiConfig, Exception: NewException(RequestMethodNotSupport, map[string]string{"method": apiConfig.Method}), Response: nil, StartRequestTime: time.Now().UnixNano(), FinishRequestTime: time.Now().UnixNano(), } } } // GET ... // // Author : go_developer@163.com<白茶清欢> // // Date: 2022/05/01 21:29:09 func GET(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse { apiConfig.Method = http.MethodGet buildRequestURLAndParam(apiConfig, header, param) return send(apiConfig, header) } // POST post请求 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/05/01 21:31:36 func POST(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse { apiConfig.Method = http.MethodPost buildRequestURLAndParam(apiConfig, header, param) return send(apiConfig, header) } // PUT put请求 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/05/01 21:31:52 func PUT(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse { apiConfig.Method = http.MethodPut buildRequestURLAndParam(apiConfig, header, param) return send(apiConfig, header) } // DELETE delete请求 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/05/01 21:32:08 func DELETE(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse { apiConfig.Method = http.MethodDelete buildRequestURLAndParam(apiConfig, header, param) return send(apiConfig, header) } // OPTION option请求 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/05/01 21:32:18 func OPTION(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse { apiConfig.Method = http.MethodOptions buildRequestURLAndParam(apiConfig, header, param) return send(apiConfig, header) } // Patch patch请求 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/05/01 21:36:12 func Patch(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse { apiConfig.Method = http.MethodPatch buildRequestURLAndParam(apiConfig, header, param) return send(apiConfig, header) } // Trace trace请求 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/05/01 21:36:24 func Trace(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse { apiConfig.Method = http.MethodTrace buildRequestURLAndParam(apiConfig, header, param) return send(apiConfig, header) } // Connect connect请求 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/05/01 21:36:39 func Connect(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse { apiConfig.Method = http.MethodConnect buildRequestURLAndParam(apiConfig, header, param) return send(apiConfig, header) } // getHttpClient 获取httpclient实例 // // Author : go_developer@163.com<白茶清欢> // // Date : 22:27 2022/5/1 func getHttpClient(apiConfig *ApiRequestConfig, header map[string]string) *httpclient.HttpClient { fullHeader := make(map[string]string) for name, val := range apiConfig.CommonHeader { fullHeader[name] = val } for name, val := range header { fullHeader[name] = val } if len(apiConfig.ContentType) == 0 { apiConfig.ContentType = ContentTypeDefault } fullHeader["content-type"] = apiConfig.ContentType return httpclient.NewHttpClient().WithHeaders(fullHeader). WithOption(httpclient.OPT_CONNECTTIMEOUT_MS, time.Duration(apiConfig.Timeout.Connect)*time.Millisecond). WithOption(httpclient.OPT_TIMEOUT, time.Duration(apiConfig.Timeout.Read)*time.Millisecond) } // buildRequestURLAndParam 构建完整请求URL与请求参数 // // Author : go_developer@163.com<白茶清欢> // // Date : 21:55 2022/5/1 func buildRequestURLAndParam(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) { apiConfig.Method = strings.ToUpper(apiConfig.Method) if apiConfig.Timeout.Connect == 0 { apiConfig.Timeout.Connect = DefaultConnectTimeout } if apiConfig.Timeout.Read == 0 { apiConfig.Timeout.Read = DefaultConnectTimeout } formatParam := make(map[string]interface{}) for paramName, paramValue := range param { uriTemplate := "{" + paramName + "}" if strings.Contains(apiConfig.URI, uriTemplate) { apiConfig.URI = strings.ReplaceAll(apiConfig.URI, uriTemplate, fmt.Sprintf("%v", paramValue)) continue } formatParam[paramName] = paramValue } apiConfig.Parameter = formatParam paramPair := make([]string, 0) switch apiConfig.Method { case http.MethodPost: apiConfig.Body, _ = json.Marshal(formatParam) default: for paramName, paramValue := range formatParam { paramPair = append(paramPair, fmt.Sprintf("%v=%v", paramName, paramValue)) } if len(paramPair) > 0 { apiConfig.URI = apiConfig.URI + "?" + strings.Join(paramPair, "&") } } apiConfig.FullURL = strings.ReplaceAll(apiConfig.Domain+"/"+apiConfig.URI, "//", "/") } // send 发送请求 // // Author : go_developer@163.com<白茶清欢> // // Date : 14:53 2022/5/2 func send(apiConfig *ApiRequestConfig, header map[string]string) *ApiResponse { var ( client *httpclient.HttpClient err error ) response := &ApiResponse{ RequestConfig: apiConfig, Response: nil, Exception: nil, StartRequestTime: time.Now().UnixNano(), FinishRequestTime: 0, } defer func() { response.FinishRequestTime = time.Now().UnixNano() }() client = getHttpClient(apiConfig, header) if response.Response, err = client.Do(apiConfig.Method, apiConfig.FullURL, nil, bytes.NewReader(apiConfig.Body)); nil != err { response.Exception = NewException(SendRequestError, map[string]string{"real_reason": err.Error()}) } return response }