github.com/fzfile/BaiduPCS-Go@v0.0.0-20200606205115-4408961cf336/requester/fetch.go (about)

     1  package requester
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"github.com/fzfile/BaiduPCS-Go/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  		case map[string]interface{}:
    60  			query := url.Values{}
    61  			for k := range value {
    62  				query.Set(k, fmt.Sprint(value[k]))
    63  			}
    64  			obody = strings.NewReader(query.Encode())
    65  		case map[interface{}]interface{}:
    66  			query := url.Values{}
    67  			for k := range value {
    68  				query.Set(fmt.Sprint(k), fmt.Sprint(value[k]))
    69  			}
    70  			obody = strings.NewReader(query.Encode())
    71  		case string:
    72  			obody = strings.NewReader(value)
    73  		case []byte:
    74  			obody = bytes.NewReader(value[:])
    75  		default:
    76  			return nil, fmt.Errorf("requester.Req: unknown post type: %s", value)
    77  		}
    78  
    79  		switch value := post.(type) {
    80  		case ContentLengther:
    81  			contentLength = value.ContentLength()
    82  		case rio.Lener:
    83  			contentLength = int64(value.Len())
    84  		case rio.Lener64:
    85  			contentLength = value.Len()
    86  		}
    87  
    88  		switch value := post.(type) {
    89  		case ContentTyper:
    90  			contentType = value.ContentType()
    91  		}
    92  	}
    93  	req, err = http.NewRequest(method, urlStr, obody)
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  
    98  	if req.ContentLength <= 0 && contentLength != 0 {
    99  		req.ContentLength = contentLength
   100  	}
   101  
   102  	// 设置浏览器标识
   103  	req.Header.Set("User-Agent", h.UserAgent)
   104  
   105  	// 设置Content-Type
   106  	if contentType != "" {
   107  		req.Header.Set("Content-Type", contentType)
   108  	}
   109  
   110  	if header != nil {
   111  		// 处理Host
   112  		if host, ok := header["Host"]; ok {
   113  			req.Host = host
   114  		}
   115  
   116  		for key := range header {
   117  			req.Header.Set(key, header[key])
   118  		}
   119  	}
   120  
   121  	return h.Client.Do(req)
   122  }
   123  
   124  // Fetch 实现 http/https 访问,
   125  // 根据给定的 method (GET, POST, HEAD, PUT 等等), urlStr (网址),
   126  // post (post 数据), header (header 请求头数据), 进行网站访问。
   127  // 返回值分别为 网站主体, 错误信息
   128  func (h *HTTPClient) Fetch(method string, urlStr string, post interface{}, header map[string]string) (body []byte, err error) {
   129  	h.lazyInit()
   130  	resp, err := h.Req(method, urlStr, post, header)
   131  	if resp != nil {
   132  		defer resp.Body.Close()
   133  	}
   134  	if err != nil {
   135  		return nil, err
   136  	}
   137  
   138  	return ioutil.ReadAll(resp.Body)
   139  }