download_file
Downloads a file through a server-issued presigned URL and returns the final file bytes.
download_file requests a one-time download URL from the websocket API and then
downloads file bytes over HTTP.
Function variants
blaze::file download_file(std::string filename, blaze::resume_at from_where = blaze::resume_at{0});
blaze::file download_file(std::string filename, blaze::resume_at from_where, std::error_code& ec) noexcept;
void async_download_file(std::string filename, std::function<void(std::error_code, blaze::file)> callback);
void async_download_file(
std::string filename,
blaze::resume_at from_where,
std::function<void(std::error_code, blaze::file)> callback
);
blaze::coro::awaitable_result<blaze::file> co_download_file(
std::string filename,
blaze::resume_at from_where = blaze::resume_at{}
);Status vs error
file.status is the API/library result. std::error_code and
std::system_error are used for transport/runtime failures only.
Parameters
struct resume_at {
std::int64_t bytes_offset;
};Prop
Type
Result
struct file {
std::vector<std::byte> content;
std::string server_checksum;
blaze::status status{};
bool good() const noexcept;
bool bad_checksum() const noexcept;
};Prop
Type
Behavior notes
download_fileis a single-result operation in all API styles.- Internally the flow is: websocket request -> presigned URL response -> HTTP download.
- Resume mode (
bytes_offset > 0) sends HTTPRange: bytes=<offset>-. - Full-download checksum validation is automatic when server provides checksum metadata.
- Resumed downloads are not auto-validated as full-file integrity by the library.
Checksum behavior
For resume_at{0}, the library compares downloaded bytes hash with server
checksum (when checksum is provided). On mismatch it returns
blaze::status::file_checksum_mismatch.
For resume_at{N>0}, the library downloads the tail range and keeps the
server checksum in server_checksum, but does not perform full-file
checksum validation automatically.
Example
Compilation note
Synchronous and Asynchronous examples compile in the same form from C++17
to C++26.
#include "blazeauth/api/api.hpp"
#include <fstream>
#include <iostream>
#include <string>
#include <system_error>
#include <vector>
void print_error_code(const std::string& context, const std::error_code& ec) {
std::cout << context << ": " << ec.message() << " ("
<< ec.value() << " : " << ec.category().name() << ")\n";
}
bool write_file(const std::string& path, const std::vector<std::byte>& bytes) {
std::ofstream out(path, std::ios::binary);
if (!out) {
return false;
}
if (!bytes.empty()) {
out.write(reinterpret_cast<const char*>(bytes.data()), static_cast<std::streamsize>(bytes.size()));
}
return static_cast<bool>(out);
}
int main() {
blaze::session session;
try {
const blaze::api_server server = session.connect();
std::cout << "Connected: " << server.location << '\n';
const blaze::application app = session.initialize("your-websocket-api-key", "your-client-id");
if (!app.good()) {
std::cout << "Initialize status: " << blaze::to_string(app.status) << '\n';
return 1;
}
const blaze::license auth = session.authorize("your-license");
if (!auth.good()) {
std::cout << "Authorize status: " << blaze::to_string(auth.status) << '\n';
return 1;
}
const blaze::file file = session.download_file("client.dll");
if (!file.good()) {
std::cout << "Download status: " << blaze::to_string(file.status) << '\n';
return 1;
}
if (!write_file("client.dll", file.content)) {
std::cout << "Failed to write output file\n";
return 1;
}
std::cout << "Downloaded bytes: " << file.content.size() << '\n';
if (!file.server_checksum.empty()) {
std::cout << "Server checksum: " << file.server_checksum << '\n';
}
session.shutdown();
} catch (const std::system_error& e) {
print_error_code("download_file failed", e.code());
return 1;
}
return 0;
}#include "blazeauth/api/api.hpp"
#include <future>
#include <iostream>
#include <string>
#include <system_error>
void print_error_code(const std::string& context, const std::error_code& ec) {
std::cout << context << ": " << ec.message() << " ("
<< ec.value() << " : " << ec.category().name() << ")\n";
}
int main() {
blaze::session session;
std::promise<int> done;
auto result = done.get_future();
session.async_connect([&](std::error_code connect_ec, blaze::api_server) {
if (connect_ec) {
print_error_code("connect failed", connect_ec);
done.set_value(1);
return;
}
session.async_initialize("your-websocket-api-key", "your-client-id",
[&](std::error_code init_ec, blaze::application app) {
if (init_ec) {
print_error_code("initialize failed", init_ec);
done.set_value(1);
return;
}
if (!app.good()) {
std::cout << "Initialize status: " << blaze::to_string(app.status) << '\n';
done.set_value(1);
return;
}
session.async_download_file("client.dll", [&](std::error_code download_ec, blaze::file file) {
if (download_ec) {
print_error_code("download_file failed", download_ec);
done.set_value(1);
return;
}
if (!file.good()) {
std::cout << "Download status: " << blaze::to_string(file.status) << '\n';
done.set_value(1);
return;
}
std::cout << "Downloaded bytes: " << file.content.size() << '\n';
session.async_shutdown([&](std::error_code shutdown_ec) {
if (shutdown_ec) {
print_error_code("shutdown failed", shutdown_ec);
done.set_value(1);
return;
}
done.set_value(0);
});
});
});
});
return result.get();
}Project must be built with C++20 support and with coroutine support available both in the language mode and in the standard library implementation for this example to compile correctly.
#include "blazeauth/api/api.hpp"
#include <future>
#include <iostream>
#include <system_error>
void print_error_code(const std::string& context, const std::error_code& ec) {
std::cout << context << ": " << ec.message() << " ("
<< ec.value() << " : " << ec.category().name() << ")\n";
}
#if BLAZEAUTH_HAS_COROUTINES
blaze::coro::task<std::error_code> run(blaze::session& session) {
const auto [connect_ec, _server] = co_await session.co_connect();
if (connect_ec) {
co_return connect_ec;
}
const auto [init_ec, app] = co_await session.co_initialize("your-websocket-api-key", "your-client-id");
if (init_ec) {
co_return init_ec;
}
if (!app.good()) {
co_return blaze::make_error_code(app.status);
}
const auto [download_ec, file] = co_await session.co_download_file("client.dll");
if (download_ec) {
co_return download_ec;
}
if (!file.good()) {
co_return blaze::make_error_code(file.status);
}
std::cout << "Downloaded bytes: " << file.content.size() << '\n';
const auto [shutdown_ec] = co_await session.co_shutdown();
co_return shutdown_ec;
}
int main() {
blaze::session session;
std::promise<std::error_code> done;
auto result = done.get_future();
blaze::coro::co_spawn([&]() -> blaze::coro::task<void> {
done.set_value(co_await run(session));
co_return;
}());
const std::error_code ec = result.get();
if (ec) {
print_error_code("download_file failed", ec);
return 1;
}
return 0;
}
#else
int main() {
std::cout << "This example requires coroutine support in the Blazeauth library build.\n";
return 0;
}
#endifDownload-file statuses
| Value | Status | Returned when |
|---|---|---|
1 | ok | Download completed successfully. |
3 | not_authorized | Session is not authorized for file download. |
6 | internal_server_error | Server failed while preparing download data. |
300 | file_not_found | Requested file does not exist. |
301 | file_invalid_name | Filename is invalid (for example too short). |
302 | file_checksum_mismatch | Full-download checksum validation failed in the client library. |
303 | file_invalid_resume_offset | resume_at.bytes_offset is invalid for requested file. |
Connection-level shutdowns
Normal download-file results are returned in file.status. The websocket may
still be closed by session-level guards:
| Close code | Meaning | When it can happen |
|---|---|---|
4200 | not_initialized | download_file was called before a successful initialize. |
4201 | rate_limited | Session or IP rate limiting closed the websocket around this operation. |