Skip to main content

HttpMetaCache

Manages HTTP metadata cache for efficient file downloads and validation. Class: HttpMetaCache
Header: launcher/net/HttpMetaCache.h
Inherits: QObject

Constructor

HttpMetaCache(QString path = QString());
path
QString
Path to the cache index file. If empty, cache is memory-only.

Cache Entry Management

getEntry(QString base, QString resource_path)
MetaEntryPtr
Retrieves an entry from cache without validation. Use only for specific caching needs.
resolveEntry(QString base, QString resource_path, QString expected_etag)
MetaEntryPtr
Gets an entry and verifies it isn’t stale. This is the recommended method for most use cases.
updateEntry(MetaEntryPtr stale_entry)
bool
Updates a previously resolved stale entry. Returns true on success.

Eviction

evictEntry(MetaEntryPtr entry)
bool
Removes a specific entry from the cache. Returns true on success.
evictAll()
bool
Clears all entries from the cache. Returns true on success.

Base Path Management

addBase(QString base, QString base_root)
void
Registers a base path for a cache category (e.g., “assets”, “libraries”).
getBasePath(QString base)
QString
Returns the root path for a registered base.

Persistence

Load()
void
Loads cache entries from the index file.
SaveNow()
void
Immediately saves cache entries to the index file.
SaveEventually()
void
Schedules a save operation to occur later (batched saves).

Example Usage

#include "net/HttpMetaCache.h"
#include "Application.h"

// Get the global cache
HttpMetaCache* cache = APPLICATION->metacache();

// Add a base path
cache->addBase("assets", "/path/to/assets");

// Resolve an entry (checks if cached file is still valid)
MetaEntryPtr entry = cache->resolveEntry(
    "assets",
    "minecraft/sounds/ambient/cave/cave1.ogg"
);

if (entry && !entry->isStale()) {
    qDebug() << "Using cached file:" << entry->getFullPath();
} else {
    qDebug() << "Need to download file";
    // After download:
    entry->setETag(response_etag);
    entry->setStale(false);
    cache->updateEntry(entry);
}

// Save cache
cache->SaveEventually();

MetaEntry

Represents a single cached file with metadata. Class: MetaEntry
Header: launcher/net/HttpMetaCache.h

Staleness

isStale()
bool
Returns true if the entry is stale and should be re-downloaded.
setStale(bool stale)
void
Marks the entry as stale or fresh.

File Path

getFullPath()
QString
Returns the full filesystem path to the cached file.

HTTP Validation

getETag()
QString
Returns the HTTP ETag for cache validation.
setETag(QString etag)
void
Sets the HTTP ETag.
getMD5Sum()
QString
Returns the MD5 checksum of the file.
setMD5Sum(QString md5sum)
void
Sets the MD5 checksum.

Timestamps

getRemoteChangedTimestamp()
QString
Returns the remote file’s last modified timestamp (RFC 2822 format).
setRemoteChangedTimestamp(QString timestamp)
void
Sets the remote changed timestamp.
setLocalChangedTimestamp(qint64 timestamp)
void
Sets the local file’s changed timestamp.

Cache Expiration

getCurrentAge()
qint64
Returns the current age of the cached entry.
setCurrentAge(qint64 age)
void
Sets the current age.
getMaximumAge()
qint64
Returns the maximum age before expiration.
setMaximumAge(qint64 age)
void
Sets the maximum age.
isExpired(qint64 offset)
bool
Returns true if the entry has expired (accounting for offset).
makeEternal(bool eternal)
void
Makes the entry never expire (eternal = true) or expire normally (eternal = false).
isEternal()
bool
Returns true if the entry never expires.

NetJob

Manages concurrent network operations (downloads, uploads). Class: NetJob
Header: launcher/net/NetJob.h
Inherits: ConcurrentTask

Constructor

explicit NetJob(
    QString job_name,
    QNetworkAccessManager* network,
    int max_concurrent = -1
);
job_name
QString
Human-readable name for the job.
network
QNetworkAccessManager*
Network manager to use for requests.
max_concurrent
int
Maximum concurrent requests (-1 for unlimited).

Adding Actions

addNetAction(Net::NetRequest::Ptr action)
bool
Adds a network request to the job. Returns true on success.
size()
int
Returns the number of network actions in the job.

Failure Handling

getFailedActions()
QList<Net::NetRequest*>
Returns list of failed network requests.
getFailedFiles()
QList<QString>
Returns list of file paths that failed to download.
setAskRetry(bool askRetry)
void
Sets whether to prompt the user to retry failed downloads.

Control

abort()
bool
Aborts the network job. Returns true if successful.
canAbort()
bool
Returns true if the job can be aborted.

Example Usage

#include "net/NetJob.h"
#include "net/Download.h"
#include "Application.h"

// Create a network job
NetJob* job = new NetJob("Download assets", APPLICATION->network());

// Add downloads
for (const QString& url : urls) {
    auto dl = Net::Download::makeFile(
        QUrl(url),
        "/path/to/destination.jar"
    );
    job->addNetAction(dl);
}

// Connect signals
connect(job, &NetJob::succeeded, []() {
    qDebug() << "All downloads completed";
});

connect(job, &NetJob::failed, [job](QString reason) {
    qDebug() << "Job failed:" << reason;
    for (auto* failed : job->getFailedActions()) {
        qDebug() << "  Failed:" << failed->url().toString();
    }
});

connect(job, &NetJob::progress, [](qint64 current, qint64 total) {
    qDebug() << "Progress:" << current << "/" << total;
});

// Start the job
job->start();

Net::Download

Handles individual file downloads with caching support. Class: Net::Download
Namespace: Net
Header: launcher/net/Download.h
Inherits: Net::NetRequest

Factory Methods

static Download::Ptr makeCached(
    QUrl url,
    MetaEntryPtr entry,
    Options options = Option::NoOptions
);
Creates a download that uses the HTTP metadata cache.

Example Usage

#include "net/Download.h"
#include "net/NetJob.h"

// Download to file
auto dl = Net::Download::makeFile(
    QUrl("https://example.com/mod.jar"),
    "/path/to/mods/mod.jar"
);

// Download with caching
MetaEntryPtr entry = cache->resolveEntry("downloads", "mod.jar");
auto cached_dl = Net::Download::makeCached(
    QUrl("https://example.com/mod.jar"),
    entry
);

// Download to memory
auto [dl_mem, data] = Net::Download::makeByteArray(
    QUrl("https://example.com/api/version.json")
);

connect(dl_mem.get(), &Task::succeeded, [data]() {
    QJsonDocument doc = QJsonDocument::fromJson(*data);
    qDebug() << "JSON:" << doc.object();
});

// Add to job
NetJob* job = new NetJob("Downloads", network);
job->addNetAction(dl);
job->addNetAction(cached_dl);
job->addNetAction(dl_mem);
job->start();

Net::NetRequest

Base class for all network requests. Class: Net::NetRequest
Namespace: Net
Header: launcher/net/NetRequest.h
Inherits: Task

Options

enum class Option {
    NoOptions = 0,
    AcceptLocalFiles = 1,  // Allow file:// URLs
    MakeEternal = 2,       // Cache entry never expires
    AutoRetry = 4          // Auto-retry on HTTP 429
};
Q_DECLARE_FLAGS(Options, Option)

Configuration

setUrl(QUrl url)
void
Sets the request URL.
url()
QUrl
Returns the request URL.
setNetwork(QNetworkAccessManager* network)
void
Sets the network access manager.
addValidator(Validator* v)
void
Adds a validator to check the downloaded data.
addHeaderProxy(std::unique_ptr<Net::HeaderProxy> proxy)
void
Adds a header proxy for modifying request headers.

Auto-Retry

enableAutoRetry(bool enable)
void
Enables automatic retry on HTTP 429 (Too Many Requests) errors.

Response Information

replyStatusCode()
int
Returns the HTTP status code.
error()
QNetworkReply::NetworkError
Returns the network error code.
errorString()
QString
Returns the error description.

Control

abort()
bool
Aborts the request. Returns true on success.
canAbort()
bool
Returns true if the request can be aborted.

Example Usage

#include "net/NetRequest.h"
#include "net/Download.h"

auto dl = Net::Download::makeFile(
    QUrl("https://api.example.com/data.json"),
    "/tmp/data.json",
    Net::NetRequest::Option::AutoRetry
);

// Enable auto-retry for rate limiting
dl->enableAutoRetry(true);

connect(dl.get(), &Task::succeeded, [dl]() {
    qDebug() << "Downloaded successfully";
    qDebug() << "Status code:" << dl->replyStatusCode();
});

connect(dl.get(), &Task::failed, [dl](QString reason) {
    qDebug() << "Download failed:" << reason;
    qDebug() << "Error:" << dl->errorString();
});

dl->start();

Common Patterns