tighten scan session and HTTP paths

This commit is contained in:
ZacharyZcR
2026-05-23 07:46:53 +08:00
parent 1a714f6a0c
commit 3c7823355d
7 changed files with 89 additions and 66 deletions
+23 -9
View File
@@ -28,8 +28,12 @@ func GetWebPortDetector() *WebPortDetector {
// 策略:TLS握手优先(快速且准确),失败后尝试GM TLS,最后HTTP
// 返回: "https", "https-gm", "http", 或 "" (都不是Web服务)
func DetectHTTPScheme(host string, port int, config *common.Config, session *common.ScanSession) string {
return DetectHTTPSchemeContext(context.Background(), host, port, config, session)
}
func DetectHTTPSchemeContext(ctx context.Context, host string, port int, config *common.Config, session *common.ScanSession) string {
// 优化:先快速检测 TCP 连通性
if !isPortReachable(host, port, config, session) {
if !isPortReachable(ctx, host, port, config, session) {
return ""
}
@@ -72,7 +76,13 @@ func DetectHTTPScheme(host string, port int, config *common.Config, session *com
// 使用HEAD请求(更轻量)
httpURL := fmt.Sprintf("http://%s", addr)
resp, err := client.Head(httpURL)
req, err := http.NewRequestWithContext(ctx, "HEAD", httpURL, nil)
if err != nil {
return ""
}
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
req.Header.Set("Accept", "*/*")
resp, err := session.HTTPDo(client, req)
if err == nil {
_ = resp.Body.Close()
return "http"
@@ -127,21 +137,25 @@ func createHTTPClient(config *common.Config, session *common.ScanSession) *http.
// DetectHTTPServiceOnly HTTP协议检测 - 保持API兼容,简化实现
func (w *WebPortDetector) DetectHTTPServiceOnly(host string, port int, config *common.Config, session *common.ScanSession) bool {
return w.DetectHTTPServiceOnlyContext(context.Background(), host, port, config, session)
}
func (w *WebPortDetector) DetectHTTPServiceOnlyContext(ctx context.Context, host string, port int, config *common.Config, session *common.ScanSession) bool {
// 优化:先快速检测 TCP 连通性,避免在不可达端口上浪费双倍超时时间
// 对于不存在的端口,这可以将检测时间从 2×timeout 减少到 1×timeout
if !isPortReachable(host, port, config, session) {
if !isPortReachable(ctx, host, port, config, session) {
return false
}
client := createHTTPClient(config, session)
// 尝试HTTP
if w.tryHTTP(client, session, host, port, "http") {
if w.tryHTTP(ctx, client, session, host, port, "http") {
return true
}
// 尝试HTTPS
if w.tryHTTP(client, session, host, port, "https") {
if w.tryHTTP(ctx, client, session, host, port, "https") {
return true
}
@@ -150,11 +164,11 @@ func (w *WebPortDetector) DetectHTTPServiceOnly(host string, port int, config *c
// isPortReachable 快速检测端口是否可达(TCP 连接测试)
// 用于在 HTTP/HTTPS 检测前过滤不可达端口,避免双重超时
func isPortReachable(host string, port int, config *common.Config, session *common.ScanSession) bool {
func isPortReachable(ctx context.Context, host string, port int, config *common.Config, session *common.ScanSession) bool {
timeout := config.Network.WebTimeout
addr := net.JoinHostPort(host, strconv.Itoa(port))
conn, err := session.DialTCP(context.Background(), "tcp", addr, timeout)
conn, err := session.DialTCP(ctx, "tcp", addr, timeout)
if err != nil {
return false
}
@@ -163,7 +177,7 @@ func isPortReachable(host string, port int, config *common.Config, session *comm
}
// tryHTTP 尝试HTTP请求 - 简化的核心逻辑
func (w *WebPortDetector) tryHTTP(client *http.Client, session *common.ScanSession, host string, port int, protocol string) bool {
func (w *WebPortDetector) tryHTTP(ctx context.Context, client *http.Client, session *common.ScanSession, host string, port int, protocol string) bool {
// 构造URL
var url string
if (port == 80 && protocol == "http") || (port == 443 && protocol == "https") {
@@ -173,7 +187,7 @@ func (w *WebPortDetector) tryHTTP(client *http.Client, session *common.ScanSessi
}
// 发送HEAD请求
req, err := http.NewRequest("HEAD", url, nil)
req, err := http.NewRequestWithContext(ctx, "HEAD", url, nil)
if err != nil {
return false
}