1 #include "cachedhttp.h"
2 #include "localcache.h"
5 CachedHttpReply::CachedHttpReply(const QByteArray &body, const HttpRequest &req)
6 : bytes(body), req(req) {
7 QTimer::singleShot(0, this, SLOT(emitSignals()));
10 QByteArray CachedHttpReply::body() const {
14 void CachedHttpReply::emitSignals() {
20 WrappedHttpReply::WrappedHttpReply(CachedHttp &cachedHttp,
22 const QByteArray &key,
24 : HttpReply(httpReply), cachedHttp(cachedHttp), cache(cache), key(key), httpReply(httpReply) {
25 connect(httpReply, SIGNAL(data(QByteArray)), SIGNAL(data(QByteArray)));
26 connect(httpReply, SIGNAL(error(QString)), SIGNAL(error(QString)));
27 connect(httpReply, SIGNAL(finished(HttpReply)), SLOT(originFinished(HttpReply)));
30 void WrappedHttpReply::originFinished(const HttpReply &reply) {
31 qDebug() << reply.statusCode() << reply.url();
32 bool doCache = reply.isSuccessful();
35 const auto &validators = cachedHttp.getValidators();
36 if (!validators.isEmpty()) {
37 const QByteArray &mime = reply.header("Content-Type");
38 auto i = validators.constFind(mime);
39 if (i != validators.constEnd()) {
40 auto validator = i.value();
41 doCache = validator(reply);
43 i = validators.constFind("*");
44 if (i != validators.constEnd()) {
45 auto validator = i.value();
46 doCache = validator(reply);
53 cache->insert(key, reply.body());
55 qDebug() << "Not caching" << reply.statusCode() << reply.url();
60 CachedHttp::CachedHttp(Http &http, const char *name)
61 : http(http), cache(LocalCache::instance(name)), cachePostRequests(false) {}
63 void CachedHttp::setMaxSeconds(uint seconds) {
64 cache->setMaxSeconds(seconds);
67 void CachedHttp::setMaxSize(uint maxSize) {
68 cache->setMaxSize(maxSize);
71 HttpReply *CachedHttp::request(const HttpRequest &req) {
72 bool cacheable = req.operation == QNetworkAccessManager::GetOperation ||
73 (cachePostRequests && req.operation == QNetworkAccessManager::PostOperation);
75 qDebug() << "Not cacheable" << req.url;
76 return http.request(req);
78 const QByteArray key = requestHash(req);
79 const QByteArray value = cache->value(key);
80 if (!value.isNull()) {
81 qDebug() << "HIT" << key << req.url;
82 return new CachedHttpReply(value, req);
84 qDebug() << "MISS" << key << req.url;
85 return new WrappedHttpReply(*this, cache, key, http.request(req));
88 QByteArray CachedHttp::requestHash(const HttpRequest &req) {
93 s = (req.url.scheme() + sep + req.url.path() + sep + req.url.query()).toUtf8();
95 s = req.url.toEncoded();
97 s += sep + req.body + sep + QByteArray::number(req.offset);
98 if (req.operation == QNetworkAccessManager::PostOperation) {
102 return LocalCache::hash(s);