Golang如何在代理服务器中实现文件下载

Golang如何在代理服务器中实现文件下载

代理服务器 这是一个下载用的HTTP处理函数,我想将文件从192.168.1.52保存到这台服务器上。

func Download(w http.ResponseWriter, r *http.Request) {
	//
	golog.Info("downloading.....")
	uid := xmux.Var[r.URL.Path]["uid"]
	filename := xmux.Var[r.URL.Path]["name"]
	es := NewResp()
	if v := filelru.FileLru.Get(uid+filename); v != nil {
		golog.Info("from cache")
		w.Write(v.([]byte))
		return
	}
	//var downReader io.Reader
	var downdata []byte
	var err error
	if goconfig.ReadBool("proxy", true) {
		proxyUrl , _ := url.Parse("http://192.168.1.52")
		rp := httputil.NewSingleHostReverseProxy(proxyUrl)
		rp.ServeHTTP(w, r)
                // 我想将文件保存到这台服务器上。在这里
	} else {
		downdata, err = ioutil.ReadFile(filepath.Join(goconfig.ReadString("storedir"), uid, filename))
		if err != nil {
			golog.Error(err.Error())
			w.Write(es.ErrorE(err))
			return
		}
	}

	filelru.FileLru.Add(uid+filename, downdata)
	w.Write(downdata)
}

更多关于Golang如何在代理服务器中实现文件下载的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang如何在代理服务器中实现文件下载的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在代理服务器中实现文件下载并保存到本地,可以通过修改ReverseProxyDirector函数或使用ModifyResponse回调来实现。以下是修改后的代码示例:

func Download(w http.ResponseWriter, r *http.Request) {
    golog.Info("downloading.....")
    uid := xmux.Var[r.URL.Path]["uid"]
    filename := xmux.Var[r.URL.Path]["name"]
    es := NewResp()
    
    if v := filelru.FileLru.Get(uid+filename); v != nil {
        golog.Info("from cache")
        w.Write(v.([]byte))
        return
    }
    
    var downdata []byte
    var err error
    
    if goconfig.ReadBool("proxy", true) {
        proxyUrl, _ := url.Parse("http://192.168.1.52")
        rp := httputil.NewSingleHostReverseProxy(proxyUrl)
        
        // 保存响应数据到本地
        rp.ModifyResponse = func(resp *http.Response) error {
            if resp.StatusCode == http.StatusOK {
                // 读取响应体
                bodyBytes, err := io.ReadAll(resp.Body)
                if err != nil {
                    return err
                }
                
                // 保存到本地文件
                localPath := filepath.Join(goconfig.ReadString("storedir"), uid, filename)
                os.MkdirAll(filepath.Dir(localPath), 0755)
                err = os.WriteFile(localPath, bodyBytes, 0644)
                if err != nil {
                    return err
                }
                
                // 保存到内存缓存
                filelru.FileLru.Add(uid+filename, bodyBytes)
                downdata = bodyBytes
                
                // 重置响应体供后续使用
                resp.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
            }
            return nil
        }
        
        rp.ServeHTTP(w, r)
    } else {
        downdata, err = ioutil.ReadFile(filepath.Join(goconfig.ReadString("storedir"), uid, filename))
        if err != nil {
            golog.Error(err.Error())
            w.Write(es.ErrorE(err))
            return
        }
        filelru.FileLru.Add(uid+filename, downdata)
        w.Write(downdata)
    }
}

或者使用更简洁的方式,在代理请求前直接下载文件:

func Download(w http.ResponseWriter, r *http.Request) {
    golog.Info("downloading.....")
    uid := xmux.Var[r.URL.Path]["uid"]
    filename := xmux.Var[r.URL.Path]["name"]
    es := NewResp()
    
    if v := filelru.FileLru.Get(uid+filename); v != nil {
        golog.Info("from cache")
        w.Write(v.([]byte))
        return
    }
    
    var downdata []byte
    var err error
    
    if goconfig.ReadBool("proxy", true) {
        // 直接下载文件
        client := &http.Client{}
        req, _ := http.NewRequest("GET", "http://192.168.1.52"+r.URL.Path, nil)
        resp, err := client.Do(req)
        if err != nil {
            golog.Error(err.Error())
            w.Write(es.ErrorE(err))
            return
        }
        defer resp.Body.Close()
        
        if resp.StatusCode == http.StatusOK {
            // 读取文件数据
            downdata, err = io.ReadAll(resp.Body)
            if err != nil {
                golog.Error(err.Error())
                w.Write(es.ErrorE(err))
                return
            }
            
            // 保存到本地
            localPath := filepath.Join(goconfig.ReadString("storedir"), uid, filename)
            os.MkdirAll(filepath.Dir(localPath), 0755)
            err = os.WriteFile(localPath, downdata, 0644)
            if err != nil {
                golog.Error(err.Error())
                w.Write(es.ErrorE(err))
                return
            }
            
            // 缓存并返回
            filelru.FileLru.Add(uid+filename, downdata)
            w.Write(downdata)
            return
        }
    } else {
        downdata, err = ioutil.ReadFile(filepath.Join(goconfig.ReadString("storedir"), uid, filename))
        if err != nil {
            golog.Error(err.Error())
            w.Write(es.ErrorE(err))
            return
        }
        filelru.FileLru.Add(uid+filename, downdata)
        w.Write(downdata)
    }
}

第一个方案使用ModifyResponse回调在代理过程中保存文件,第二个方案直接下载文件后再代理返回。两个方案都能实现将远程文件保存到本地服务器的需求。

回到顶部