From 050b78f37874b573e9e59a353b857dc562639856 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Mon, 28 May 2018 12:32:31 +0800 Subject: [PATCH 1/2] Send Cache-Control header in WebUI responses Tune the caching time to be shorter, in case there is a program update. Change the cacheability to private, as WebUI resources are not intended to be cached at proxy. For uncacheable responses, send out "no-store" explicitly to halt browser caching. --- src/base/http/types.h | 4 +++- src/webui/webapplication.cpp | 30 +++++++++++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/base/http/types.h b/src/base/http/types.h index 2e16d9630..0e30feb9e 100644 --- a/src/base/http/types.h +++ b/src/base/http/types.h @@ -63,10 +63,12 @@ namespace Http const char HEADER_REQUEST_METHOD_POST[] = "POST"; const char CONTENT_TYPE_HTML[] = "text/html"; + const char CONTENT_TYPE_CSS[] = "text/css"; + const char CONTENT_TYPE_TXT[] = "text/plain"; + const char CONTENT_TYPE_JS[] = "application/javascript"; const char CONTENT_TYPE_JSON[] = "application/json"; const char CONTENT_TYPE_GIF[] = "image/gif"; const char CONTENT_TYPE_PNG[] = "image/png"; - const char CONTENT_TYPE_TXT[] = "text/plain"; const char CONTENT_TYPE_FORM_ENCODED[] = "application/x-www-form-urlencoded"; const char CONTENT_TYPE_FORM_DATA[] = "multipart/form-data"; diff --git a/src/webui/webapplication.cpp b/src/webui/webapplication.cpp index 349ebefe4..28bab0ba8 100644 --- a/src/webui/webapplication.cpp +++ b/src/webui/webapplication.cpp @@ -73,7 +73,6 @@ const QString PATH_PREFIX_THEME {QStringLiteral("/theme/")}; const QString WWW_FOLDER {QStringLiteral(":/www")}; const QString PUBLIC_FOLDER {QStringLiteral("/public")}; const QString PRIVATE_FOLDER {QStringLiteral("/private")}; -const QString MAX_AGE_MONTH {QStringLiteral("public, max-age=2592000")}; namespace { @@ -141,6 +140,22 @@ namespace return QUrl(QLatin1String("http://") + hostHeader); return hostHeader; } + + QString getCachingInterval(QString contentType) + { + contentType = contentType.toLower(); + + if (contentType.startsWith(QLatin1String("image/"))) + return QLatin1String("private, max-age=604800"); // 1 week + + if ((contentType == Http::CONTENT_TYPE_CSS) + || (contentType == Http::CONTENT_TYPE_JS)) { + // short interval in case of program update + return QLatin1String("private, max-age=43200"); // 12 hrs + } + + return QLatin1String("no-store"); + } } WebApplication::WebApplication(QObject *parent) @@ -176,14 +191,12 @@ void WebApplication::sendWebUIFile() if (request().path.startsWith(PATH_PREFIX_IMAGES)) { const QString imageFilename {request().path.mid(PATH_PREFIX_IMAGES.size())}; sendFile(QLatin1String(":/icons/") + imageFilename); - header(Http::HEADER_CACHE_CONTROL, MAX_AGE_MONTH); return; } if (request().path.startsWith(PATH_PREFIX_THEME)) { const QString iconId {request().path.mid(PATH_PREFIX_THEME.size())}; sendFile(IconProvider::instance()->getIconPath(iconId)); - header(Http::HEADER_CACHE_CONTROL, MAX_AGE_MONTH); return; } } @@ -455,7 +468,9 @@ void WebApplication::sendFile(const QString &path) // find translated file in cache auto it = m_translatedFiles.constFind(path); if ((it != m_translatedFiles.constEnd()) && (lastModified <= (*it).lastModified)) { - print((*it).data, QMimeDatabase().mimeTypeForFileNameAndData(path, (*it).data).name()); + const QString mimeName {QMimeDatabase().mimeTypeForFileNameAndData(path, (*it).data).name()}; + print((*it).data, mimeName); + header(Http::HEADER_CACHE_CONTROL, getCachingInterval(mimeName)); return; } @@ -474,8 +489,8 @@ void WebApplication::sendFile(const QString &path) QByteArray data {file.readAll()}; file.close(); - const QMimeType type {QMimeDatabase().mimeTypeForFileNameAndData(path, data)}; - const bool isTranslatable {type.inherits(QLatin1String("text/plain"))}; + const QMimeType mimeType {QMimeDatabase().mimeTypeForFileNameAndData(path, data)}; + const bool isTranslatable {mimeType.inherits(QLatin1String("text/plain"))}; // Translate the file if (isTranslatable) { @@ -486,7 +501,8 @@ void WebApplication::sendFile(const QString &path) m_translatedFiles[path] = {data, lastModified}; // caching translated file } - print(data, type.name()); + print(data, mimeType.name()); + header(Http::HEADER_CACHE_CONTROL, getCachingInterval(mimeType.name())); } Http::Response WebApplication::processRequest(const Http::Request &request, const Http::Environment &env) From eaa276b28413b862a10edb021b9bd2da8da9a915 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Mon, 28 May 2018 13:52:29 +0800 Subject: [PATCH 2/2] Fix WebUI cache behavior for css files The style.css in public & private folders share the same URI, this confuses the browser cache, so rename one of them. --- src/webui/webui.qrc | 2 +- src/webui/www/public/css/{style.css => login.css} | 0 src/webui/www/public/login.html | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/webui/www/public/css/{style.css => login.css} (100%) diff --git a/src/webui/webui.qrc b/src/webui/webui.qrc index 686aea1db..7baac49c9 100644 --- a/src/webui/webui.qrc +++ b/src/webui/webui.qrc @@ -42,7 +42,7 @@ www/private/transferlist.html www/private/upload.html www/private/uploadlimit.html - www/public/css/style.css + www/public/css/login.css www/public/login.html www/public/scripts/lib/mootools-1.2-core-yc.js diff --git a/src/webui/www/public/css/style.css b/src/webui/www/public/css/login.css similarity index 100% rename from src/webui/www/public/css/style.css rename to src/webui/www/public/css/login.css diff --git a/src/webui/www/public/login.html b/src/webui/www/public/login.html index 8eed097a7..1982f4788 100644 --- a/src/webui/www/public/login.html +++ b/src/webui/www/public/login.html @@ -5,7 +5,7 @@ qBittorrent QBT_TR(Web UI)QBT_TR[CONTEXT=OptionsDialog] - +