From e9096eaca1cfd7bb855cb0c36e4cadf2b2b3956f Mon Sep 17 00:00:00 2001 From: Shreyas Date: Thu, 8 May 2025 15:29:08 +0530 Subject: [PATCH] fix(common): url and param encoding (#5041) --- .../src/helpers/functional/process-request.ts | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/hoppscotch-common/src/helpers/functional/process-request.ts b/packages/hoppscotch-common/src/helpers/functional/process-request.ts index f11f15fd..e4bf20c9 100644 --- a/packages/hoppscotch-common/src/helpers/functional/process-request.ts +++ b/packages/hoppscotch-common/src/helpers/functional/process-request.ts @@ -34,13 +34,29 @@ const processParams = (params: [string, string][]): [string, string][] => { const isEncodingRequired = encodeMode === "enable" || (encodeMode === "auto" && needsEncoding(value)) - const encodedKey = isEncodingRequired ? encodeParam(key) : key const encodedValue = isEncodingRequired ? encodeParam(value) : value - return [encodedKey, encodedValue] + return [key, encodedValue] }) } +const buildQueryString = (params: [string, string][]): string => + params.map(([k, v]) => `${encodeURIComponent(k)}=${v}`).join("&") + +const combineWithExistingSearch = (urlObj: URL, queryString: string): URL => { + const existingSearch = + urlObj.search.length > 1 ? urlObj.search.substring(1) : "" + + urlObj.search = pipe( + existingSearch, + O.fromPredicate((s) => s.length > 0), + O.map((s) => `${s}&${queryString}`), + O.getOrElse(() => queryString) + ) + + return urlObj +} + const updateUrl = ( url: string, params: [string, string][] @@ -50,10 +66,17 @@ const updateUrl = ( () => new URL(url), (e) => new Error(`Invalid URL: ${e}`) ), - E.map((u) => { - processParams(params).forEach(([k, v]) => u.searchParams.append(k, v)) - return decodeURIComponent(u.toString()) - }) + E.map((urlObj) => { + const processedParams = processParams(params) + + if (processedParams.length > 0) { + const queryString = buildQueryString(processedParams) + return combineWithExistingSearch(urlObj, queryString) + } + + return urlObj + }), + E.map((u) => u.toString()) ) export const preProcessRelayRequest = (req: RelayRequest): RelayRequest =>