添加下载代理接口

This commit is contained in:
junleea 2025-09-06 13:54:12 +08:00
parent f0e025bec5
commit e2ebdc0621
2 changed files with 73 additions and 0 deletions

View File

@ -6,7 +6,9 @@ import (
"io"
"log"
"net/http"
"net/url"
"os"
"path/filepath"
"strconv"
"time"
"videoplayer/dao"
@ -57,6 +59,8 @@ func SetUpToolGroup(router *gin.Engine) {
toolGroup.POST("/del_monitor", DelMonitor) //删除设备监控
//发送邮件
toolGroup.POST("/send_mail", SendMailTool)
//下载代理
toolGroup.GET("/dl/:url", DownloadProxyHandle)
}
func GetMonitorList(c *gin.Context) {
@ -485,3 +489,71 @@ func SendMailTool(c *gin.Context) {
}
}
// DownloadProxyHandle 处理下载代理请求
func DownloadProxyHandle(c *gin.Context) {
key := c.Query("key")
if key == "" || key != proto.Config.DOWNLOAD_PROXY_KEY {
c.JSON(http.StatusOK, gin.H{"code": proto.ParameterError, "message": "failed, key is null or error"})
}
// 获取URL参数
encodedURL := c.Param("url")
if encodedURL == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "URL参数不能为空", "code": proto.ParameterError, "message": "failed"})
return
}
// URL解码
decodedURL, err := url.QueryUnescape(encodedURL)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "URL解码失败: " + err.Error(), "code": proto.ParameterError, "message": "failed"})
return
}
// 验证URL格式
parsedURL, err := url.Parse(decodedURL)
if err != nil || parsedURL.Scheme == "" || parsedURL.Host == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的URL格式", "code": proto.ParameterError, "message": "failed"})
return
}
// 发起请求获取目标资源
resp, err := http.Get(decodedURL)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取资源失败: " + err.Error(), "code": proto.InternalServerError})
return
}
defer resp.Body.Close()
// 检查响应状态
if resp.StatusCode != http.StatusOK {
c.JSON(http.StatusBadGateway, gin.H{"error": "目标资源请求失败,状态码: " + resp.Status, "code": proto.InternalServerError})
return
}
// 获取文件名
filename := getFilenameFromURL(parsedURL)
// 设置响应头,告诉浏览器这是一个文件下载
c.Header("Content-Disposition", "attachment; filename="+url.QueryEscape(filename))
c.Header("Content-Type", resp.Header.Get("Content-Type"))
c.Header("Content-Length", resp.Header.Get("Content-Length"))
// 将响应体流式传输到客户端
_, err = io.Copy(c.Writer, resp.Body)
if err != nil {
// 已经开始传输数据后发生错误无法返回JSON只能记录日志
log.Println("tool download proxy handle error:", err)
}
}
// 从URL中提取文件名
func getFilenameFromURL(u *url.URL) string {
// 从路径中提取文件名
filename := filepath.Base(u.Path)
// 如果路径中没有文件名,尝试从查询参数中获取
if filename == "" || filename == "/" {
filename = "download_file"
}
return filename
}

View File

@ -100,6 +100,7 @@ type ConfigStruct struct {
MONITOR_SERVER_TOKEN string `json:"monitor_server_token"` // 监控服务器token,用于状态监控及邮件通知
APP_ID string `json:"app_id"` // 应用ID,用于标识不同应用
MONITOR_MAIL []StructValue `json:"monitor_mail"` // 设备监控邮件通知配置
DOWNLOAD_PROXY_KEY string `json:"download_proxy_key"` // 下载代理key
}
func WriteConfigToFile() {