refactor(outbound): probe via xray burstObservatory instead of SOCKS round-trip

Replace the HTTP-mode outbound test that spun up a SOCKS inbound and
ran an httptrace'd request from the Go client with a probe-only xray
config: burstObservatory probes the target outbound directly and the
result is read from xray's /debug/vars metrics endpoint.

The probe lives inside xray, so the measured delay and failure
reasons reflect what xray itself sees over the real proxy chain.
Drops the DNS/Connect/TLS/TTFB breakdown (and statusCode) since the
observatory snapshot only exposes total delay; the frontend popover
is updated accordingly.
This commit is contained in:
MHSanaei
2026-05-27 04:53:13 +02:00
parent 3f787ae169
commit 31d7ed5103
3 changed files with 121 additions and 156 deletions
+2 -7
View File
@@ -101,10 +101,10 @@ function showSecurity(security?: string): boolean {
return security === 'tls' || security === 'reality';
}
function hasBreakdown(r: { endpoints?: unknown[]; ttfbMs?: number; tlsMs?: number; connectMs?: number; dnsMs?: number; statusCode?: number; error?: string } | null | undefined): boolean {
function hasBreakdown(r: { endpoints?: unknown[]; error?: string } | null | undefined): boolean {
if (!r) return false;
if (r.endpoints?.length) return true;
return !!(r.ttfbMs || r.tlsMs || r.connectMs || r.dnsMs || r.statusCode || r.error);
return !!r.error;
}
export default function OutboundsTab({
@@ -335,11 +335,6 @@ export default function OutboundsTab({
</div>
{hasBreakdown(r) && (
<>
{r.ttfbMs ? <div>TTFB: {r.ttfbMs} ms</div> : null}
{r.tlsMs ? <div>TLS: {r.tlsMs} ms</div> : null}
{r.connectMs ? <div>Connect: {r.connectMs} ms</div> : null}
{r.dnsMs ? <div>DNS: {r.dnsMs} ms</div> : null}
{r.statusCode ? <div>HTTP {r.statusCode}</div> : null}
{(r.endpoints || []).map((ep) => (
<div key={ep.address} className="endpoint-row">
<span className={ep.success ? 'dot-ok' : 'dot-fail'}></span>
-5
View File
@@ -54,11 +54,6 @@ export const OutboundTestResultSchema = z.object({
delay: z.number().optional(),
error: z.string().optional(),
mode: z.string().optional(),
ttfbMs: z.number().optional(),
tlsMs: z.number().optional(),
connectMs: z.number().optional(),
dnsMs: z.number().optional(),
statusCode: z.number().optional(),
endpoints: z
.array(
z.object({