ChatGPT-Next-Web/app/api/stability.ts

101 lines
2.6 KiB
TypeScript

import type { NextRequest } from 'next/server';
import { auth } from '@/app/api/auth';
import { getServerSideConfig } from '@/app/config/server';
import { ModelProvider, STABILITY_BASE_URL } from '@/app/constant';
import { NextResponse } from 'next/server';
export async function handle(
req: NextRequest,
{ params }: { params: { path: string[] } },
) {
console.log('[Stability] params ', params);
if (req.method === 'OPTIONS') {
return NextResponse.json({ body: 'OK' }, { status: 200 });
}
const controller = new AbortController();
const serverConfig = getServerSideConfig();
let baseUrl = serverConfig.stabilityUrl || STABILITY_BASE_URL;
if (!baseUrl.startsWith('http')) {
baseUrl = `https://${baseUrl}`;
}
if (baseUrl.endsWith('/')) {
baseUrl = baseUrl.slice(0, -1);
}
const path = `${req.nextUrl.pathname}`.replaceAll('/api/stability/', '');
console.log('[Stability Proxy] ', path);
console.log('[Stability Base Url]', baseUrl);
const timeoutId = setTimeout(
() => {
controller.abort();
},
10 * 60 * 1000,
);
const authResult = auth(req, ModelProvider.Stability);
if (authResult.error) {
return NextResponse.json(authResult, {
status: 401,
});
}
const bearToken = req.headers.get('Authorization') ?? '';
const token = bearToken.trim().replaceAll('Bearer ', '').trim();
const key = token || serverConfig.stabilityApiKey;
if (!key) {
return NextResponse.json(
{
error: true,
message: `missing STABILITY_API_KEY in server env vars`,
},
{
status: 401,
},
);
}
const fetchUrl = `${baseUrl}/${path}`;
console.log('[Stability Url] ', fetchUrl);
const fetchOptions: RequestInit = {
headers: {
'Content-Type': req.headers.get('Content-Type') || 'multipart/form-data',
'Accept': req.headers.get('Accept') || 'application/json',
'Authorization': `Bearer ${key}`,
},
method: req.method,
body: req.body,
// to fix #2485: https://stackoverflow.com/questions/55920957/cloudflare-worker-typeerror-one-time-use-body
redirect: 'manual',
// @ts-ignore
duplex: 'half',
signal: controller.signal,
};
try {
const res = await fetch(fetchUrl, fetchOptions);
// to prevent browser prompt for credentials
const newHeaders = new Headers(res.headers);
newHeaders.delete('www-authenticate');
// to disable nginx buffering
newHeaders.set('X-Accel-Buffering', 'no');
return new Response(res.body, {
status: res.status,
statusText: res.statusText,
headers: newHeaders,
});
} finally {
clearTimeout(timeoutId);
}
}