]> git.sur5r.net Git - minitube/blob - lib/http/src/cachedhttp.cpp
New upstream version 3.1
[minitube] / lib / http / src / cachedhttp.cpp
1 #include "cachedhttp.h"
2 #include "localcache.h"
3
4 namespace {
5
6 QByteArray requestHash(const HttpRequest &req) {
7     const char sep = '|';
8     QByteArray s = req.url.toEncoded() + sep + req.body + sep + QByteArray::number(req.offset);
9     if (req.operation == QNetworkAccessManager::PostOperation) {
10         s.append(sep);
11         s.append("POST");
12     }
13     return LocalCache::hash(s);
14 }
15 } // namespace
16
17 CachedHttpReply::CachedHttpReply(const QByteArray &body, const HttpRequest &req)
18     : bytes(body), req(req) {
19     QTimer::singleShot(0, this, SLOT(emitSignals()));
20 }
21
22 QByteArray CachedHttpReply::body() const {
23     return bytes;
24 }
25
26 void CachedHttpReply::emitSignals() {
27     emit data(body());
28     emit finished(*this);
29     deleteLater();
30 }
31
32 WrappedHttpReply::WrappedHttpReply(LocalCache *cache, const QByteArray &key, HttpReply *httpReply)
33     : HttpReply(httpReply), cache(cache), key(key), httpReply(httpReply) {
34     connect(httpReply, SIGNAL(data(QByteArray)), SIGNAL(data(QByteArray)));
35     connect(httpReply, SIGNAL(error(QString)), SIGNAL(error(QString)));
36     connect(httpReply, SIGNAL(finished(HttpReply)), SLOT(originFinished(HttpReply)));
37 }
38
39 void WrappedHttpReply::originFinished(const HttpReply &reply) {
40     if (reply.isSuccessful()) cache->insert(key, reply.body());
41     emit finished(reply);
42 }
43
44 CachedHttp::CachedHttp(Http &http, const char *name)
45     : http(http), cache(LocalCache::instance(name)), cachePostRequests(false) {}
46
47 void CachedHttp::setMaxSeconds(uint seconds) {
48     cache->setMaxSeconds(seconds);
49 }
50
51 void CachedHttp::setMaxSize(uint maxSize) {
52     cache->setMaxSize(maxSize);
53 }
54
55 HttpReply *CachedHttp::request(const HttpRequest &req) {
56     bool cacheable = req.operation == QNetworkAccessManager::GetOperation ||
57                      (cachePostRequests && req.operation == QNetworkAccessManager::PostOperation);
58     if (!cacheable) {
59         qDebug() << "Not cacheable" << req.url;
60         return http.request(req);
61     }
62     const QByteArray key = requestHash(req);
63     const QByteArray value = cache->value(key);
64     if (!value.isNull()) {
65         qDebug() << "CachedHttp HIT" << req.url;
66         return new CachedHttpReply(value, req);
67     }
68     qDebug() << "CachedHttp MISS" << req.url.toString();
69     return new WrappedHttpReply(cache, key, http.request(req));
70 }