浏览代码

修复 调试模式下因重定向后的地址出错导致下载测速失败时输出的最终地址不准确的问题

xiu2 3 月之前
父节点
当前提交
397cfd25d3
共有 2 个文件被更改,包括 43 次插入19 次删除
  1. 14 12
      README.md
  2. 29 7
      task/download.go

+ 14 - 12
README.md

@@ -58,13 +58,13 @@ mkdir cfst
 cd cfst
 
 # 下载 CFST 压缩包(自行根据需求替换 URL 中 [版本号] 和 [文件名])
-wget -N https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.1/cfst_linux_amd64.tar.gz
+wget -N https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_amd64.tar.gz
 # 如果你是在国内网络环境中下载,那么请使用下面这几个镜像加速之一:
-# wget -N https://ghfast.top/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.1/cfst_linux_arm64.tar.gz
-# wget -N https://wget.la/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.1/cfst_linux_arm64.tar.gz
-# wget -N https://ghproxy.net/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.1/cfst_linux_arm64.tar.gz
-# wget -N https://gh-proxy.com/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.1/cfst_linux_arm64.tar.gz
-# wget -N https://hk.gh-proxy.com/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.1/cfst_linux_arm64.tar.gz
+# wget -N https://ghfast.top/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_arm64.tar.gz
+# wget -N https://wget.la/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_arm64.tar.gz
+# wget -N https://ghproxy.net/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_arm64.tar.gz
+# wget -N https://gh-proxy.com/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_arm64.tar.gz
+# wget -N https://hk.gh-proxy.com/https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.2/cfst_linux_arm64.tar.gz
 # 如果下载失败的话,尝试删除 -N 参数(如果是为了更新,则记得提前删除旧压缩包 rm cfst_linux_amd64.tar.gz )
 
 # 解压(不需要删除旧文件,会直接覆盖,自行根据需求替换 文件名)
@@ -703,6 +703,8 @@ cfst.exe -f 1.txt
 像这种直接提示 HTTP 状态码的,比较好判断,如 403 就是测速地址禁止你访问,404 就是测速地址找不到文件,具体可以搜索 HTTP 状态码含义
 3. `... context deadline exceeded (Client.Timeout exceeded while awaiting headers) ...`  
 这种一般是超时引起的,可能是 IP 等网络问题,也可能是 -dt 下载测速时间设置的太短了,当然默认的 10 秒到不至于超时
+4. `...tls: handshake failure...` 或 `...tls: failed to verify certificate...`  
+这种 TLS 握手失败/TLS 证书错误 代表下载测速地址和测速 IP 服务器不匹配,也就是 下载测速地址 与 测速 IP 其中一方有误(例如下载测速地址是托管在 Fastly CDN 的,但测速 IP 是 Cloudflare CDN 的,或者反过来,总之就是 IP 服务器告诉你这个网站域名它不认识并把你拒之门外)
 
 > 如果你遇到了其他报错原因,且翻译后还是不懂,可以发 Issues 或 Discussions 询问。
 
@@ -805,8 +807,8 @@ _**English language version of CFST (Text language differences only) [#64](https
 为了方便,我是在编译的时候将版本号写入代码中的 version 变量,因此你手动编译时,需要像下面这样在 `go build` 命令后面加上 `-ldflags` 参数来指定版本号:
 
 ```bash
-go build -ldflags "-s -w -X main.version=v2.3.3"
-# 在 CloudflareSpeedTest 目录中通过命令行(例如 CMD、Bat 脚本)运行该命令,即可编译一个可在和当前设备同样系统、位数、架构的环境下运行的二进制程序(Go 会自动检测你的系统位数、架构)且版本号为 v2.3.3
+go build -ldflags "-s -w -X main.version=v1.0.0"
+# 在 CloudflareSpeedTest 目录中通过命令行(例如 CMD、Bat 脚本)运行该命令,即可编译一个可在和当前设备同样系统、位数、架构的环境下运行的二进制程序(Go 会自动检测你的系统位数、架构)且版本号为 v1.0.0
 ```
 
 如果想要在 Windows 64位系统下编译**其他系统、架构、位数**,那么需要指定 **GOOS** 和 **GOARCH** 变量。
@@ -816,7 +818,7 @@ go build -ldflags "-s -w -X main.version=v2.3.3"
 ```bat
 SET GOOS=linux
 SET GOARCH=amd64
-go build -ldflags "-s -w -X main.version=v2.3.3"
+go build -ldflags "-s -w -X main.version=v1.0.0"
 ```
 
 例如在 Linux 系统下编译一个适用于 **Windows 系统 amd 架构 32 位**的二进制程序:
@@ -824,7 +826,7 @@ go build -ldflags "-s -w -X main.version=v2.3.3"
 ```bash
 GOOS=windows
 GOARCH=386
-go build -ldflags "-s -w -X main.version=v2.3.3"
+go build -ldflags "-s -w -X main.version=v1.0.0"
 ```
 
 > 可以运行 `go tool dist list` 来查看当前 Go 版本支持编译哪些组合。
@@ -836,7 +838,7 @@ go build -ldflags "-s -w -X main.version=v2.3.3"
 
 ```bat
 :: Windows 系统下是这样:
-SET version=v2.3.3
+SET version=v1.0.0
 SET GOOS=linux
 SET GOARCH=amd64
 go build -o Releases\cfst_linux_amd64\cfst -ldflags "-s -w -X main.version=%version%"
@@ -844,7 +846,7 @@ go build -o Releases\cfst_linux_amd64\cfst -ldflags "-s -w -X main.version=%vers
 
 ```bash
 # Linux 系统下是这样:
-version=v2.3.3
+version=v1.0.0
 GOOS=windows
 GOARCH=386
 go build -o Releases/cfst_windows_386/cfst.exe -ldflags "-s -w -X main.version=${version}"

+ 29 - 7
task/download.go

@@ -110,13 +110,38 @@ func getDialContext(ip *net.IPAddr) func(ctx context.Context, network, address s
 	}
 }
 
+// 统一的请求报错调试输出
+func printDownloadDebugInfo(ip *net.IPAddr, err error, statusCode int, url, lastRedirectURL string, response *http.Response) {
+	finalURL := url // 默认的最终 URL,这样当 response 为空时也能输出
+	if lastRedirectURL != "" {
+		finalURL = lastRedirectURL // 如果 lastRedirectURL 不是空,说明重定向过,优先输出最后一次要重定向至的目标
+	} else if response != nil && response.Request != nil && response.Request.URL != nil {
+		finalURL = response.Request.URL.String() // 如果 response 不为 nil,且 Request 和 URL 都不为 nil,则获取最后一次成功的响应地址
+	}
+	if url != finalURL { // 如果 URL 和最终地址不一致,说明有重定向,是该重定向后的地址引起的错误
+		if statusCode > 0 { // 如果状态码大于 0,说明是后续 HTTP 状态码引起的错误
+			fmt.Printf("\033[31m[调试] IP: %s, 下载测速终止,HTTP 状态码: %d, 下载测速地址: %s, 出错的重定向后地址: %s\033[0m\n", ip.String(), statusCode, url, finalURL)
+		} else {
+			fmt.Printf("\033[31m[调试] IP: %s, 下载测速失败,错误信息: %v, 下载测速地址: %s, 出错的重定向后地址: %s\033[0m\n", ip.String(), err, url, finalURL)
+		}
+	} else { // 如果 URL 和最终地址一致,说明没有重定向
+		if statusCode > 0 { // 如果状态码大于 0,说明是后续 HTTP 状态码引起的错误
+			fmt.Printf("\033[31m[调试] IP: %s, 下载测速终止,HTTP 状态码: %d, 下载测速地址: %s\033[0m\n", ip.String(), statusCode, url)
+		} else {
+			fmt.Printf("\033[31m[调试] IP: %s, 下载测速失败,错误信息: %v, 下载测速地址: %s\033[0m\n", ip.String(), err, url)
+		}
+	}
+}
+
 // return download Speed
 func downloadHandler(ip *net.IPAddr) (float64, string) {
+	var lastRedirectURL string // 用于记录最后一次重定向目标,以便在访问错误时输出
 	client := &http.Client{
 		Transport: &http.Transport{DialContext: getDialContext(ip)},
 		Timeout:   Timeout,
 		CheckRedirect: func(req *http.Request, via []*http.Request) error {
-			if len(via) > 10 { // 限制最多重定向 10 次
+			lastRedirectURL = req.URL.String() // 记录每次重定向的目标,以便在访问错误时输出
+			if len(via) > 10 {                 // 限制最多重定向 10 次
 				if utils.Debug { // 调试模式下,输出更多信息
 					fmt.Printf("\033[31m[调试] IP: %s, 下载测速地址重定向次数过多,终止测速,下载测速地址: %s\033[0m\n", ip.String(), req.URL.String())
 				}
@@ -141,21 +166,18 @@ func downloadHandler(ip *net.IPAddr) (float64, string) {
 	response, err := client.Do(req)
 	if err != nil {
 		if utils.Debug { // 调试模式下,输出更多信息
-			finalURL := URL                                                                // 默认的最终 URL,这样当 response 为空时也能输出
-			if response != nil && response.Request != nil && response.Request.URL != nil { // 如果 response 和 URL 存在,则获取最终 URL
-				finalURL = response.Request.URL.String()
-			}
-			fmt.Printf("\033[31m[调试] IP: %s, 下载测速失败,错误信息: %v, 下载测速地址: %s, 最终地址(如有重定向): %s\033[0m\n", ip.String(), err, URL, finalURL)
+			printDownloadDebugInfo(ip, err, 0, URL, lastRedirectURL, response)
 		}
 		return 0.0, ""
 	}
 	defer response.Body.Close()
 	if response.StatusCode != 200 {
 		if utils.Debug { // 调试模式下,输出更多信息
-			fmt.Printf("\033[31m[调试] IP: %s, 下载测速终止,HTTP 状态码: %d, 下载测速地址: %s, 最终地址(如有重定向): %s\033[0m\n", ip.String(), response.StatusCode, URL, response.Request.URL.String())
+			printDownloadDebugInfo(ip, nil, response.StatusCode, URL, lastRedirectURL, response)
 		}
 		return 0.0, ""
 	}
+
 	// 通过头部参数获取地区码
 	colo := getHeaderColo(response.Header)