server: wrap headers for mcp proxy (#21072)
* server: wrap headers for mcp proxy * Update tools/server/server-cors-proxy.h Co-authored-by: Georgi Gerganov <ggerganov@gmail.com> * fix build * chore: update webui build output * chore: update webui build output --------- Co-authored-by: Georgi Gerganov <ggerganov@gmail.com> Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>
This commit is contained in:
parent
7c203670f8
commit
abf9a62161
Binary file not shown.
|
|
@ -32,13 +32,22 @@ static server_http_res_ptr proxy_request(const server_http_req & req, std::strin
|
||||||
|
|
||||||
SRV_INF("proxying %s request to %s://%s:%i%s\n", method.c_str(), parsed_url.scheme.c_str(), parsed_url.host.c_str(), parsed_url.port, parsed_url.path.c_str());
|
SRV_INF("proxying %s request to %s://%s:%i%s\n", method.c_str(), parsed_url.scheme.c_str(), parsed_url.host.c_str(), parsed_url.port, parsed_url.path.c_str());
|
||||||
|
|
||||||
|
std::map<std::string, std::string> headers;
|
||||||
|
for (auto [key, value] : req.headers) {
|
||||||
|
auto new_key = key;
|
||||||
|
if (string_starts_with(new_key, "X-Proxy-Header-")) {
|
||||||
|
string_replace_all(new_key, "X-Proxy-Header-", "");
|
||||||
|
}
|
||||||
|
headers[new_key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
auto proxy = std::make_unique<server_http_proxy>(
|
auto proxy = std::make_unique<server_http_proxy>(
|
||||||
method,
|
method,
|
||||||
parsed_url.scheme,
|
parsed_url.scheme,
|
||||||
parsed_url.host,
|
parsed_url.host,
|
||||||
parsed_url.port,
|
parsed_url.port,
|
||||||
parsed_url.path,
|
parsed_url.path,
|
||||||
req.headers,
|
headers,
|
||||||
req.body,
|
req.body,
|
||||||
req.should_stop,
|
req.should_stop,
|
||||||
600, // timeout_read (default to 10 minutes)
|
600, // timeout_read (default to 10 minutes)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ using server_http_res_ptr = std::unique_ptr<server_http_res>;
|
||||||
|
|
||||||
struct server_http_req {
|
struct server_http_req {
|
||||||
std::map<std::string, std::string> params; // path_params + query_params
|
std::map<std::string, std::string> params; // path_params + query_params
|
||||||
std::map<std::string, std::string> headers; // reserved for future use
|
std::map<std::string, std::string> headers; // used by MCP proxy
|
||||||
std::string path;
|
std::string path;
|
||||||
std::string query_string; // query parameters string (e.g. "action=save")
|
std::string query_string; // query parameters string (e.g. "action=save")
|
||||||
std::string body;
|
std::string body;
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,13 @@ import type {
|
||||||
MCPResourceContent,
|
MCPResourceContent,
|
||||||
MCPReadResourceResult
|
MCPReadResourceResult
|
||||||
} from '$lib/types';
|
} from '$lib/types';
|
||||||
import { buildProxiedUrl, throwIfAborted, isAbortError, createBase64DataUrl } from '$lib/utils';
|
import {
|
||||||
|
buildProxiedUrl,
|
||||||
|
buildProxiedHeaders,
|
||||||
|
throwIfAborted,
|
||||||
|
isAbortError,
|
||||||
|
createBase64DataUrl
|
||||||
|
} from '$lib/utils';
|
||||||
|
|
||||||
interface ToolResultContentItem {
|
interface ToolResultContentItem {
|
||||||
type: string;
|
type: string;
|
||||||
|
|
@ -118,7 +124,7 @@ export class MCPService {
|
||||||
const requestInit: RequestInit = {};
|
const requestInit: RequestInit = {};
|
||||||
|
|
||||||
if (config.headers) {
|
if (config.headers) {
|
||||||
requestInit.headers = config.headers;
|
requestInit.headers = buildProxiedHeaders(config.headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.credentials) {
|
if (config.credentials) {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,21 @@ export function buildProxiedUrl(targetUrl: string): URL {
|
||||||
return proxyUrl;
|
return proxyUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap original headers for proxying through the CORS proxy. This avoids issues with duplicated llama.cpp-specific and target headers when using the CORS proxy.
|
||||||
|
* @param headers - The original headers to be proxied to target
|
||||||
|
* @returns List of "wrapped" headers to be sent to the CORS proxy
|
||||||
|
*/
|
||||||
|
export function buildProxiedHeaders(headers: Record<string, string>): Record<string, string> {
|
||||||
|
const proxiedHeaders: Record<string, string> = {};
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(headers)) {
|
||||||
|
proxiedHeaders[`X-Proxy-Header-${key}`] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return proxiedHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a proxied URL string for use in fetch requests.
|
* Get a proxied URL string for use in fetch requests.
|
||||||
* @param targetUrl - The original URL to proxy
|
* @param targetUrl - The original URL to proxy
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ export { highlightCode, detectIncompleteCodeBlock, type IncompleteCodeBlock } fr
|
||||||
export { setConfigValue, getConfigValue, configToParameterRecord } from './config-helpers';
|
export { setConfigValue, getConfigValue, configToParameterRecord } from './config-helpers';
|
||||||
|
|
||||||
// CORS Proxy
|
// CORS Proxy
|
||||||
export { buildProxiedUrl, getProxiedUrlString } from './cors-proxy';
|
export { buildProxiedUrl, getProxiedUrlString, buildProxiedHeaders } from './cors-proxy';
|
||||||
|
|
||||||
// Conversation utilities
|
// Conversation utilities
|
||||||
export { createMessageCountMap, getMessageCount } from './conversation-utils';
|
export { createMessageCountMap, getMessageCount } from './conversation-utils';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue