Buy commercial curl support from WolfSSL. We help you work
out your issues, debug your libcurl applications, use the API, port to new
platforms, add new features and more. With a team lead by the curl founder
himself.
Continue Download C++ Implementation
- Contemporary messages sorted: [ by date ] [ by thread ] [ by subject ] [ by author ] [ by messages with attachments ]
From: Tomas Berger via curl-library <curl-library_at_cool.haxx.se>
Date: Tue, 8 Dec 2020 16:49:11 +0100
I have been trying to be able to continue a download from a half finished state, my write function is rather simple, but I have a couple of couts.
The idea is to download to a temporary file, and when the download is complete copy, and remove the tempfile
Relying on CURLOPT_RESUME_FROM_LARGE to help me continue from where I left of, with the size of what was downloaded before as its parameter
I also rewrite 2 bytes, so that my cout can make sure that the same offsets get the same bytes
struct DownloaderFile {
std::string filename;
std::fstream file;
uint64_t offset{0};
};
size_t serverToFile(char* buffer, size_t size, size_t nmemb, DownloaderFile* fileInfo) {
if (!fileInfo->file.is_open()) {
fileInfo->file.open(fileInfo->filename, std::ios::out | std::ios::binary);
if (!fileInfo->file.is_open()) {
return -1;
}
}
std::cout << "write to [" << fileInfo->offset << "] = " << (unsigned int)((uint8_t)buffer[0]) << "\n";
std::cout << "write to [" << fileInfo->offset + 1 << "] = " << (unsigned int)((uint8_t)buffer[1]) << "\n";
std::cout << "write to [" << fileInfo->offset + 2 << "] = " << (unsigned int)((uint8_t)buffer[2]) << "\n";
fileInfo->file.seekp(fileInfo->offset, std::ios::beg);
fileInfo->file.write(buffer, size * nmemb);
uint64_t actualWrite = static_cast<uint64_t>(fileInfo->file.tellp()) - fileInfo->offset;
fileInfo->offset += actualWrite;
std::cout << "write to [" << fileInfo->offset - 3 << "] = " << (unsigned int)((uint8_t)buffer[size * nmemb - 3]) << "\n";
std::cout << "write to [" << fileInfo->offset - 2 << "] = " << (unsigned int)((uint8_t)buffer[size * nmemb - 2]) << "\n";
std::cout << "write to [" << fileInfo->offset - 1 << "] = " << (unsigned int)((uint8_t)buffer[size * nmemb - 1]) << "\n";
std::cout << "left of to write in" << fileInfo->offset << "\n";
return actualWrite;
}
void downloadFile(CURL* curl) {
std::string filename = "file.zip";
std::string tempname = "file_TEMP";
DownloaderFile ftpfile;
ftpfile.filename = tempname;
setGenericCurlData(curl, filename);// set generic stuff, such as URL/username/password etc
if (fs::exists(tempdest) {
curl_off_t from = fs::file_size(tempdest, err) - 2; // -2 to just overwrite some byte so we can see it's correct in the output
ftpfile.offset = from;
curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, from);
}
// write to file
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, serverToFile);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
CURLcode res = curl_easy_perform(curl);
if (CURLE_OK == res) {
fs::copy_file(tempdest, filename, fs::copy_options::overwrite_existing);
fs::remove(tempdest);
std::cout << "succsess\n";
}
else {
std::cout << "failed\n";
}
}
Now the output i get before i cut the connection is:
write to [3719995] = 24
write to [3719996] = 65
write to [3719997] = 235
left of to write in 3719998
This means I wrote the byte 65 (converted to uint8 for readability) to offset 3719996 in the file etc
When trying to continue the download, it seems to work, it write over, the 2 bytes, with the same value at the same offsets
write to [3719996] = 65
write to [3719997] = 235
write to [3719998] = 102
But the zip file can not be unzipped, and their sha256 sum is different, so something went wrong.
I assume I might have made an logical error, but I can see where.
I hope you guys can help me see where I have gone wrong.
Thank you!
Tomas Berger
togtja_at_gmail.com (https://link.getmailspring.com/link/958B01AB-1826-4886-BEE5-062E99C25AE4_at_getmailspring.com/0?redirect=mailto%3Atogtja%40gmail.com&recipient=Y3VybC1saWJyYXJ5QGNvb2wuaGF4eC5zZQ%3D%3D)
-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.se/mail/etiquette.html
Received on 2020-12-08
Date: Tue, 8 Dec 2020 16:49:11 +0100
I have been trying to be able to continue a download from a half finished state, my write function is rather simple, but I have a couple of couts.
The idea is to download to a temporary file, and when the download is complete copy, and remove the tempfile
Relying on CURLOPT_RESUME_FROM_LARGE to help me continue from where I left of, with the size of what was downloaded before as its parameter
I also rewrite 2 bytes, so that my cout can make sure that the same offsets get the same bytes
struct DownloaderFile {
std::string filename;
std::fstream file;
uint64_t offset{0};
};
size_t serverToFile(char* buffer, size_t size, size_t nmemb, DownloaderFile* fileInfo) {
if (!fileInfo->file.is_open()) {
fileInfo->file.open(fileInfo->filename, std::ios::out | std::ios::binary);
if (!fileInfo->file.is_open()) {
return -1;
}
}
std::cout << "write to [" << fileInfo->offset << "] = " << (unsigned int)((uint8_t)buffer[0]) << "\n";
std::cout << "write to [" << fileInfo->offset + 1 << "] = " << (unsigned int)((uint8_t)buffer[1]) << "\n";
std::cout << "write to [" << fileInfo->offset + 2 << "] = " << (unsigned int)((uint8_t)buffer[2]) << "\n";
fileInfo->file.seekp(fileInfo->offset, std::ios::beg);
fileInfo->file.write(buffer, size * nmemb);
uint64_t actualWrite = static_cast<uint64_t>(fileInfo->file.tellp()) - fileInfo->offset;
fileInfo->offset += actualWrite;
std::cout << "write to [" << fileInfo->offset - 3 << "] = " << (unsigned int)((uint8_t)buffer[size * nmemb - 3]) << "\n";
std::cout << "write to [" << fileInfo->offset - 2 << "] = " << (unsigned int)((uint8_t)buffer[size * nmemb - 2]) << "\n";
std::cout << "write to [" << fileInfo->offset - 1 << "] = " << (unsigned int)((uint8_t)buffer[size * nmemb - 1]) << "\n";
std::cout << "left of to write in" << fileInfo->offset << "\n";
return actualWrite;
}
void downloadFile(CURL* curl) {
std::string filename = "file.zip";
std::string tempname = "file_TEMP";
DownloaderFile ftpfile;
ftpfile.filename = tempname;
setGenericCurlData(curl, filename);// set generic stuff, such as URL/username/password etc
if (fs::exists(tempdest) {
curl_off_t from = fs::file_size(tempdest, err) - 2; // -2 to just overwrite some byte so we can see it's correct in the output
ftpfile.offset = from;
curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, from);
}
// write to file
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, serverToFile);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
CURLcode res = curl_easy_perform(curl);
if (CURLE_OK == res) {
fs::copy_file(tempdest, filename, fs::copy_options::overwrite_existing);
fs::remove(tempdest);
std::cout << "succsess\n";
}
else {
std::cout << "failed\n";
}
}
Now the output i get before i cut the connection is:
write to [3719995] = 24
write to [3719996] = 65
write to [3719997] = 235
left of to write in 3719998
This means I wrote the byte 65 (converted to uint8 for readability) to offset 3719996 in the file etc
When trying to continue the download, it seems to work, it write over, the 2 bytes, with the same value at the same offsets
write to [3719996] = 65
write to [3719997] = 235
write to [3719998] = 102
But the zip file can not be unzipped, and their sha256 sum is different, so something went wrong.
I assume I might have made an logical error, but I can see where.
I hope you guys can help me see where I have gone wrong.
Thank you!
Tomas Berger
togtja_at_gmail.com (https://link.getmailspring.com/link/958B01AB-1826-4886-BEE5-062E99C25AE4_at_getmailspring.com/0?redirect=mailto%3Atogtja%40gmail.com&recipient=Y3VybC1saWJyYXJ5QGNvb2wuaGF4eC5zZQ%3D%3D)
-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.se/mail/etiquette.html
Received on 2020-12-08