Files
ProjectOctopus/agent-wdd/cmd/Download.go
zeaslity 8fc55e2e28 Enhance Download Functionality with Proxy and Progress Tracking
- Implemented advanced download utility with proxy support for SOCKS5 and HTTP protocols
- Added progress tracking with human-readable file size and download percentage
- Updated go.mod and go.sum to include new dependencies for proxy and networking
- Created flexible proxy client generation for different proxy types
- Improved error handling and logging in download process
2025-02-27 15:06:40 +08:00

122 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package cmd
import (
"agent-wdd/log"
"agent-wdd/utils"
"context"
"fmt"
"net"
"net/http"
"net/url"
"time"
"github.com/spf13/cobra"
"golang.org/x/net/proxy"
)
// 示例添加download子命令
func addDownloadSubcommands(cmd *cobra.Command) {
proxyCmd := &cobra.Command{
Use: "proxy [proxyUrl] [url] [dest]",
Short: "使用代理下载 支持socks5代理 http代理",
Args: cobra.ExactArgs(3),
Run: func(cmd *cobra.Command, args []string) {
proxyURL := args[0]
fileURL := args[1]
destPath := args[2]
log.Info("Downloading using proxy: %s -> from %s to %s\n", proxyURL, fileURL, destPath)
// 创建带代理的HTTP客户端
client, err := createProxyClient(proxyURL)
if err != nil {
log.Error("创建代理客户端失败: %v", err)
}
// 执行下载
downloadOk, resultLog := utils.DownloadFileWithClient(client, fileURL, destPath)
if !downloadOk {
log.Error("下载失败: %v", resultLog)
} else {
log.Info("文件下载完成")
}
},
}
cmd.Run = func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
log.Error("请输入下载地址")
return
} else if len(args) == 1 {
args = append(args, ".")
}
log.Info("Downloading without proxy: %s -> %s\n", args[0], args[1])
downloadOk, resultLog := utils.DownloadFile(args[0], args[1])
if !downloadOk {
log.Error("下载失败: %s", resultLog)
} else {
log.Info("下载成功: %s", args[1])
}
}
cmd.AddCommand(proxyCmd)
}
// 创建带代理的HTTP客户端
func createProxyClient(proxyURL string) (*http.Client, error) {
parsedURL, err := url.Parse(proxyURL)
if err != nil {
return nil, fmt.Errorf("无效的代理URL: %w", err)
}
switch parsedURL.Scheme {
case "socks5":
return createSocks5Client(parsedURL)
case "http", "https":
return createHTTPClient(parsedURL), nil
default:
return nil, fmt.Errorf("不支持的代理协议: %s", parsedURL.Scheme)
}
}
// 创建SOCKS5代理客户端
func createSocks5Client(proxyURL *url.URL) (*http.Client, error) {
var auth *proxy.Auth
if proxyURL.User != nil {
password, _ := proxyURL.User.Password()
auth = &proxy.Auth{
User: proxyURL.User.Username(),
Password: password,
}
}
dialer, err := proxy.SOCKS5("tcp", proxyURL.Host, auth, proxy.Direct)
if err != nil {
return nil, fmt.Errorf("创建SOCKS5拨号器失败: %w", err)
}
return &http.Client{
Transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.Dial(network, addr)
},
},
Timeout: 10 * time.Second,
}, nil
}
// 创建HTTP代理客户端
func createHTTPClient(proxyURL *url.URL) *http.Client {
return &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyURL),
},
Timeout: 30 * time.Minute,
}
}