mirror of
https://github.com/Nezumi-2711/next-gdrive-index.git
synced 2026-09-22 13:38:38 +00:00
Use /thumbnail endpoint and add long cache
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { z } from "zod";
|
||||
|
||||
import { decryptData } from "~/utils/encryptionHelper/hash";
|
||||
import gdrive from "~/utils/gdriveInstance";
|
||||
@@ -16,6 +17,14 @@ export async function GET(
|
||||
{ params: { encryptedId } }: Props,
|
||||
) {
|
||||
try {
|
||||
const searchParams = new URL(request.nextUrl).searchParams;
|
||||
const size = searchParams.get("size") || "512";
|
||||
|
||||
const validSize = z.coerce.number().safeParse(size);
|
||||
if (!validSize.success) {
|
||||
throw new Error("Invalid size");
|
||||
}
|
||||
|
||||
const defaultImage = NextResponse.redirect(
|
||||
new URL("/og.png", config.basePath),
|
||||
{
|
||||
@@ -23,86 +32,39 @@ export async function GET(
|
||||
},
|
||||
);
|
||||
const decryptedId = await decryptData(encryptedId);
|
||||
const _fileMeta = gdrive.files.get({
|
||||
|
||||
const fileMeta = await gdrive.files.get({
|
||||
fileId: decryptedId,
|
||||
fields:
|
||||
"id, name, mimeType, fileExtension, webContentLink, thumbnailLink",
|
||||
supportsAllDrives: config.apiConfig.isTeamDrive,
|
||||
});
|
||||
const _fileContent = gdrive.files.get(
|
||||
{
|
||||
fileId: decryptedId,
|
||||
alt: "media",
|
||||
supportsAllDrives: config.apiConfig.isTeamDrive,
|
||||
},
|
||||
{
|
||||
responseType: "stream",
|
||||
},
|
||||
);
|
||||
|
||||
const [fileMeta, fileContent] = await Promise.all([
|
||||
_fileMeta,
|
||||
_fileContent,
|
||||
]);
|
||||
const fileSize = Number(fileMeta.data.size || 0);
|
||||
|
||||
if (!fileMeta.data.webContentLink) return defaultImage;
|
||||
if (!fileMeta.data.thumbnailLink) return defaultImage;
|
||||
if (
|
||||
!fileMeta.data.mimeType?.startsWith("image") &&
|
||||
!fileMeta.data.mimeType?.startsWith("video")
|
||||
)
|
||||
return defaultImage;
|
||||
|
||||
// If svg, return actual image since there is no thumbnail for svg
|
||||
if (
|
||||
fileMeta.data.mimeType?.includes("svg") &&
|
||||
fileSize <= config.apiConfig.maxFileSize
|
||||
) {
|
||||
const fileBuffer = await new Promise<Buffer>((resolve, reject) => {
|
||||
const chunks: Buffer[] = [];
|
||||
fileContent.data.on("data", (chunk) => {
|
||||
chunks.push(chunk);
|
||||
});
|
||||
fileContent.data.on("end", () => {
|
||||
resolve(Buffer.concat(chunks));
|
||||
});
|
||||
fileContent.data.on("error", (err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
|
||||
return new NextResponse(fileBuffer, {
|
||||
headers: {
|
||||
"Cache-Control": "public, max-age=31536000, immutable",
|
||||
"Content-Type": fileMeta.data.mimeType || "application/octet-stream",
|
||||
"Content-Length": fileBuffer.length.toString(),
|
||||
"Content-Disposition": `attachment; filename="${encodeURIComponent(
|
||||
fileMeta.data.name || `Untitled.${fileMeta.data.fileExtension}`,
|
||||
)}"`,
|
||||
},
|
||||
});
|
||||
return defaultImage;
|
||||
}
|
||||
|
||||
if (config.apiConfig.proxyThumbnail) {
|
||||
const downloadThumb = await fetch(fileMeta.data.thumbnailLink, {
|
||||
cache: "force-cache",
|
||||
});
|
||||
const buffer = await downloadThumb.arrayBuffer();
|
||||
const url = `https://drive.google.com/thumbnail?id=${decryptedId}&sz=w${size}`;
|
||||
|
||||
return new NextResponse(buffer, {
|
||||
headers: {
|
||||
"Cache-Control": "public, max-age=31536000, immutable",
|
||||
"Content-Type": fileMeta.data.mimeType || "application/octet-stream",
|
||||
"Content-Length": buffer.byteLength.toString(),
|
||||
"Content-Disposition": `attachment; filename="${encodeURIComponent(
|
||||
fileMeta.data.name || `Untitled.${fileMeta.data.fileExtension}`,
|
||||
)}"`,
|
||||
},
|
||||
});
|
||||
if (!config.apiConfig.proxyThumbnail) {
|
||||
return NextResponse.redirect(url);
|
||||
}
|
||||
|
||||
return NextResponse.redirect(fileMeta.data.thumbnailLink);
|
||||
const downloadThumb = await fetch(url, {
|
||||
cache: "force-cache",
|
||||
});
|
||||
const buffer = await downloadThumb.arrayBuffer();
|
||||
|
||||
return new NextResponse(buffer, {
|
||||
headers: {
|
||||
"Cache-Control": "public, max-age=31536000, immutable",
|
||||
"Content-Type": "image/jpeg",
|
||||
"Content-Length": buffer.byteLength.toString(),
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
const e = error as Error;
|
||||
console.error(e.message);
|
||||
|
||||
Reference in New Issue
Block a user