feat(proxy): serve local game assets from games root
This commit is contained in:
@@ -4,6 +4,8 @@ import sharp from 'sharp';
|
||||
import { createRequire } from 'module';
|
||||
import { traceRequestSchema, type TraceResult } from '@tts/shared';
|
||||
import { offsetShape, parseSvgShape } from './svgShape.js';
|
||||
import { resolveAsset } from './resolveAsset.js';
|
||||
import type { Bindings } from '../env.js';
|
||||
|
||||
// vtracer is a CommonJS package; load it via require so the wasm initializes
|
||||
// with the correct `__dirname`.
|
||||
@@ -17,7 +19,7 @@ const vtracer = require('@visioncortex/vtracer') as {
|
||||
): string;
|
||||
};
|
||||
|
||||
const app = new Hono();
|
||||
const app = new Hono<{ Bindings: Bindings }>();
|
||||
|
||||
/**
|
||||
* Trace an image into a vector shape and return it BSON-encoded.
|
||||
@@ -39,19 +41,29 @@ app.get('/', async (c) => {
|
||||
const { url, mode, threshold, format, simplify, maxColors, offset } =
|
||||
parsed.data;
|
||||
|
||||
// Only allow http(s) to avoid SSRF via file://, etc.
|
||||
const parsedUrl = new URL(url);
|
||||
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
|
||||
return c.json({ error: 'Only http(s) urls are allowed' }, 400);
|
||||
// Resolve the image: a relative path is a local game asset under GAMES_ROOT;
|
||||
// otherwise it must be an http(s) URL.
|
||||
const resolved = await resolveAsset(url, c.env?.GAMES_ROOT);
|
||||
if (!resolved.ok) {
|
||||
return c.json({ error: 'Invalid or missing image url' }, 400);
|
||||
}
|
||||
const asset = resolved.asset;
|
||||
|
||||
let image: Buffer;
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) {
|
||||
return c.json({ error: `Image responded ${res.status}` }, 502);
|
||||
if (asset.stream) {
|
||||
const chunks: Buffer[] = [];
|
||||
for await (const chunk of asset.stream) {
|
||||
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
||||
}
|
||||
image = Buffer.concat(chunks);
|
||||
} else {
|
||||
const res = await fetch(asset.url!);
|
||||
if (!res.ok) {
|
||||
return c.json({ error: `Image responded ${res.status}` }, 502);
|
||||
}
|
||||
image = Buffer.from(await res.arrayBuffer());
|
||||
}
|
||||
image = Buffer.from(await res.arrayBuffer());
|
||||
} catch (err) {
|
||||
return c.json({ error: `Failed to fetch image: ${String(err)}` }, 502);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user