I’m trying to upload a file to cloudflare from an embedded device.
There a C++ application that generates a SHA-1 checksum before uploading the file
std::string generate_checksum(const std::string& file_path) {
std::string test_file_path = file_path;
std::ifstream file(test_file_path, std::ios::binary);
if (!file) {
throw std::runtime_error("Cannot open file for checksum.");
}
SHA_CTX sha1;
SHA1_Init(&sha1);
char buffer[8192];
while (file.read(buffer, sizeof(buffer))) {
SHA1_Update(&sha1, buffer, file.gcount());
}
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1_Final(hash, &sha1);
std::ostringstream result;
for (int i = 0; i < SHA_DIGEST_LENGTH; ++i) {
result << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(hash[i]);
}
return result.str();
}
The generated checksum is then stored in a database and the upload starts, Uploaded with santdard CURL settings (can prepare a code snippet if thats relevent?)
A worker processes the file upload and checks the checksum of the uploaded file against the checksum in the database
async function validateChecksum(fileContent, expectedChecksum) {
const sha1Buffer = await crypto.subtle.digest("SHA-1", fileContent);
const sha1Array = Array.from(new Uint8Array(sha1Buffer));
const computedChecksum = sha1Array.map(b => b.toString(16).padStart(2, '0')).join('');
return computedChecksum === expectedChecksum;
}
// handle upload method ...
const url = new URL(request.url);
const checksum = url.searchParams.get('checksum');
const uploadStream = await request.body;
const originalFileName = request.headers.get('X-Original-File-Name');
const uploadResponse = await env.STREAM_BUCKET.put(`some-folder/${originalFileName}`, uploadStream);
if (!uploadResponse) {
await updateTransferStatus(site_id, camera_id, "FAILURE", env);
return new Response(
JSON.stringify({ transfer_status: "FAILURE" }),
{ status: 500, headers: { 'Content-Type': 'application/json' } }
);
}
const uploadedFile = await env.STREAM_BUCKET.get(`${site_id}/${camera_id}/${originalFileName}`);
const fileContent = await uploadedFile.arrayBuffer();
const isChecksumValid = await validateChecksum(fileContent, checksum);
I was expecting the checksums to match but am brand new to this kind of task, what have I missed or not considered?
integrity is good; can download and open the file, the filenames are the same, the paths between client and cloud storage do differ but the filename is the same