package common import ( "fmt" "github.com/go-resty/resty/v2" "io" "io/ioutil" "net/http" "os" "path" "regexp" "strings" ) // NewHttpClient 新建一个 resty 的对象 func NewHttpClient(_reqParam ...ReqParam) *resty.Client { //const defUserAgent = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50" const defUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.41" var reqParam ReqParam var HttpProxy, UserAgent, Referer string if len(_reqParam) > 0 { reqParam = _reqParam[0] } if len(reqParam.HttpProxy) > 0 { HttpProxy = reqParam.HttpProxy } if len(reqParam.UserAgent) > 0 { UserAgent = reqParam.UserAgent } else { UserAgent = defUserAgent } if len(reqParam.Referer) > 0 { Referer = reqParam.Referer } httpClient := resty.New() httpClient.SetTimeout(HTMLTimeOut) if HttpProxy != "" { httpClient.SetProxy(HttpProxy) } httpClient.SetHeaders(map[string]string{ "Content-Type": "application/json", "User-Agent": UserAgent, }) if len(Referer) > 0 { httpClient.SetHeader("Referer", Referer) } return httpClient } // DownFile 从指定的 url 下载文件 func DownFile(urlStr string, _reqParam ...ReqParam) ([]byte, string, error) { var reqParam ReqParam if len(_reqParam) > 0 { reqParam = _reqParam[0] } httpClient := NewHttpClient(reqParam) resp, err := httpClient.R().Get(urlStr) if err != nil { return nil, "", err } filename := GetFileName(resp.RawResponse) return resp.Body(), filename, nil } // GetFileName 获取下载文件的文件名 func GetFileName(resp *http.Response) string { contentDisposition := resp.Header.Get("Content-Disposition") if len(contentDisposition) == 0 { return "" } re := regexp.MustCompile(`filename=["]*([^"]+)["]*`) matched := re.FindStringSubmatch(contentDisposition) if matched == nil || len(matched) == 0 || len(matched[0]) == 0 { //fmt.Println("######") return "" } return matched[1] } // AddBaseUrl 判断驶入的 url 是否需要拼接 baseUrl func AddBaseUrl(baseUrl, url string) string { if strings.Contains(url, "://") { return url } return fmt.Sprintf("%s%s", baseUrl, url) } func GetDebugFolder() (string, error) { if defDebugFolder == "" { nowProcessRoot, _ := os.Getwd() nowProcessRoot = path.Join(nowProcessRoot, DebugFolder) err := os.MkdirAll(nowProcessRoot, os.ModePerm) if err != nil { return "", err } defDebugFolder = nowProcessRoot return nowProcessRoot, err } return defDebugFolder, nil } func GetTmpFolder() (string, error) { if defTmpFolder == "" { nowProcessRoot, _ := os.Getwd() nowProcessRoot = path.Join(nowProcessRoot, TmpFolder) err := os.MkdirAll(nowProcessRoot, os.ModePerm) if err != nil { return "", err } defTmpFolder = nowProcessRoot return nowProcessRoot, err } return defTmpFolder, nil } func ClearTmpFolder() error { nowTmpFolder, err := GetTmpFolder() if err != nil { return err } pathSep := string(os.PathSeparator) files, err := ioutil.ReadDir(nowTmpFolder) if err != nil { return err } for _, curFile := range files { fullPath := nowTmpFolder + pathSep + curFile.Name() if curFile.IsDir() { err = os.RemoveAll(fullPath) if err != nil { return err } } else { // 这里就是文件了 err = os.Remove(fullPath) if err != nil { return err } } } return nil } func CopyFile(dstName, srcName string) (written int64, err error) { src, err := os.Open(srcName) if err != nil { return } defer src.Close() dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return } defer dst.Close() return io.Copy(dst, src) } var ( defDebugFolder = "" defTmpFolder = "" ) // ReqParam 可选择传入的参数 type ReqParam struct { UserExtList []string // 用户确认的视频后缀名支持列表 DebugMode bool // 调试标志位 HttpProxy string // HttpClient 相关 UserAgent string // HttpClient 相关 Referer string // HttpClient 相关 MediaType string // HttpClient 相关 Charset string // HttpClient 相关 Topic int // 搜索结果的时候,返回 Topic N 以内的 }