refactor: 优化 HTTP 请求处理逻辑
- 改进了对重定向的处理,确保在 CheckRedirect 返回 ErrUseLastResponse 时能够正确处理响应。 - 移除了不必要的空行以提升代码可读性。 - 增强了错误处理逻辑,确保在没有响应的情况下返回适当的错误信息。
This commit is contained in:
@@ -44,12 +44,12 @@ func (t *timingTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
port = "80"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// DNS查询时间
|
||||
dnsStart := time.Now()
|
||||
ips, err := net.LookupIP(host)
|
||||
dnsTime := time.Since(dnsStart)
|
||||
|
||||
|
||||
t.mu.Lock()
|
||||
t.nameLookup = dnsTime
|
||||
if len(ips) > 0 {
|
||||
@@ -65,11 +65,11 @@ func (t *timingTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
}
|
||||
}
|
||||
t.mu.Unlock()
|
||||
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
// TCP连接时间(如果已知IP)
|
||||
var connectTime time.Duration
|
||||
if t.primaryIP != "" {
|
||||
@@ -80,13 +80,13 @@ func (t *timingTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
conn.Close()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 执行HTTP请求
|
||||
httpStart := time.Now()
|
||||
resp, err := t.transport.RoundTrip(req)
|
||||
httpTime := time.Since(httpStart)
|
||||
totalTime := time.Since(start)
|
||||
|
||||
|
||||
t.mu.Lock()
|
||||
if connectTime > 0 {
|
||||
t.connect = connectTime
|
||||
@@ -103,7 +103,7 @@ func (t *timingTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
}
|
||||
}
|
||||
t.mu.Unlock()
|
||||
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
@@ -139,17 +139,14 @@ func handleGet(c *gin.Context, urlStr string, params map[string]interface{}) {
|
||||
|
||||
// 创建自定义Transport用于时间跟踪
|
||||
timingTransport := newTimingTransport()
|
||||
|
||||
|
||||
// 创建HTTP客户端
|
||||
client := &http.Client{
|
||||
Transport: timingTransport,
|
||||
Timeout: 15 * time.Second,
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
// 跟随重定向,最多20次
|
||||
if len(via) >= 20 {
|
||||
return fmt.Errorf("重定向次数过多")
|
||||
}
|
||||
return nil
|
||||
// 不跟随重定向,返回第一个状态码和 header
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
|
||||
@@ -181,8 +178,11 @@ func handleGet(c *gin.Context, urlStr string, params map[string]interface{}) {
|
||||
// 执行请求
|
||||
startTime := time.Now()
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
// 错误处理
|
||||
|
||||
// 处理重定向错误:当 CheckRedirect 返回 ErrUseLastResponse 时,
|
||||
// client.Do 会返回响应和错误,但响应仍然有效(包含重定向状态码和 header)
|
||||
if err != nil && resp == nil {
|
||||
// 真正的错误,没有响应
|
||||
errMsg := err.Error()
|
||||
if strings.Contains(errMsg, "no such host") {
|
||||
result["ip"] = "域名无法解析"
|
||||
@@ -204,7 +204,24 @@ func handleGet(c *gin.Context, urlStr string, params map[string]interface{}) {
|
||||
c.JSON(200, result)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 如果有响应(包括重定向响应),继续处理
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
} else {
|
||||
// 没有响应也没有错误,不应该发生
|
||||
result["error"] = "未知错误"
|
||||
result["ip"] = "访问失败"
|
||||
result["totaltime"] = "*"
|
||||
result["downtime"] = "*"
|
||||
result["downsize"] = "*"
|
||||
result["downspeed"] = "*"
|
||||
result["firstbytetime"] = "*"
|
||||
result["conntime"] = "*"
|
||||
result["size"] = "*"
|
||||
c.JSON(200, result)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取时间信息
|
||||
timingTransport.mu.Lock()
|
||||
@@ -237,19 +254,19 @@ func handleGet(c *gin.Context, urlStr string, params map[string]interface{}) {
|
||||
bodyReader := io.LimitReader(resp.Body, 1024*1024) // 限制1MB
|
||||
bodyStartTime := time.Now()
|
||||
body, err := io.ReadAll(bodyReader)
|
||||
bodyReadTime := time.Now().Sub(bodyStartTime)
|
||||
bodyReadTime := time.Since(bodyStartTime)
|
||||
if err != nil && err != io.EOF {
|
||||
result["error"] = err.Error()
|
||||
}
|
||||
|
||||
downloadSize := int64(len(body))
|
||||
statusCode := resp.StatusCode
|
||||
|
||||
|
||||
// 如果首字节时间为0,使用连接时间
|
||||
if firstByteTime == 0 {
|
||||
firstByteTime = connectTime
|
||||
}
|
||||
|
||||
|
||||
// 总时间 = 实际请求时间
|
||||
if totalTime == 0 {
|
||||
totalTime = time.Since(startTime)
|
||||
@@ -327,16 +344,14 @@ func handlePost(c *gin.Context, urlStr string, params map[string]interface{}) {
|
||||
|
||||
// 创建自定义Transport用于时间跟踪
|
||||
timingTransport := newTimingTransport()
|
||||
|
||||
|
||||
// 创建HTTP客户端
|
||||
client := &http.Client{
|
||||
Transport: timingTransport,
|
||||
Timeout: 15 * time.Second,
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
if len(via) >= 20 {
|
||||
return fmt.Errorf("重定向次数过多")
|
||||
}
|
||||
return nil
|
||||
// 不跟随重定向,返回第一个状态码和 header
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
|
||||
@@ -363,7 +378,11 @@ func handlePost(c *gin.Context, urlStr string, params map[string]interface{}) {
|
||||
// 执行请求
|
||||
startTime := time.Now()
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
|
||||
// 处理重定向错误:当 CheckRedirect 返回 ErrUseLastResponse 时,
|
||||
// client.Do 会返回响应和错误,但响应仍然有效(包含重定向状态码和 header)
|
||||
if err != nil && resp == nil {
|
||||
// 真正的错误,没有响应
|
||||
errMsg := err.Error()
|
||||
if strings.Contains(errMsg, "no such host") {
|
||||
result["ip"] = "域名无法解析"
|
||||
@@ -385,7 +404,24 @@ func handlePost(c *gin.Context, urlStr string, params map[string]interface{}) {
|
||||
c.JSON(200, result)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 如果有响应(包括重定向响应),继续处理
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
} else {
|
||||
// 没有响应也没有错误,不应该发生
|
||||
result["error"] = "未知错误"
|
||||
result["ip"] = "访问失败"
|
||||
result["totaltime"] = "*"
|
||||
result["downtime"] = "*"
|
||||
result["downsize"] = "*"
|
||||
result["downspeed"] = "*"
|
||||
result["firstbytetime"] = "*"
|
||||
result["conntime"] = "*"
|
||||
result["size"] = "*"
|
||||
c.JSON(200, result)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取时间信息
|
||||
timingTransport.mu.Lock()
|
||||
@@ -425,12 +461,12 @@ func handlePost(c *gin.Context, urlStr string, params map[string]interface{}) {
|
||||
|
||||
downloadSize := int64(len(body))
|
||||
statusCode := resp.StatusCode
|
||||
|
||||
|
||||
// 如果首字节时间为0,使用连接时间
|
||||
if firstByteTime == 0 {
|
||||
firstByteTime = connectTime
|
||||
}
|
||||
|
||||
|
||||
// 总时间 = 实际请求时间
|
||||
if totalTime == 0 {
|
||||
totalTime = time.Since(startTime)
|
||||
|
||||
Reference in New Issue
Block a user