github.com/iikira/iikira-go-utils@v0.0.0-20230610031953-f2cb11cde33a/requester/fetch.go (about) 1 package requester 2 3 import ( 4 "bytes" 5 "fmt" 6 "github.com/iikira/iikira-go-utils/requester/rio" 7 "io" 8 "io/ioutil" 9 "net/http" 10 "net/url" 11 "strings" 12 ) 13 14 // HTTPGet 简单实现 http 访问 GET 请求 15 func HTTPGet(urlStr string) (body []byte, err error) { 16 resp, err := DefaultClient.Get(urlStr) 17 if resp != nil { 18 defer resp.Body.Close() 19 } 20 if err != nil { 21 return nil, err 22 } 23 return ioutil.ReadAll(resp.Body) 24 } 25 26 // Req 参见 *HTTPClient.Req, 使用默认 http 客户端 27 func Req(method string, urlStr string, post interface{}, header map[string]string) (resp *http.Response, err error) { 28 return DefaultClient.Req(method, urlStr, post, header) 29 } 30 31 // Fetch 参见 *HTTPClient.Fetch, 使用默认 http 客户端 32 func Fetch(method string, urlStr string, post interface{}, header map[string]string) (body []byte, err error) { 33 return DefaultClient.Fetch(method, urlStr, post, header) 34 } 35 36 // Req 实现 http/https 访问, 37 // 根据给定的 method (GET, POST, HEAD, PUT 等等), urlStr (网址), 38 // post (post 数据), header (header 请求头数据), 进行网站访问。 39 // 返回值分别为 *http.Response, 错误信息 40 func (h *HTTPClient) Req(method string, urlStr string, post interface{}, header map[string]string) (resp *http.Response, err error) { 41 h.lazyInit() 42 var ( 43 req *http.Request 44 obody io.Reader 45 contentLength int64 46 contentType string 47 ) 48 49 if post != nil { 50 switch value := post.(type) { 51 case io.Reader: 52 obody = value 53 case map[string]string: 54 query := url.Values{} 55 for k := range value { 56 query.Set(k, value[k]) 57 } 58 obody = strings.NewReader(query.Encode()) 59 contentType = "application/x-www-form-urlencoded" 60 case map[string]interface{}: 61 query := url.Values{} 62 for k := range value { 63 query.Set(k, fmt.Sprint(value[k])) 64 } 65 obody = strings.NewReader(query.Encode()) 66 contentType = "application/x-www-form-urlencoded" 67 case map[interface{}]interface{}: 68 query := url.Values{} 69 for k := range value { 70 query.Set(fmt.Sprint(k), fmt.Sprint(value[k])) 71 } 72 obody = strings.NewReader(query.Encode()) 73 contentType = "application/x-www-form-urlencoded" 74 case string: 75 obody = strings.NewReader(value) 76 case []byte: 77 obody = bytes.NewReader(value[:]) 78 default: 79 return nil, fmt.Errorf("requester.Req: unknown post type: %s", value) 80 } 81 82 switch value := post.(type) { 83 case ContentLengther: 84 contentLength = value.ContentLength() 85 case rio.Lener: 86 contentLength = int64(value.Len()) 87 case rio.Lener64: 88 contentLength = value.Len() 89 } 90 91 switch value := post.(type) { 92 case ContentTyper: 93 contentType = value.ContentType() 94 } 95 } 96 req, err = http.NewRequest(method, urlStr, obody) 97 if err != nil { 98 return nil, err 99 } 100 101 if req.ContentLength <= 0 && contentLength != 0 { 102 req.ContentLength = contentLength 103 } 104 105 // 设置浏览器标识 106 req.Header.Set("User-Agent", h.UserAgent) 107 108 // 设置Content-Type 109 if contentType != "" { 110 req.Header.Set("Content-Type", contentType) 111 } 112 113 if header != nil { 114 // 处理Host 115 if host, ok := header["Host"]; ok { 116 req.Host = host 117 } 118 119 for key := range header { 120 req.Header.Set(key, header[key]) 121 } 122 } 123 124 return h.Client.Do(req) 125 } 126 127 // Fetch 实现 http/https 访问, 128 // 根据给定的 method (GET, POST, HEAD, PUT 等等), urlStr (网址), 129 // post (post 数据), header (header 请求头数据), 进行网站访问。 130 // 返回值分别为 网站主体, 错误信息 131 func (h *HTTPClient) Fetch(method string, urlStr string, post interface{}, header map[string]string) (body []byte, err error) { 132 h.lazyInit() 133 resp, err := h.Req(method, urlStr, post, header) 134 if resp != nil { 135 defer resp.Body.Close() 136 } 137 if err != nil { 138 return nil, err 139 } 140 141 return ioutil.ReadAll(resp.Body) 142 }