package main import ( "encoding/json" "fmt" "io" "io/ioutil" "log" "mime" "net/http" "net/url" "os" "strconv" "time" ) func saveURL(url string) (tmpFile string, contentType string, err error) { req, err := http.NewRequest("GET", url, nil) if err != nil { return } return saveHTTPRequest(req) } //{"video_url":"http://153.37.232.145/vweixinp.tc.qq.com/1007_6475d21fb443453b8adeac7e59cc0e1c.f10.mp4?vkey=E79C6B0DA06E7A434D15E24774F91412386D1956768C400AC93ECA5320ACAAAF050E1E1BA5C22DFD81B5EE3FBA97E928E0FC2DC597CF611B3E6641BC1AEE2892736FFE29E993F200AA4A0811FEB4E234C48516131207DDE4&sha=0&save=1"} type videoURL struct { VideoURL string `json:"video_url"` } //readVideoURL try to read a file into json structure //containing video_url // func readVideoURL(path string) (u string) { body, err := ioutil.ReadFile(path) if err == nil { var v = videoURL{} err = json.Unmarshal([]byte(body), &v) if err == nil { _, err = url.ParseRequestURI(v.VideoURL) if err == nil { return v.VideoURL } } } return "" } func buildHTTPReqWithHeader(httpMethod, targetURL string, headers map[string]string) (req *http.Request, err error) { req, err = http.NewRequest(httpMethod, targetURL, nil) if err != nil { return } if headers != nil { for k, v := range headers { req.Header.Set(k, v) } } return } func saveHTTPRequest(req *http.Request) (tmpFile string, contentType string, err error) { var myClient = &http.Client{Timeout: 20 * time.Second} r, err := myClient.Do(req) if err != nil { log.Printf("Fail to get URL: %s", req.RequestURI) log.Println(err) return "", "", err } defer r.Body.Close() contentType = r.Header.Get("Content-Type") contentLen := r.Header.Get("Content-Length") len, _ := strconv.Atoi(contentLen) log.Println(r) file, err := ioutil.TempFile(os.TempDir(), "wechat_hitxy_") // Use io.Copy to just dump the response body to the file. This supports huge files _, err = io.Copy(file, r.Body) if err != nil { log.Println(err) return "", contentType, err } noSuffix := file.Name() file.Close() tmpFile = noSuffix + contentType2Suffix(contentType) os.Rename(noSuffix, tmpFile) //see if its a video url if len < 4096 && contentType == "text/plain" { u := readVideoURL(tmpFile) if u != "" { fmt.Println("saveing video url: " + u) os.Remove(tmpFile) //remove json file tmpFile, contentType, err = saveURL(u) } } return } func saveURLwithHTTPHeader(url string, headers map[string]string) (tmpFile string, contentType string, err error) { log.Println("saveURL: " + url) req, err := buildHTTPReqWithHeader("GET", url, headers) if err != nil { return } return saveHTTPRequest(req) } func contentType2Suffix(typ string) string { exts, err := mime.ExtensionsByType(typ) if err != nil { return "" } return exts[0] }