mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 10:06:21 +00:00
fix(cli): localize remote assets before validate so it matches render (#2001)
validate served the composition over a loopback origin and let headless
Chrome fetch remote <img crossorigin>/@font-face assets cross-origin, while
the render pipeline downloads them to disk first. Buckets whose CORS
allowlist omits the loopback origin then failed the CORS-mode request with a
false net::ERR_FAILED that never occurs in the real render, pushing authors
(and agent pipelines) to delete crossorigin — which disables WebGL
color-grading/shaders for that asset.
Reuse producer's localizeRemote{Media,Image,FontFace}Sources in validate,
downloading into a temp dir served as an extra static-server asset root
(project dir untouched, cleaned up after). validate now matches render.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
89e36da13d
commit
906c8d04f8
@@ -71,7 +71,11 @@ export async function serveStaticProjectHtml(
|
||||
projectDir: string,
|
||||
html: string,
|
||||
bindErrorMessage = "Failed to bind local HTTP server",
|
||||
// Extra dirs to resolve non-index requests against, after projectDir (e.g. a
|
||||
// temp dir of localized remote assets).
|
||||
assetRoots: readonly string[] = [],
|
||||
): Promise<StaticProjectServer> {
|
||||
const roots = [projectDir, ...assetRoots];
|
||||
// fallow-ignore-next-line complexity
|
||||
const server = createServer((req, res) => {
|
||||
const url = req.url ?? "/";
|
||||
@@ -81,16 +85,15 @@ export async function serveStaticProjectHtml(
|
||||
return;
|
||||
}
|
||||
|
||||
const filePath = resolve(projectDir, decodeURIComponent(url).replace(/^\//, ""));
|
||||
const rel = relative(projectDir, filePath);
|
||||
if (rel.startsWith("..") || isAbsolute(rel)) {
|
||||
res.writeHead(403);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
if (existsSync(filePath)) {
|
||||
serveFileWithRange(filePath, req.headers.range, res);
|
||||
return;
|
||||
const requestPath = decodeURIComponent(url).replace(/^\//, "");
|
||||
for (const root of roots) {
|
||||
const filePath = resolve(root, requestPath);
|
||||
const rel = relative(root, filePath);
|
||||
if (rel.startsWith("..") || isAbsolute(rel)) continue; // traversal guard; try next root
|
||||
if (existsSync(filePath)) {
|
||||
serveFileWithRange(filePath, req.headers.range, res);
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.writeHead(404);
|
||||
res.end();
|
||||
|
||||
Reference in New Issue
Block a user