fix(api): fixed POST request for API blocks (#392)

This commit is contained in:
Waleed Latif
2025-05-21 11:57:38 -07:00
committed by GitHub
parent b9b662bf6d
commit a94fd8703f
3 changed files with 111 additions and 7 deletions

View File

@@ -71,28 +71,43 @@ export async function GET(request: Request) {
return createErrorResponse("Missing 'url' parameter", 400)
}
// Extract custom headers from the request
const method = url.searchParams.get('method') || 'GET'
const bodyParam = url.searchParams.get('body')
let body: string | undefined = undefined
if (bodyParam && ['POST', 'PUT', 'PATCH'].includes(method.toUpperCase())) {
try {
body = decodeURIComponent(bodyParam)
} catch (error) {
logger.warn(`[${requestId}] Failed to decode body parameter`, error)
}
}
const customHeaders: Record<string, string> = {}
// 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
const headerName = key.substring(7)
customHeaders[headerName] = value
}
}
logger.info(`[${requestId}] Proxying GET request to: ${targetUrl}`)
logger.debug(`[${requestId}] Custom headers:`, customHeaders)
if (body && !customHeaders['Content-Type']) {
customHeaders['Content-Type'] = 'application/json'
}
logger.info(`[${requestId}] Proxying ${method} request to: ${targetUrl}`)
try {
// Forward the request to the target URL with all specified headers
const response = await fetch(targetUrl, {
method: 'GET',
method: method,
headers: {
...getProxyHeaders(),
...customHeaders,
},
body: body || undefined,
})
// Get response data

View File

@@ -452,5 +452,75 @@ describe('HTTP Request Tool', () => {
// Reset window
global.window = originalWindow
})
test('should include method parameter in proxy URL', () => {
const originalWindow = global.window
Object.defineProperty(global, 'window', {
value: {
location: {
origin: 'https://simstudio.ai',
},
},
writable: true,
})
const originalVitest = process.env.VITEST
try {
process.env.VITEST = undefined
const buildProxyUrl = (params: any) => {
const baseUrl = `https://external-api.com/endpoint`
let proxyUrl = `/api/proxy?url=${encodeURIComponent(baseUrl)}`
if (params.method) {
proxyUrl += `&method=${encodeURIComponent(params.method)}`
}
if (
params.body &&
['POST', 'PUT', 'PATCH'].includes(params.method?.toUpperCase() || '')
) {
const bodyStr =
typeof params.body === 'string' ? params.body : JSON.stringify(params.body)
proxyUrl += `&body=${encodeURIComponent(bodyStr)}`
}
return proxyUrl
}
const getParams = {
url: 'https://external-api.com/endpoint',
method: 'GET',
}
const getProxyUrl = buildProxyUrl(getParams)
expect(getProxyUrl).toContain('/api/proxy?url=')
expect(getProxyUrl).toContain('&method=GET')
const postParams = {
url: 'https://external-api.com/endpoint',
method: 'POST',
body: { key: 'value' },
}
const postProxyUrl = buildProxyUrl(postParams)
expect(postProxyUrl).toContain('/api/proxy?url=')
expect(postProxyUrl).toContain('&method=POST')
expect(postProxyUrl).toContain('&body=')
expect(postProxyUrl).toContain(encodeURIComponent('{"key":"value"}'))
const putParams = {
url: 'https://external-api.com/endpoint',
method: 'PUT',
body: 'string body',
}
const putProxyUrl = buildProxyUrl(putParams)
expect(putProxyUrl).toContain('/api/proxy?url=')
expect(putProxyUrl).toContain('&method=PUT')
expect(putProxyUrl).toContain(`&body=${encodeURIComponent('string body')}`)
} finally {
global.window = originalWindow
process.env.VITEST = originalVitest
}
})
})
})

View File

@@ -232,9 +232,18 @@ export const requestTool: ToolConfig<RequestParams, RequestResponse> = {
// Determine if we should use the proxy
if (shouldUseProxy(url)) {
// Route request through our proxy
let proxyUrl = `/api/proxy?url=${encodeURIComponent(url)}`
if (params.method) {
proxyUrl += `&method=${encodeURIComponent(params.method)}`
}
if (params.body && ['POST', 'PUT', 'PATCH'].includes(params.method?.toUpperCase() || '')) {
const bodyStr =
typeof params.body === 'string' ? params.body : JSON.stringify(params.body)
proxyUrl += `&body=${encodeURIComponent(bodyStr)}`
}
// Forward all headers as URL parameters
const userHeaders = transformTable(params.headers || null)
@@ -387,6 +396,16 @@ export const requestTool: ToolConfig<RequestParams, RequestResponse> = {
if (shouldUseProxy(processedUrl)) {
let proxyUrl = `/api/proxy?url=${encodeURIComponent(processedUrl)}`
if (params.method) {
proxyUrl += `&method=${encodeURIComponent(params.method)}`
}
if (params.body && ['POST', 'PUT', 'PATCH'].includes(params.method?.toUpperCase() || '')) {
const bodyStr =
typeof params.body === 'string' ? params.body : JSON.stringify(params.body)
proxyUrl += `&body=${encodeURIComponent(bodyStr)}`
}
// Forward all headers as URL parameters
const userHeaders = transformTable(params.headers || null)
for (const [key, value] of Object.entries(userHeaders)) {