From 5e5754fa6260eb20dcf18c6632472eb091a2ba9e Mon Sep 17 00:00:00 2001 From: Pallavi Date: Mon, 1 Sep 2025 21:22:18 +0530 Subject: [PATCH 1/2] preserve port and method on host change --- .../resources/[resourceId]/proxy/page.tsx | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx index ae831277..5ec16618 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx @@ -649,18 +649,29 @@ export default function ReverseProxyTargets(props: { defaultValue={row.original.ip} className="min-w-[150px]" onBlur={(e) => { - const parsed = parseHostTarget(e.target.value); - if (parsed) { - updateTarget(row.original.targetId, { - ...row.original, - method: parsed.protocol, - ip: parsed.host, - port: parsed.port - }); + const input = e.target.value.trim(); + const hasProtocol = /^https?:\/\//.test(input); + const hasPort = /:\d+/.test(input); + + if (hasProtocol || hasPort) { + const parsed = parseHostTarget(input); + if (parsed) { + updateTarget(row.original.targetId, { + ...row.original, + method: hasProtocol ? parsed.protocol : row.original.method, + ip: parsed.host, + port: hasPort ? parsed.port : row.original.port + }); + } else { + updateTarget(row.original.targetId, { + ...row.original, + ip: input + }); + } } else { updateTarget(row.original.targetId, { ...row.original, - ip: e.target.value + ip: input }); } }} @@ -961,11 +972,21 @@ export default function ReverseProxyTargets(props: { id="ip" {...field} onBlur={(e) => { - const parsed = parseHostTarget(e.target.value); - if (parsed) { - addTargetForm.setValue("method", parsed.protocol); - addTargetForm.setValue("ip", parsed.host); - addTargetForm.setValue("port", parsed.port); + const input = e.target.value.trim(); + const hasProtocol = /^https?:\/\//.test(input); + const hasPort = /:\d+/.test(input); + + if (hasProtocol || hasPort) { + const parsed = parseHostTarget(input); + if (parsed) { + if (hasProtocol || !addTargetForm.getValues("method")) { + addTargetForm.setValue("method", parsed.protocol); + } + addTargetForm.setValue("ip", parsed.host); + if (hasPort || !addTargetForm.getValues("port")) { + addTargetForm.setValue("port", parsed.port); + } + } } else { field.onBlur(); } From b670e6e3dcdf81e2ee92fb7fe9e494a29e291fed Mon Sep 17 00:00:00 2001 From: Pallavi Date: Mon, 1 Sep 2025 21:47:50 +0530 Subject: [PATCH 2/2] update parser to handle h2c --- .../resources/[resourceId]/proxy/page.tsx | 10 ++++----- src/lib/parseHostTarget.ts | 22 +++++++++++++++---- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx index 5ec16618..87c3dd13 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/proxy/page.tsx @@ -650,8 +650,8 @@ export default function ReverseProxyTargets(props: { className="min-w-[150px]" onBlur={(e) => { const input = e.target.value.trim(); - const hasProtocol = /^https?:\/\//.test(input); - const hasPort = /:\d+/.test(input); + const hasProtocol = /^(https?|h2c):\/\//.test(input); + const hasPort = /:\d+(?:\/|$)/.test(input); if (hasProtocol || hasPort) { const parsed = parseHostTarget(input); @@ -675,9 +675,7 @@ export default function ReverseProxyTargets(props: { }); } }} - /> - ) }, { @@ -973,8 +971,8 @@ export default function ReverseProxyTargets(props: { {...field} onBlur={(e) => { const input = e.target.value.trim(); - const hasProtocol = /^https?:\/\//.test(input); - const hasPort = /:\d+/.test(input); + const hasProtocol = /^(https?|h2c):\/\//.test(input); + const hasPort = /:\d+(?:\/|$)/.test(input); if (hasProtocol || hasPort) { const parsed = parseHostTarget(input); diff --git a/src/lib/parseHostTarget.ts b/src/lib/parseHostTarget.ts index c79c7aa3..b860f410 100644 --- a/src/lib/parseHostTarget.ts +++ b/src/lib/parseHostTarget.ts @@ -1,15 +1,29 @@ + export function parseHostTarget(input: string) { try { - const normalized = input.match(/^https?:\/\//) ? input : `http://${input}`; + const normalized = input.match(/^(https?|h2c):\/\//) ? input : `http://${input}`; const url = new URL(normalized); - const protocol = url.protocol.replace(":", ""); // http | https + const protocol = url.protocol.replace(":", ""); // http | https | h2c const host = url.hostname; - const port = url.port ? parseInt(url.port, 10) : protocol === "https" ? 443 : 80; + + let defaultPort: number; + switch (protocol) { + case "https": + defaultPort = 443; + break; + case "h2c": + defaultPort = 80; + break; + default: // http + defaultPort = 80; + break; + } + + const port = url.port ? parseInt(url.port, 10) : defaultPort; return { protocol, host, port }; } catch { return null; } } -