@@ -48,7 +48,29 @@ func GetOneFaviconURL(urlStr string) (string, error) {
4848
4949// 获取远程文件的大小
5050func GetRemoteFileSize (url string ) (int64 , error ) {
51- resp , err := http .Head (url )
51+ // 创建一个自定义的 HTTP 客户端
52+ client := & http.Client {
53+ Timeout : 10 * time .Second ,
54+ // 启用自动重定向
55+ CheckRedirect : func (req * http.Request , via []* http.Request ) error {
56+ return nil
57+ },
58+ }
59+
60+ // 创建请求
61+ req , err := http .NewRequest ("GET" , url , nil )
62+ if err != nil {
63+ return 0 , err
64+ }
65+
66+ // 添加浏览器模拟头信息
67+ req .Header .Set ("User-Agent" , "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" )
68+ req .Header .Set ("Accept" , "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8" )
69+ req .Header .Set ("Accept-Language" , "en-US,en;q=0.9" )
70+ req .Header .Set ("Connection" , "keep-alive" )
71+
72+ // 发送请求
73+ resp , err := client .Do (req )
5274 if err != nil {
5375 return 0 , err
5476 }
@@ -65,25 +87,28 @@ func GetRemoteFileSize(url string) (int64, error) {
6587
6688 // 获取Content-Length字段,即文件大小
6789 size := resp .ContentLength
90+
91+ // 如果服务器没有提供 Content-Length,尝试读取响应体来确定大小
92+ if size <= 0 {
93+ global .Logger .Infof ("Content-Length not provided for %s, using alternative method" , url )
94+ // 不实际读取整个响应体,因为我们已经有了连接,可以直接关闭
95+ return 0 , fmt .Errorf ("Content-Length not provided by server" )
96+ }
97+
6898 return size , nil
6999}
70100
71101// 下载图片
72102func DownloadImage (ctx context.Context , url string , storage storage.RcloneStorage ) (string , error ) {
73- // 获取远程文件大小
74- fileSize , err := GetRemoteFileSize ( url )
103+ // 创建请求
104+ req , err := http . NewRequest ( "GET" , url , nil )
75105 if err != nil {
76106 return "" , err
77107 }
78-
79- // 判断文件大小是否在阈值内(设置为 10MB)
80- maxSize := int64 (10 * 1024 * 1024 )
81- if fileSize > maxSize {
82- return "" , fmt .Errorf ("文件太大,不下载。大小:%d字节" , fileSize )
83- }
84-
85- // 发送HTTP GET请求获取图片数据
86- response , err := http .Get (url )
108+
109+ // 发送请求
110+ client := & http.Client {Timeout : 10 * time .Second }
111+ response , err := client .Do (req )
87112 if err != nil {
88113 return "" , err
89114 }
@@ -98,16 +123,23 @@ func DownloadImage(ctx context.Context, url string, storage storage.RcloneStorag
98123 return "" , fmt .Errorf ("HTTP request failed, status code: %d" , response .StatusCode )
99124 }
100125
126+ // 限制最大下载大小为 10MB
127+ limitedReader := http .MaxBytesReader (nil , response .Body , 10 * 1024 * 1024 )
128+
129+ // 生成文件名
101130 urlFileName := path .Base (url )
102131 fileExt := path .Ext (url )
103132 if fileExt == "" {
104133 fileExt = ".ico"
105134 }
106135 fileName := util .Md5 (fmt .Sprintf ("%s%s" , urlFileName , time .Now ().String ())) + fileExt
107136
108- // 使用 rclone 存储接口上传文件
109- filepath , err := storage .Upload (ctx , response . Body , fileName )
137+ // 上传文件
138+ filepath , err := storage .Upload (ctx , limitedReader , fileName )
110139 if err != nil {
140+ if strings .Contains (err .Error (), "request body too large" ) {
141+ return "" , fmt .Errorf ("文件太大,不下载" )
142+ }
111143 return "" , fmt .Errorf ("failed to upload file: %v" , err )
112144 }
113145
0 commit comments