mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-20 18:11:00 +00:00
fix(outbound): include tested outbound in HTTP probe config (#5120)
HTTP-pinging a subscription outbound always reported "Probe timed out". The frontend sends only the template outbounds as allOutbounds, but subscription outbounds are injected at runtime and aren't in that list, so burstObservatory had no outbound matching the tag to probe. Append the tested outbound when its tag is missing instead of only when allOutbounds is empty, so the probe always has a target while preserving the template outbounds that back dialerProxy chains.
This commit is contained in:
+20
-2
@@ -352,8 +352,14 @@ func (s *OutboundService) testOutboundHTTP(outboundJSON string, testURL string,
|
||||
return &TestOutboundResult{Mode: "http", Success: false, Error: fmt.Sprintf("Invalid allOutbounds JSON: %v", err)}, nil
|
||||
}
|
||||
}
|
||||
if len(allOutbounds) == 0 {
|
||||
allOutbounds = []any{testOutbound}
|
||||
// The outbound under test must be present in the config so burstObservatory
|
||||
// has something with outboundTag to probe. allOutbounds is the template's
|
||||
// outbounds (for dialerProxy chains); subscription outbounds are injected at
|
||||
// runtime and aren't part of it, so without this the probe targets a tag that
|
||||
// doesn't exist in the config and every test times out. Append (don't replace)
|
||||
// so manual outbounds' dialerProxy chains keep resolving.
|
||||
if !outboundsContainTag(allOutbounds, outboundTag) {
|
||||
allOutbounds = append(allOutbounds, testOutbound)
|
||||
}
|
||||
|
||||
metricsPort, err := findAvailablePort()
|
||||
@@ -396,6 +402,18 @@ func (s *OutboundService) testOutboundHTTP(outboundJSON string, testURL string,
|
||||
return pollObservatoryResult(testProcess, metricsPort, outboundTag, 12*time.Second), nil
|
||||
}
|
||||
|
||||
// outboundsContainTag reports whether any outbound in the slice has the given tag.
|
||||
func outboundsContainTag(outbounds []any, tag string) bool {
|
||||
for _, ob := range outbounds {
|
||||
if m, ok := ob.(map[string]any); ok {
|
||||
if t, _ := m["tag"].(string); t == tag {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// createTestConfig builds a probe-only xray config: the original outbounds
|
||||
// are kept as-is so dialerProxy chains still resolve, a burstObservatory
|
||||
// is wired to probe the target tag, and a metrics listener exposes the
|
||||
|
||||
Reference in New Issue
Block a user