fix: increase rate limit and add detailed logging to diagnose broken thumbnails
This commit is contained in:
@@ -31,16 +31,8 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
|
|||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
const retryAfter = Math.ceil((resetAt - Date.now()) / 1000);
|
const retryAfter = Math.ceil((resetAt - Date.now()) / 1000);
|
||||||
return NextResponse.json(
|
console.warn(`[Image API] ⚠️ Rate limit exceeded for IP: ${ip}. Retry after ${retryAfter}s`);
|
||||||
{ error: 'Too many requests' },
|
return NextResponse.json({ error: 'Too many requests' }, { status: 429 });
|
||||||
{
|
|
||||||
status: 429,
|
|
||||||
headers: {
|
|
||||||
'Retry-After': String(retryAfter),
|
|
||||||
'X-RateLimit-Remaining': '0',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { id: token } = await params;
|
const { id: token } = await params;
|
||||||
@@ -48,6 +40,7 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
|
|||||||
// Decode the opaque token back to an Immich asset ID
|
// Decode the opaque token back to an Immich asset ID
|
||||||
const assetId = decodeAssetId(token);
|
const assetId = decodeAssetId(token);
|
||||||
if (!assetId) {
|
if (!assetId) {
|
||||||
|
console.error(`[Image API] ❌ Invalid token: ${token.substring(0, 10)}...`);
|
||||||
return NextResponse.json({ error: 'Invalid token' }, { status: 400 });
|
return NextResponse.json({ error: 'Invalid token' }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,9 +60,12 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
|
|||||||
|
|
||||||
const result = await immich.streamAsset(assetId, size);
|
const result = await immich.streamAsset(assetId, size);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
console.error(`[Image API] ❌ Asset not found in Immich: ${assetId} (Size: ${size})`);
|
||||||
return NextResponse.json({ error: 'Asset not found' }, { status: 404 });
|
return NextResponse.json({ error: 'Asset not found' }, { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`[Image API] ✅ Serving ${assetId} (${size}) - Type: ${result.contentType}`);
|
||||||
|
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
'Content-Type': result.contentType,
|
'Content-Type': result.contentType,
|
||||||
// Images are immutable once uploaded to Immich — cache aggressively
|
// Images are immutable once uploaded to Immich — cache aggressively
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const envSchema = z.object({
|
|||||||
CACHE_TTL: z.coerce.number().int().min(0).default(300),
|
CACHE_TTL: z.coerce.number().int().min(0).default(300),
|
||||||
|
|
||||||
/** Rate limit: max requests per minute per IP */
|
/** Rate limit: max requests per minute per IP */
|
||||||
RATE_LIMIT_RPM: z.coerce.number().int().min(1).default(120),
|
RATE_LIMIT_RPM: z.coerce.number().int().min(1).default(600),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Secret used for signing auth cookies and encrypting asset tokens.
|
* Secret used for signing auth cookies and encrypting asset tokens.
|
||||||
|
|||||||
Reference in New Issue
Block a user