mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-11 13:50:59 +00:00
feat(online): use xray online-stats API for onlines and access-log-free IP limit
Adopt xray-core's statsUserOnline policy and GetUsersStats RPC so online detection is connection-based and IP limiting no longer requires an access log. Falls back to the legacy traffic-delta onlines and access-log parsing when the running core lacks the RPCs (Unimplemented), probed lazily per process so a panel-driven version switch re-evaluates automatically. Backend: - xray/api.go: GetOnlineUsers (one GetUsersStats call returns all online users and their source IPs) and IsUnimplementedErr. - xray/process.go: per-process OnlineAPISupport tri-state capability cache. - service/xray.go: ensureStatsPolicy injects statsUserOnline into every policy level of the generated config; XrayService.GetOnlineUsers probes and falls back. - job/xray_traffic_job.go: union API onlines into the delta-derived active set; bump last_online for idle-but-connected clients. - job/check_client_ip_job.go: API-first IP source with shared enforcement; live observations bypass the 30-min stale cutoff; access-log path unchanged for older cores. - service/setting.go: GetIpLimitEnable always true; new accessLogEnable default for features that genuinely read the access log. Frontend: - Client form split into Basic and Config tabs; IP Limit and IP Log no longer gated on access log; compact Auto Renew next to Start After First Use; tabBasic/tabConfig added to all 13 locales. - Xray logs button on the dashboard now gated on accessLogEnable.
This commit is contained in:
@@ -53,8 +53,12 @@ func TestXrayAPI_E2E(t *testing.T) {
|
||||
map[string]any{"type": "field", "inboundTag": []string{"api"}, "outboundTag": "api"},
|
||||
},
|
||||
},
|
||||
"policy": map[string]any{},
|
||||
"stats": map[string]any{},
|
||||
"policy": map[string]any{
|
||||
"levels": map[string]any{
|
||||
"0": map[string]any{"statsUserOnline": true},
|
||||
},
|
||||
},
|
||||
"stats": map[string]any{},
|
||||
}
|
||||
cfgBytes, err := json.MarshalIndent(cfg, "", " ")
|
||||
if err != nil {
|
||||
@@ -130,6 +134,19 @@ func TestXrayAPI_E2E(t *testing.T) {
|
||||
t.Fatalf("missing inbound error not matched by IsMissingHandlerErr: %q", err)
|
||||
}
|
||||
|
||||
// --- online-stats API ---
|
||||
// statsUserOnline is enabled in the policy above; with no client
|
||||
// connections the call must succeed and return an empty set. This proves
|
||||
// the GetUsersStats plumbing against a real core (an older binary would
|
||||
// return Unimplemented here — see IsUnimplementedErr).
|
||||
online, err := api.GetOnlineUsers()
|
||||
if err != nil {
|
||||
t.Fatalf("GetOnlineUsers: %v", err)
|
||||
}
|
||||
if len(online) != 0 {
|
||||
t.Fatalf("expected no online users on an idle core, got %+v", online)
|
||||
}
|
||||
|
||||
// --- routing (rules + balancers replace) ---
|
||||
newRouting := []byte(`{
|
||||
"domainStrategy": "AsIs",
|
||||
|
||||
Reference in New Issue
Block a user