fix: web GUI upload Content-Type mismatch with presigned URL

Same fix as the Chrome extension — the web GUI's uploadHTTP() was using
item.file.type (browser-determined MIME) instead of presigned.contentType
(server-signed MIME). For broadcast formats like MXF, R3D, BRAW where
the browser returns empty or generic types, this causes an S3 signature
mismatch and the PUT fails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Zac Gaetano 2026-04-06 21:56:03 -04:00
parent 3b39803b49
commit 9e1e25ac97

View file

@ -1083,12 +1083,14 @@ async function uploadHTTP(files) {
try {
const presigned = await api('POST','/api/presigned',{filename:item.name,prefix:selectedPrefix,contentType:item.file.type||'application/octet-stream'});
if (!presigned.success) throw new Error(presigned.error||'Failed to get presigned URL');
// Use the content type the server signed — browser file.type may differ for broadcast formats
const signedType = presigned.contentType || item.file.type || 'application/octet-stream';
await new Promise((resolve,reject) => {
const xhr=new XMLHttpRequest();
xhr.open('PUT',presigned.url);
xhr.setRequestHeader('Content-Type',item.file.type||'application/octet-stream');
xhr.setRequestHeader('Content-Type',signedType);
xhr.upload.onprogress=e=>{ if(e.lengthComputable){ const p=Math.round(e.loaded/e.total*100); document.getElementById(`progbar-${idx}`).style.width=p+'%'; setFileStatus(idx,'uploading',p+'%'); } };
xhr.onload=()=>xhr.status<300?resolve():reject(new Error(`S3 ${xhr.status}`));
xhr.onload=()=>xhr.status<300?resolve():reject(new Error(`S3 error ${xhr.status}`));
xhr.onerror=()=>reject(new Error('Network error'));
xhr.send(item.file);
});