83 lines
2.5 KiB
JavaScript
83 lines
2.5 KiB
JavaScript
import path from "node:path";
|
|
import sharp from 'sharp';
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const session = await getUserSession(event);
|
|
const userFolder = getUserFolder(session);
|
|
|
|
const query = getQuery(event);
|
|
const q = new URLSearchParams(query);
|
|
if (userFolder) {
|
|
let subfolder = q.get('subfolder') || '';
|
|
subfolder = path.join(userFolder, subfolder);
|
|
q.set('subfolder', subfolder);
|
|
}
|
|
const filename = q.get('filename');
|
|
const dirName = path.dirname(filename);
|
|
const baseFileName = path.basename(filename);
|
|
|
|
if (dirName && dirName !== '.') {
|
|
const subfolder = q.get('subfolder') || '';
|
|
if (subfolder) {
|
|
q.set('subfolder', path.join(subfolder, dirName));
|
|
q.set('filename', baseFileName);
|
|
} else {
|
|
q.set('subfolder', dirName);
|
|
}
|
|
}
|
|
|
|
if (
|
|
!isPathNameOk(q.get('subfolder'))
|
|
|| !isPathNameOk(q.get('filename'))
|
|
|| !isPathNameOk(q.get('type'))
|
|
) {
|
|
const statusMessage = `Bad path name: ${q.toString()}`;
|
|
throw createError({
|
|
statusCode: 500,
|
|
statusMessage,
|
|
data: { ok: false, message: statusMessage }
|
|
});
|
|
}
|
|
|
|
const url = `${comfyUrl()}/view?${q.toString()}`;
|
|
const resp = await fetchComfy(url);
|
|
if (resp.status !== 200) {
|
|
const txt = await resp.text();
|
|
const statusMessage = `View failed: ${resp.status} ${resp.statusText}, ${txt}`;
|
|
console.error('error', statusMessage, txt, url);
|
|
throw createError({
|
|
statusCode: 500,
|
|
statusMessage,
|
|
data: { ok: false, message: statusMessage }
|
|
});
|
|
}
|
|
|
|
const blob = await resp.blob();
|
|
if (!blob.size) {
|
|
const statusMessage = `Blank image`;
|
|
throw createError({
|
|
statusCode: 500,
|
|
statusMessage,
|
|
data: { ok: false, message: statusMessage }
|
|
});
|
|
}
|
|
const width = parseInt(q.get('width'));
|
|
|
|
const expireAfterMs = 24 * 60 * 60 * 1000;
|
|
const expiresAt = new Date(Date.now() + expireAfterMs);
|
|
const disposition = q.has('download') ? 'download' : 'inline';
|
|
const headers = {
|
|
'Content-Disposition': `${disposition}; filename="${filename}"`,
|
|
'Expires': expiresAt.toUTCString(),
|
|
};
|
|
if (width) {
|
|
// set expires so we don't have to resize every time.
|
|
headers.Expires = new Date(Date.now() + 24 * 60 * 60 * 1000).toUTCString(), // 1 day
|
|
setResponseHeaders(event, headers);
|
|
return await sharp(await blob.arrayBuffer())
|
|
.resize(width, null, {withoutEnlargement: false}).webp().toBuffer();
|
|
}
|
|
setResponseHeaders(event, headers);
|
|
return blob;
|
|
});
|