From 5426314fd1bbcb6ecd0f330506753b63deddbb2a Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Tue, 22 Apr 2025 16:26:07 -0700 Subject: [PATCH] fix(api): add support custom headers in request --- sim/app/api/proxy/route.ts | 19 ++++++++++++++-- sim/tools/http/request.ts | 46 ++++++++++++++++++++++++++++++-------- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/sim/app/api/proxy/route.ts b/sim/app/api/proxy/route.ts index 515b7fa3ef..8326723cef 100644 --- a/sim/app/api/proxy/route.ts +++ b/sim/app/api/proxy/route.ts @@ -67,13 +67,28 @@ export async function GET(request: Request) { return createErrorResponse("Missing 'url' parameter", 400) } + // Extract custom headers from the request + const customHeaders: Record = {}; + + // Process all header.* parameters in the URL + for (const [key, value] of url.searchParams.entries()) { + if (key.startsWith('header.')) { + const headerName = key.substring(7); // Remove 'header.' prefix + customHeaders[headerName] = value; + } + } + logger.info(`[${requestId}] Proxying GET request to: ${targetUrl}`); + logger.debug(`[${requestId}] Custom headers:`, customHeaders); try { - // Forward the request to the target URL + // Forward the request to the target URL with all specified headers const response = await fetch(targetUrl, { method: 'GET', - headers: getProxyHeaders(), + headers: { + ...getProxyHeaders(), + ...customHeaders + }, }); // Get response data diff --git a/sim/tools/http/request.ts b/sim/tools/http/request.ts index 22f7764970..38ae727c98 100644 --- a/sim/tools/http/request.ts +++ b/sim/tools/http/request.ts @@ -78,13 +78,21 @@ const processUrl = (url: string, pathParams?: Record, queryParam // Handle query parameters if (queryParams) { const queryParamsObj = transformTable(queryParams) - const queryString = Object.entries(queryParamsObj) - .filter(([_, value]) => value !== undefined && value !== null) - .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`) - .join('&') - - if (queryString) { - url += (url.includes('?') ? '&' : '?') + queryString + + // Verify if URL already has query params to use proper separator + const separator = url.includes('?') ? '&' : '?' + + // Build query string manually to avoid double-encoding issues + const queryParts: string[] = [] + + for (const [key, value] of Object.entries(queryParamsObj)) { + if (value !== undefined && value !== null) { + queryParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`) + } + } + + if (queryParts.length > 0) { + url += separator + queryParts.join('&') } } @@ -217,7 +225,17 @@ export const requestTool: ToolConfig = { // Determine if we should use the proxy if (shouldUseProxy(url)) { // Route request through our proxy - const proxyUrl = `/api/proxy?url=${encodeURIComponent(url)}` + let proxyUrl = `/api/proxy?url=${encodeURIComponent(url)}` + + // Forward all headers as URL parameters + const userHeaders = transformTable(params.headers || null) + + // Add all custom headers as query parameters + for (const [key, value] of Object.entries(userHeaders)) { + if (value !== undefined && value !== null) { + proxyUrl += `&header.${encodeURIComponent(key)}=${encodeURIComponent(String(value))}` + } + } const response = await fetch(proxyUrl, { method: 'GET', @@ -359,7 +377,17 @@ export const requestTool: ToolConfig = { // For external URLs that need proxying if (shouldUseProxy(processedUrl)) { - return `/api/proxy?url=${encodeURIComponent(processedUrl)}` + let proxyUrl = `/api/proxy?url=${encodeURIComponent(processedUrl)}` + + // Forward all headers as URL parameters + const userHeaders = transformTable(params.headers || null) + for (const [key, value] of Object.entries(userHeaders)) { + if (value !== undefined && value !== null) { + proxyUrl += `&header.${encodeURIComponent(key)}=${encodeURIComponent(String(value))}` + } + } + + return proxyUrl } return processedUrl