Files
llama.cpp/tools/ui/src/lib/utils/api-headers.ts
T
Aleksander Grygier 4c0170dfc9 ui : route chat requests through protocol adapters
Assisted-by: pi:llama.cpp/DeepSeek-V4.1-Flash
2026-09-28 12:10:10 +02:00

94 lines
3.2 KiB
TypeScript

import { getBackend } from './api-base';
import { redactValue } from './redact';
import { CORS_PROXY, HEADERS } from '$lib/constants';
import { MimeTypeApplication } from '$lib/enums';
import { getProtocolAdapter } from '$lib/services/protocols';
import { settingsStore } from '$lib/stores/settings/index.svelte';
import type { Backend } from '$lib/types';
/**
* Get authorization headers for API requests to a backend.
*/
export function getAuthHeaders(backendId?: string): Record<string, string> {
const backend = getBackend(backendId);
if (backend) return getAuthHeadersForBackend(backend);
// no backends resolver yet (early startup, or a non-browser call): keep the
// pre-backends behaviour and authenticate against the serving origin
const apiKey = settingsStore.config.apiKey?.toString().trim();
return apiKey ? { [HEADERS.AUTHORIZATION]: `${HEADERS.BEARER}${apiKey}` } : {};
}
/**
* Get authorization headers for a backend object, including one that is not
* registered yet (used by the connection test on the add-backend form).
* The protocol adapter owns the credential scheme and any required headers.
*/
export function getAuthHeadersForBackend(backend: Backend): Record<string, string> {
return getProtocolAdapter(backend).authHeaders(backend);
}
/**
* Get standard JSON headers with optional authorization
*/
export function getJsonHeaders(backendId?: string): Record<string, string> {
return {
[HEADERS.CONTENT_TYPE]: MimeTypeApplication.JSON,
...getAuthHeaders(backendId)
};
}
/**
* Sanitize HTTP headers by redacting sensitive values.
* Known sensitive headers (from HEADERS.REDACTED) and any extra headers
* specified by the caller are fully redacted. Headers listed in
* `partialRedactHeaders` are partially redacted, showing only the
* specified number of trailing characters.
*
* @param headers - Headers to sanitize
* @param extraRedactedHeaders - Additional header names to fully redact
* @param partialRedactHeaders - Map of header name -> number of trailing chars to keep visible
* @returns Object with header names as keys and (possibly redacted) values
*/
export function sanitizeHeaders(
headers?: HeadersInit,
extraRedactedHeaders?: Iterable<string>,
partialRedactHeaders?: Map<string, number>
): Record<string, string> {
if (!headers) {
return {};
}
const normalized = new Headers(headers);
const sanitized: Record<string, string> = {};
const redactedHeaders = new Set(
Array.from(extraRedactedHeaders ?? [], (header) => header.toLowerCase())
);
for (const [key, value] of normalized.entries()) {
const normalizedKey = key.toLowerCase();
const unproxiedKey = normalizedKey.startsWith(CORS_PROXY.HEADER_PREFIX)
? normalizedKey.slice(CORS_PROXY.HEADER_PREFIX.length)
: normalizedKey;
const partialChars =
partialRedactHeaders?.get(normalizedKey) ?? partialRedactHeaders?.get(unproxiedKey);
if (partialChars !== undefined) {
sanitized[key] = redactValue(value, partialChars);
} else if (
HEADERS.REDACTED.has(normalizedKey) ||
HEADERS.REDACTED.has(unproxiedKey) ||
redactedHeaders.has(normalizedKey) ||
redactedHeaders.has(unproxiedKey)
) {
sanitized[key] = redactValue(value);
} else {
sanitized[key] = value;
}
}
return sanitized;
}