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