fix: ETag case mismatch in multipart upload complete route
api.js sends parts as { partNumber, ETag } (uppercase) but upload.js
was reading p.etag (lowercase), resulting in undefined ETag passed to
S3 CompleteMultipartUpload → InvalidPart error on all large file uploads.
Also handle both casings defensively.
This commit is contained in:
parent
17646c1155
commit
3154cce37c
1 changed files with 15 additions and 7 deletions
|
|
@ -83,6 +83,14 @@ async function syncToAmpp(assetId, projectId, binId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Derive a media_type string from a MIME type
|
||||||
|
function mediaTypeFromMime(mime = '') {
|
||||||
|
if (mime.startsWith('video')) return 'video';
|
||||||
|
if (mime.startsWith('audio')) return 'audio';
|
||||||
|
if (mime.startsWith('image')) return 'image';
|
||||||
|
return 'document';
|
||||||
|
}
|
||||||
|
|
||||||
// POST /api/v1/upload/init - Initialize a multipart upload
|
// POST /api/v1/upload/init - Initialize a multipart upload
|
||||||
router.post('/init', async (req, res, next) => {
|
router.post('/init', async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -106,9 +114,7 @@ router.post('/init', async (req, res, next) => {
|
||||||
VALUES ($1,$2,$3,$4,$4,'ingesting',$5,$6,$7,$8,NOW(),NOW())`,
|
VALUES ($1,$2,$3,$4,$4,'ingesting',$5,$6,$7,$8,NOW(),NOW())`,
|
||||||
[
|
[
|
||||||
assetId, projectId, binId || null, filename,
|
assetId, projectId, binId || null, filename,
|
||||||
contentType.startsWith('video') ? 'video'
|
mediaTypeFromMime(contentType),
|
||||||
: contentType.startsWith('audio') ? 'audio'
|
|
||||||
: contentType.startsWith('image') ? 'image' : 'document',
|
|
||||||
s3Key, fileSize,
|
s3Key, fileSize,
|
||||||
tagsArray.length > 0 ? tagsArray : null,
|
tagsArray.length > 0 ? tagsArray : null,
|
||||||
]
|
]
|
||||||
|
|
@ -179,7 +185,11 @@ router.post('/complete', async (req, res, next) => {
|
||||||
Key: key,
|
Key: key,
|
||||||
UploadId: uploadId,
|
UploadId: uploadId,
|
||||||
MultipartUpload: {
|
MultipartUpload: {
|
||||||
Parts: parts.map(p => ({ ETag: p.etag, PartNumber: p.partNumber })),
|
// Accept both casings: api.js sends ETag (uppercase), defend against both
|
||||||
|
Parts: parts.map(p => ({
|
||||||
|
ETag: p.ETag || p.etag,
|
||||||
|
PartNumber: p.partNumber || p.PartNumber,
|
||||||
|
})),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
@ -261,9 +271,7 @@ router.post('/simple', upload.single('file'), async (req, res, next) => {
|
||||||
VALUES ($1,$2,$3,$4,$4,'ingesting',$5,$6,$7,$8,NOW(),NOW())`,
|
VALUES ($1,$2,$3,$4,$4,'ingesting',$5,$6,$7,$8,NOW(),NOW())`,
|
||||||
[
|
[
|
||||||
assetId, projectId, binId || null, filename,
|
assetId, projectId, binId || null, filename,
|
||||||
mimeType.startsWith('video') ? 'video'
|
mediaTypeFromMime(mimeType),
|
||||||
: mimeType.startsWith('audio') ? 'audio'
|
|
||||||
: mimeType.startsWith('image') ? 'image' : 'document',
|
|
||||||
s3Key, req.file.size,
|
s3Key, req.file.size,
|
||||||
tagsArray.length > 0 ? tagsArray : null,
|
tagsArray.length > 0 ? tagsArray : null,
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue