Skip to content

Commit f59a32a

Browse files
pawelniewieclaude
andcommitted
Fix direct upload: use MD5-base64 checksum and check PUT response
ActiveStorage (disk + S3) expects MD5-base64 checksums: - Disk service: ensure_integrity_of computes Digest::MD5.base64digest - S3/MinIO: presigned URL enforces content_md5 header Switching from SHA-256 hex to MD5 base64 fixes the integrity check. Also throw on non-2xx PUT responses so upload failures aren't silently swallowed before the PATCH confirmation is sent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 098bb2c commit f59a32a

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

src/import_session.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export class ImportSessionManager {
130130

131131
async #buildManifest(files) {
132132
return Promise.all(files.map(async (f) => {
133-
const checksum = await this.#sha256(f.fullPath)
133+
const checksum = await this.#md5Base64(f.fullPath)
134134
const ext = f.ext.slice(1)
135135
return {
136136
relative_path: f.relativePath,
@@ -167,11 +167,14 @@ export class ImportSessionManager {
167167

168168
async #uploadFile(entry, filePath, sessionId) {
169169
const fileBuffer = fs.readFileSync(filePath)
170-
await fetch(entry.direct_upload_url, {
170+
const uploadRes = await fetch(entry.direct_upload_url, {
171171
method: "PUT",
172172
headers: { "Content-Type": entry.content_type || "application/octet-stream" },
173173
body: fileBuffer
174174
})
175+
if (!uploadRes.ok) {
176+
throw new Error(`Upload failed for ${entry.relative_path}: HTTP ${uploadRes.status}`)
177+
}
175178
await this.client.markFileUploaded(sessionId, entry.id)
176179
}
177180

@@ -209,12 +212,12 @@ export class ImportSessionManager {
209212
return name.startsWith(".")
210213
}
211214

212-
async #sha256(filePath) {
215+
async #md5Base64(filePath) {
213216
return new Promise((resolve, reject) => {
214-
const hash = crypto.createHash("sha256")
217+
const hash = crypto.createHash("md5")
215218
const stream = fs.createReadStream(filePath)
216219
stream.on("data", d => hash.update(d))
217-
stream.on("end", () => resolve(hash.digest("hex")))
220+
stream.on("end", () => resolve(hash.digest("base64")))
218221
stream.on("error", reject)
219222
})
220223
}

0 commit comments

Comments
 (0)