Skip to content

Commit 339cdb4

Browse files
committed
fix: 提升批量测IP并发与IP检查竞速
1 parent 2008a51 commit 339cdb4

11 files changed

Lines changed: 455 additions & 86 deletions

File tree

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ SINGBOX_BINARY=
3131
# CORS_ALLOWED_ORIGINS=https://panel.example.com,https://ops.example.com
3232
CORS_ALLOWED_ORIGINS=
3333

34+
# 批量测 IP 并发(前端批量请求并发数;留空使用默认值)
35+
SBPM_BATCH_CHECK_IP_CONCURRENCY=
36+
3437
# 登录限速(防暴力破解)
3538
LOGIN_RATE_LIMIT_WINDOW_SECONDS=60
3639
LOGIN_RATE_LIMIT_MAX_ATTEMPTS=10

backend/main.go

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,29 @@ const (
401401
indexCacheControlHeader = "no-cache, max-age=0, must-revalidate"
402402
)
403403

404+
func upsertIndexMetaTag(indexContent []byte, metaName string, metaTag string) []byte {
405+
metaMarker := []byte(fmt.Sprintf(`name="%s"`, metaName))
406+
updated := false
407+
408+
if idx := bytes.Index(indexContent, metaMarker); idx >= 0 {
409+
start := bytes.LastIndex(indexContent[:idx], []byte("<meta"))
410+
if start >= 0 {
411+
endRel := bytes.IndexByte(indexContent[idx:], '>')
412+
if endRel >= 0 {
413+
end := idx + endRel + 1
414+
indexContent = append(indexContent[:start], append([]byte(metaTag), indexContent[end:]...)...)
415+
updated = true
416+
}
417+
}
418+
}
419+
420+
if !updated && bytes.Contains(indexContent, []byte("</head>")) {
421+
indexContent = bytes.Replace(indexContent, []byte("</head>"), []byte(metaTag+"\n </head>"), 1)
422+
}
423+
424+
return indexContent
425+
}
426+
404427
func registerFrontendRoutes(r *gin.Engine, frontendDistDir string, appVersion string) error {
405428
assetsFS, sourceName, err := frontendAssetFS(frontendDistDir)
406429
if err != nil {
@@ -417,23 +440,22 @@ func registerFrontendRoutes(r *gin.Engine, frontendDistDir string, appVersion st
417440
log.Printf("Invalid SBPM_NODES_VIRTUAL_THRESHOLD=%d, using default 50", nodesVirtualThreshold)
418441
nodesVirtualThreshold = 50
419442
}
420-
metaName := []byte(`name="sbpm-nodes-virtual-threshold"`)
421-
meta := fmt.Sprintf(` <meta name="sbpm-nodes-virtual-threshold" content="%d" />`, nodesVirtualThreshold)
422-
thresholdUpdated := false
423-
if idx := bytes.Index(indexContent, metaName); idx >= 0 {
424-
start := bytes.LastIndex(indexContent[:idx], []byte("<meta"))
425-
if start >= 0 {
426-
endRel := bytes.IndexByte(indexContent[idx:], '>')
427-
if endRel >= 0 {
428-
end := idx + endRel + 1
429-
indexContent = append(indexContent[:start], append([]byte(meta), indexContent[end:]...)...)
430-
thresholdUpdated = true
431-
}
432-
}
433-
}
434-
if !thresholdUpdated && bytes.Contains(indexContent, []byte("</head>")) {
435-
indexContent = bytes.Replace(indexContent, []byte("</head>"), []byte(meta+"\n </head>"), 1)
436-
}
443+
nodesVirtualThresholdMeta := fmt.Sprintf(
444+
` <meta name="sbpm-nodes-virtual-threshold" content="%d" />`,
445+
nodesVirtualThreshold,
446+
)
447+
indexContent = upsertIndexMetaTag(indexContent, "sbpm-nodes-virtual-threshold", nodesVirtualThresholdMeta)
448+
449+
batchCheckIPConcurrency := readIntEnv("SBPM_BATCH_CHECK_IP_CONCURRENCY", 10)
450+
if batchCheckIPConcurrency < 1 {
451+
log.Printf("Invalid SBPM_BATCH_CHECK_IP_CONCURRENCY=%d, using default 10", batchCheckIPConcurrency)
452+
batchCheckIPConcurrency = 10
453+
}
454+
batchCheckIPConcurrencyMeta := fmt.Sprintf(
455+
` <meta name="sbpm-batch-check-ip-concurrency" content="%d" />`,
456+
batchCheckIPConcurrency,
457+
)
458+
indexContent = upsertIndexMetaTag(indexContent, "sbpm-batch-check-ip-concurrency", batchCheckIPConcurrencyMeta)
437459

438460
indexFingerprint := calcContentFingerprint(indexContent)
439461
indexETag := fmt.Sprintf("\"sbpm-%s\"", indexFingerprint)

backend/main_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,33 @@ func TestRegisterFrontendRoutesServesIndexWithRevalidateHeaders(t *testing.T) {
104104
}
105105
}
106106

107+
func TestRegisterFrontendRoutes_InjectsBatchCheckIPConcurrencyMeta(t *testing.T) {
108+
gin.SetMode(gin.TestMode)
109+
r := gin.New()
110+
distDir := writeTestFrontendDist(t)
111+
112+
t.Setenv("SBPM_BATCH_CHECK_IP_CONCURRENCY", "12")
113+
if err := registerFrontendRoutes(r, distDir, "1.2.4"); err != nil {
114+
t.Fatalf("register frontend routes: %v", err)
115+
}
116+
117+
req := httptest.NewRequest(http.MethodGet, "/", nil)
118+
rec := httptest.NewRecorder()
119+
r.ServeHTTP(rec, req)
120+
121+
if rec.Code != http.StatusOK {
122+
t.Fatalf("unexpected status: %d", rec.Code)
123+
}
124+
125+
body := rec.Body.String()
126+
if !strings.Contains(body, `name="sbpm-batch-check-ip-concurrency"`) {
127+
t.Fatalf("missing batch check ip concurrency meta: %s", body)
128+
}
129+
if !strings.Contains(body, `content="12"`) {
130+
t.Fatalf("missing batch check ip concurrency value: %s", body)
131+
}
132+
}
133+
107134
func TestRegisterFrontendRoutesServesAssetsWithImmutableCache(t *testing.T) {
108135
gin.SetMode(gin.TestMode)
109136
r := gin.New()

0 commit comments

Comments
 (0)