Source-candidate: poe d9a564e6d20f5f0fd75ce45b12cbbf8bb4c9d568\nSource-candidate: magica38ba5762b06716db1dee00d0afec162656488f5c\nValidated321whole-file phase plus whole bus1349/model-proxy100/webui490; final gate tooling checks pending, not landed.
22 lines
887 B
JavaScript
22 lines
887 B
JavaScript
import { validateHeaderValue } from 'node:http';
|
|
export class ProxyError extends Error {
|
|
constructor(code) { super(code); this.name = 'ProxyError'; this.code = code; }
|
|
}
|
|
export const refuse = code => { throw new ProxyError(code); };
|
|
|
|
export function validManagementKey(key) {
|
|
if (typeof key !== 'string' || !/^[\x21-\x7e]{1,4096}$/.test(key)) return false;
|
|
try { validateHeaderValue('Authorization', `Bearer ${key}`); return true; }
|
|
catch { return false; }
|
|
}
|
|
|
|
export function proxyTiming(value) {
|
|
const result = {};
|
|
for (const [field, max, code] of [['rotateGraceMinutes', 1440, 'proxy-rotate-grace-invalid'], ['firstOutputSeconds', 3600, 'proxy-first-output-invalid']]) {
|
|
if (!Object.hasOwn(value, field)) continue;
|
|
if (!Number.isInteger(value[field]) || value[field] < 1 || value[field] > max) refuse(code);
|
|
result[field] = value[field];
|
|
}
|
|
return result;
|
|
}
|