mirror of
https://github.com/tiennm99/rplace.git
synced 2026-10-11 03:13:48 +00:00
fix: serve /api/canvas raw, drop manual gzip + add error envelope
Manual CompressionStream + Content-Encoding: gzip caused the browser to receive un-decoded gzipped bytes through the wrangler-dev + vite proxy path, surfacing as "Canvas buffer truncated: got 3598 bytes" in the new decoder bounds check. Cloudflare's edge auto-compresses compressible content already, so the manual gzip layer was redundant in prod and broken in dev. Also wraps getFullCanvas in try/catch and returns a JSON error envelope on failure instead of letting Hono's default handler return a 500 with text body the client decoder would mis-parse.
This commit is contained in:
1 parent
ad8d2a6f71
commit
a0c32b18ee
1 file changed
+15
-15
+15
-15
@@ -11,23 +11,23 @@ const app = new Hono();
|
|||||||
// ~64 bytes is generous per pixel JSON object {"x":2047,"y":2047,"color":31}
|
// ~64 bytes is generous per pixel JSON object {"x":2047,"y":2047,"color":31}
|
||||||
const MAX_BODY_BYTES = MAX_BATCH_SIZE * 64;
|
const MAX_BODY_BYTES = MAX_BATCH_SIZE * 64;
|
||||||
|
|
||||||
/** GET /api/canvas — full canvas as binary; gzip when supported */
|
/** GET /api/canvas — full canvas as binary.
|
||||||
|
* Cloudflare's edge auto-compresses compressible content; we don't set
|
||||||
|
* Content-Encoding manually (caused double-encoding / undecoded blobs
|
||||||
|
* through wrangler dev + vite proxy during testing). */
|
||||||
app.get('/api/canvas', async (c) => {
|
app.get('/api/canvas', async (c) => {
|
||||||
const buffer = await getFullCanvas(c.env);
|
try {
|
||||||
const acceptsGzip = (c.req.header('accept-encoding') || '').includes('gzip');
|
const buffer = await getFullCanvas(c.env);
|
||||||
|
return new Response(buffer, {
|
||||||
const headers = {
|
headers: {
|
||||||
'Content-Type': 'application/octet-stream',
|
'Content-Type': 'application/octet-stream',
|
||||||
'Cache-Control': 'public, max-age=10, s-maxage=10, stale-while-revalidate=30',
|
'Cache-Control': 'public, max-age=10, s-maxage=10, stale-while-revalidate=30',
|
||||||
Vary: 'Accept-Encoding',
|
},
|
||||||
};
|
});
|
||||||
|
} catch (err) {
|
||||||
if (acceptsGzip) {
|
console.error('Canvas read failed:', err);
|
||||||
const gzStream = new Response(buffer).body.pipeThrough(new CompressionStream('gzip'));
|
return c.json({ error: 'canvas_read_failed', message: String(err) }, 500);
|
||||||
headers['Content-Encoding'] = 'gzip';
|
|
||||||
return new Response(gzStream, { headers });
|
|
||||||
}
|
}
|
||||||
return new Response(buffer, { headers });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/** POST /api/place — batch pixel placement */
|
/** POST /api/place — batch pixel placement */
|
||||||
|
|||||||
Reference in new issue
Block a user