From e62ad84bb712b3deca73ce61ed80f0fabb7ab9ef Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Tue, 26 May 2026 12:41:23 +0200 Subject: [PATCH] feat(frontend): symmetric TCP HTTP host/path + extra sockopt knobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OutboundFormModal: - Sockopt section gains 5 common-but-rarely-tweaked knobs: acceptProxyProtocol, tproxy (off/redirect/tproxy), tcpcongestion (bbr/cubic/reno), V6Only, tcpUserTimeout. The remaining sockopt fields (tcpKeepAliveIdle, tcpMaxSeg, tcpWindowClamp, trustedXForwardedFor) are still edit-via-JSON; they are deeply tunable and not commonly touched. InboundFormModal: - TCP HTTP camouflage gains host + path inputs symmetric to the outbound side. Switch ON seeds request with sensible defaults (version 1.1, method GET, path ['/'], empty headers). The two inputs use the same normalize/getValueProps comma-string ↔ string[] dance the outbound side uses, so the wire shape stays identical to what xray-core expects. --- .../src/pages/inbounds/InboundFormModal.tsx | 68 ++++++++++++++++++- frontend/src/pages/xray/OutboundFormModal.tsx | 44 ++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/inbounds/InboundFormModal.tsx b/frontend/src/pages/inbounds/InboundFormModal.tsx index 43df00bd..0704cade 100644 --- a/frontend/src/pages/inbounds/InboundFormModal.tsx +++ b/frontend/src/pages/inbounds/InboundFormModal.tsx @@ -1157,7 +1157,17 @@ export default function InboundFormModal({ onChange={(v) => { setFieldValue( ['streamSettings', 'tcpSettings', 'header'], - v ? { type: 'http' } : { type: 'none' }, + v + ? { + type: 'http', + request: { + version: '1.1', + method: 'GET', + path: ['/'], + headers: {}, + }, + } + : { type: 'none' }, ); }} /> @@ -1165,6 +1175,62 @@ export default function InboundFormModal({ }} + {/* Host + path camouflage inputs only render when the Switch + above is on. Both are string[] on the wire; normalize + + getValueProps translate to/from comma-joined input. Mirrors + the symmetric outbound side. */} + + prev.streamSettings?.tcpSettings?.header?.type + !== curr.streamSettings?.tcpSettings?.header?.type + } + > + {({ getFieldValue }) => { + const headerType = getFieldValue( + ['streamSettings', 'tcpSettings', 'header', 'type'], + ) as string | undefined; + if (headerType !== 'http') return null; + return ( + <> + + typeof v === 'string' + ? v.split(',').map((s) => s.trim()).filter(Boolean) + : Array.isArray(v) ? v : [] + } + getValueProps={(v: unknown) => ({ + value: Array.isArray(v) ? v.join(',') : '', + })} + > + + + + typeof v === 'string' + ? v.split(',').map((s) => s.trim()).filter(Boolean) + : Array.isArray(v) ? v : ['/'] + } + getValueProps={(v: unknown) => ({ + value: Array.isArray(v) ? v.join(',') : '/', + })} + > + + + + ); + }} + )} diff --git a/frontend/src/pages/xray/OutboundFormModal.tsx b/frontend/src/pages/xray/OutboundFormModal.tsx index fffd5e15..ef39ad24 100644 --- a/frontend/src/pages/xray/OutboundFormModal.tsx +++ b/frontend/src/pages/xray/OutboundFormModal.tsx @@ -38,6 +38,7 @@ import { OutboundDomainStrategies, OutboundProtocols as Protocols, SNIFFING_OPTION, + TCP_CONGESTION_OPTION, TLS_FLOW_CONTROL, USERS_SECURITY, UTLS_FINGERPRINT, @@ -1516,6 +1517,49 @@ export default function OutboundFormModal({ > + + ({ + value: v, + label: v, + }))} + /> + + + + + + + + + + )}