fixes
This commit is contained in:
1 parent
c8456f0fac
commit
bb2180f44b
4 files changed
+74
-146
No files matched your search
+51
-95
@@ -10,8 +10,6 @@
|
||||
input, button { margin-bottom: 10px; }
|
||||
#log { border: 1px solid #ccc; padding: 10px; max-height: 200px; overflow-y: auto; background: #f9f9f9; }
|
||||
</style>
|
||||
<!-- Including jsSHA library from CDN -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsSHA/3.2.0/sha256.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Загрузка и стриминг файла</h1>
|
||||
@@ -51,105 +49,63 @@
|
||||
logDiv.appendChild(p);
|
||||
}
|
||||
|
||||
// Compute SHA-256 hash of a file using jsSHA library (incremental reading)
|
||||
function computeSHA256(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunkSize = 2097152 * 10; // 2MB per chunk
|
||||
let offset = 0;
|
||||
const reader = new FileReader();
|
||||
const shaObj = new jsSHA("SHA-256", "ARRAYBUFFER");
|
||||
|
||||
reader.onload = function(e) {
|
||||
// Update hash with current chunk data
|
||||
shaObj.update(e.target.result);
|
||||
offset += chunkSize;
|
||||
appendLog(`Processed ${Math.min(offset, file.size)} из ${file.size} байт`);
|
||||
if (offset < file.size) {
|
||||
readNextChunk();
|
||||
} else {
|
||||
try {
|
||||
const hash = shaObj.getHash("HEX");
|
||||
resolve(hash);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
reader.onerror = function(err) {
|
||||
reject(err);
|
||||
};
|
||||
|
||||
function readNextChunk() {
|
||||
const slice = file.slice(offset, offset + chunkSize);
|
||||
reader.readAsArrayBuffer(slice);
|
||||
}
|
||||
|
||||
readNextChunk();
|
||||
});
|
||||
}
|
||||
|
||||
// Upload file in chunks (max 80 MB per chunk)
|
||||
// Upload file in chunks (max 80 MB per chunk) without computing file hash
|
||||
async function uploadFileInChunks(file) {
|
||||
const maxChunkSize = 80 * 1024 * 1024; // 80 MB
|
||||
let offset = 0;
|
||||
let uploadId = null;
|
||||
try {
|
||||
appendLog("Starting hash computation...");
|
||||
const hashHex = await computeSHA256(file);
|
||||
appendLog(`Computed SHA-256 hash: ${hashHex}`);
|
||||
appendLog("Starting file upload...");
|
||||
|
||||
while (offset < file.size) {
|
||||
const chunk = file.slice(offset, Math.min(offset + maxChunkSize, file.size));
|
||||
appendLog(`Uploading chunk starting at byte ${offset}`);
|
||||
|
||||
while (offset < file.size) {
|
||||
const chunk = file.slice(offset, Math.min(offset + maxChunkSize, file.size));
|
||||
appendLog(`Uploading chunk starting at byte ${offset}`);
|
||||
|
||||
// Prepare headers for the chunk upload
|
||||
const headers = {
|
||||
"X-Content-SHA256": hashHex,
|
||||
"X-File-Name": btoa(unescape(encodeURIComponent(file.name))), // File name in base64
|
||||
"X-Chunk-Start": offset.toString(),
|
||||
"Content-Type": file.type || "application/octet-stream"
|
||||
};
|
||||
if (uploadId) {
|
||||
headers["X-Upload-ID"] = uploadId;
|
||||
}
|
||||
|
||||
const response = await fetch(BASE_URL, {
|
||||
method: "POST",
|
||||
headers: headers,
|
||||
body: chunk
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
appendLog(`Chunk upload failed: ${errorData.error}`);
|
||||
throw new Error(`Upload failed at offset ${offset}: ${errorData.error}`);
|
||||
}
|
||||
|
||||
const resultData = await response.json();
|
||||
// Save uploadId from first response if not set
|
||||
if (!uploadId && resultData.upload_id) {
|
||||
uploadId = resultData.upload_id;
|
||||
}
|
||||
|
||||
// If final response contains content_id, upload is complete
|
||||
if (resultData.content_id) {
|
||||
appendLog(`Upload complete. File ID: ${resultData.content_id}`);
|
||||
return resultData;
|
||||
}
|
||||
|
||||
// Update offset based on server-reported current size
|
||||
if (resultData.current_size !== undefined) {
|
||||
offset = resultData.current_size;
|
||||
appendLog(`Server reports current_size: ${offset}`);
|
||||
} else {
|
||||
appendLog("Unexpected response from server, missing current_size.");
|
||||
throw new Error("Missing current_size in response");
|
||||
}
|
||||
// Prepare headers for the chunk upload
|
||||
const headers = {
|
||||
"X-File-Name": btoa(unescape(encodeURIComponent(file.name))), // File name in base64
|
||||
"X-Chunk-Start": offset.toString(),
|
||||
"Content-Type": file.type || "application/octet-stream"
|
||||
};
|
||||
if (uploadId) {
|
||||
headers["X-Upload-ID"] = uploadId;
|
||||
}
|
||||
// Set header to indicate the last chunk if this is the final part of the file
|
||||
if (offset + chunk.size >= file.size) {
|
||||
headers["X-Last-Chunk"] = "1";
|
||||
}
|
||||
|
||||
const response = await fetch(BASE_URL, {
|
||||
method: "POST",
|
||||
headers: headers,
|
||||
body: chunk
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
appendLog(`Chunk upload failed: ${errorData.error}`);
|
||||
throw new Error(`Upload failed at offset ${offset}: ${errorData.error}`);
|
||||
}
|
||||
|
||||
const resultData = await response.json();
|
||||
// Save uploadId from first response if not set
|
||||
if (!uploadId && resultData.upload_id) {
|
||||
uploadId = resultData.upload_id;
|
||||
}
|
||||
|
||||
// If final response contains content_id, upload is complete
|
||||
if (resultData.content_id) {
|
||||
appendLog(`Upload complete. File ID: ${resultData.content_id}`);
|
||||
return resultData;
|
||||
}
|
||||
|
||||
// Update offset based on server-reported current size
|
||||
if (resultData.current_size !== undefined) {
|
||||
offset = resultData.current_size;
|
||||
appendLog(`Server reports current_size: ${offset}`);
|
||||
} else {
|
||||
appendLog("Unexpected response from server, missing current_size.");
|
||||
throw new Error("Missing current_size in response");
|
||||
}
|
||||
} catch (err) {
|
||||
appendLog(`Error during upload: ${err}`);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user