#include "localcache.h"
#include <QtNetwork>
-CachedHttpReply::CachedHttpReply(const QByteArray &body, const HttpRequest &req)
- : bytes(body), req(req) {
- QTimer::singleShot(0, this, SLOT(emitSignals()));
+CachedHttpReply::CachedHttpReply(const QByteArray &body, const QUrl &url, bool autoSignals)
+ : bytes(body), requestUrl(url) {
+ if (autoSignals) QTimer::singleShot(0, this, SLOT(emitSignals()));
}
QByteArray CachedHttpReply::body() const {
const QByteArray &key,
HttpReply *httpReply)
: HttpReply(httpReply), cachedHttp(cachedHttp), cache(cache), key(key), httpReply(httpReply) {
- connect(httpReply, SIGNAL(data(QByteArray)), SIGNAL(data(QByteArray)));
- connect(httpReply, SIGNAL(error(QString)), SIGNAL(error(QString)));
connect(httpReply, SIGNAL(finished(HttpReply)), SLOT(originFinished(HttpReply)));
}
void WrappedHttpReply::originFinished(const HttpReply &reply) {
qDebug() << reply.statusCode() << reply.url();
- bool doCache = reply.isSuccessful();
+ bool success = reply.isSuccessful();
+ if (!success) {
+ // Fallback to stale cached data on HTTP error
+ const QByteArray value = cache->possiblyStaleValue(key);
+ if (!value.isNull()) {
+ qDebug() << "Using stale cache value" << reply.url();
+ emit data(value);
+ auto replyFromCache = new CachedHttpReply(value, reply.url(), false);
+ emit finished(*replyFromCache);
+ replyFromCache->deleteLater();
+ return;
+ }
+ }
+ bool doCache = success;
if (doCache) {
const auto &validators = cachedHttp.getValidators();
if (!validators.isEmpty()) {
else
qDebug() << "Not caching" << reply.statusCode() << reply.url();
+ if (success) {
+ emit data(reply.body());
+ } else {
+ emit error(reply.reasonPhrase());
+ }
emit finished(reply);
}
const QByteArray value = cache->value(key);
if (!value.isNull()) {
qDebug() << "HIT" << key << req.url;
- return new CachedHttpReply(value, req);
+ return new CachedHttpReply(value, req.url);
}
qDebug() << "MISS" << key << req.url;
return new WrappedHttpReply(*this, cache, key, http.request(req));