Browse Source

Prebuild HTTP headers as much as possible

This avoids some branching when building a HTTP response.
adaptive-webui-19844
Chocobo1 4 years ago
parent
commit
957d697aee
No known key found for this signature in database
GPG Key ID: 210D9C873253A68C
  1. 43
      src/webui/webapplication.cpp
  2. 6
      src/webui/webapplication.h

43
src/webui/webapplication.cpp

@ -335,25 +335,34 @@ void WebApplication::configure()
m_domainList = pref->getServerDomains().split(';', QString::SkipEmptyParts); m_domainList = pref->getServerDomains().split(';', QString::SkipEmptyParts);
std::for_each(m_domainList.begin(), m_domainList.end(), [](QString &entry) { entry = entry.trimmed(); }); std::for_each(m_domainList.begin(), m_domainList.end(), [](QString &entry) { entry = entry.trimmed(); });
m_isClickjackingProtectionEnabled = pref->isWebUiClickjackingProtectionEnabled();
m_isCSRFProtectionEnabled = pref->isWebUiCSRFProtectionEnabled(); m_isCSRFProtectionEnabled = pref->isWebUiCSRFProtectionEnabled();
m_isSecureCookieEnabled = pref->isWebUiSecureCookieEnabled(); m_isSecureCookieEnabled = pref->isWebUiSecureCookieEnabled();
m_isHostHeaderValidationEnabled = pref->isWebUIHostHeaderValidationEnabled(); m_isHostHeaderValidationEnabled = pref->isWebUIHostHeaderValidationEnabled();
m_isHttpsEnabled = pref->isWebUiHttpsEnabled(); m_isHttpsEnabled = pref->isWebUiHttpsEnabled();
m_contentSecurityPolicy = m_prebuiltHeaders.clear();
m_prebuiltHeaders.push_back({QLatin1String(Http::HEADER_X_XSS_PROTECTION), QLatin1String("1; mode=block")});
m_prebuiltHeaders.push_back({QLatin1String(Http::HEADER_X_CONTENT_TYPE_OPTIONS), QLatin1String("nosniff")});
if (!m_isAltUIUsed)
m_prebuiltHeaders.push_back({QLatin1String(Http::HEADER_REFERRER_POLICY), QLatin1String("same-origin")});
const bool isClickjackingProtectionEnabled = pref->isWebUiClickjackingProtectionEnabled();
if (isClickjackingProtectionEnabled)
m_prebuiltHeaders.push_back({QLatin1String(Http::HEADER_X_FRAME_OPTIONS), QLatin1String("SAMEORIGIN")});
const QString contentSecurityPolicy =
(m_isAltUIUsed (m_isAltUIUsed
? QLatin1String("") ? QLatin1String("")
: QLatin1String("default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; object-src 'none'; form-action 'self';")) : QLatin1String("default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; object-src 'none'; form-action 'self';"))
+ (m_isClickjackingProtectionEnabled ? QLatin1String(" frame-ancestors 'self';") : QLatin1String("")) + (isClickjackingProtectionEnabled ? QLatin1String(" frame-ancestors 'self';") : QLatin1String(""))
+ (m_isHttpsEnabled ? QLatin1String(" upgrade-insecure-requests;") : QLatin1String("")); + (m_isHttpsEnabled ? QLatin1String(" upgrade-insecure-requests;") : QLatin1String(""));
if (!contentSecurityPolicy.isEmpty())
m_prebuiltHeaders.push_back({QLatin1String(Http::HEADER_CONTENT_SECURITY_POLICY), contentSecurityPolicy});
m_useCustomHTTPHeaders = pref->isWebUICustomHTTPHeadersEnabled(); if (pref->isWebUICustomHTTPHeadersEnabled()) {
m_customHTTPHeaders.clear();
if (m_useCustomHTTPHeaders) {
const QString customHeaders = pref->getWebUICustomHTTPHeaders().trimmed(); const QString customHeaders = pref->getWebUICustomHTTPHeaders().trimmed();
const QVector<QStringRef> customHeaderLines = customHeaders.splitRef('\n', QString::SkipEmptyParts); const QVector<QStringRef> customHeaderLines = customHeaders.splitRef('\n', QString::SkipEmptyParts);
m_customHTTPHeaders.reserve(customHeaderLines.size());
for (const QStringRef &line : customHeaderLines) { for (const QStringRef &line : customHeaderLines) {
const int idx = line.indexOf(':'); const int idx = line.indexOf(':');
@ -365,7 +374,7 @@ void WebApplication::configure()
const QString header = line.left(idx).trimmed().toString(); const QString header = line.left(idx).trimmed().toString();
const QString value = line.mid(idx + 1).trimmed().toString(); const QString value = line.mid(idx + 1).trimmed().toString();
m_customHTTPHeaders.push_back({header, value}); m_prebuiltHeaders.push_back({header, value});
} }
} }
} }
@ -460,22 +469,8 @@ Http::Response WebApplication::processRequest(const Http::Request &request, cons
print(error.message(), Http::CONTENT_TYPE_TXT); print(error.message(), Http::CONTENT_TYPE_TXT);
} }
header(QLatin1String(Http::HEADER_X_XSS_PROTECTION), QLatin1String("1; mode=block")); for (const CustomHTTPHeader &prebuiltHeader : asConst(m_prebuiltHeaders))
header(QLatin1String(Http::HEADER_X_CONTENT_TYPE_OPTIONS), QLatin1String("nosniff")); header(prebuiltHeader.name, prebuiltHeader.value);
if (m_isClickjackingProtectionEnabled)
header(QLatin1String(Http::HEADER_X_FRAME_OPTIONS), QLatin1String("SAMEORIGIN"));
if (!m_isAltUIUsed)
header(QLatin1String(Http::HEADER_REFERRER_POLICY), QLatin1String("same-origin"));
if (!m_contentSecurityPolicy.isEmpty())
header(QLatin1String(Http::HEADER_CONTENT_SECURITY_POLICY), m_contentSecurityPolicy);
if (m_useCustomHTTPHeaders) {
for (const CustomHTTPHeader &customHeader : asConst(m_customHTTPHeaders))
header(customHeader.name, customHeader.value);
}
return response(); return response();
} }

6
src/webui/webapplication.h

@ -151,12 +151,10 @@ private:
// security related // security related
QStringList m_domainList; QStringList m_domainList;
bool m_isClickjackingProtectionEnabled;
bool m_isCSRFProtectionEnabled; bool m_isCSRFProtectionEnabled;
bool m_isSecureCookieEnabled; bool m_isSecureCookieEnabled;
bool m_isHostHeaderValidationEnabled; bool m_isHostHeaderValidationEnabled;
bool m_isHttpsEnabled; bool m_isHttpsEnabled;
QString m_contentSecurityPolicy;
// Custom HTTP headers // Custom HTTP headers
struct CustomHTTPHeader struct CustomHTTPHeader
@ -164,6 +162,6 @@ private:
QString name; QString name;
QString value; QString value;
}; };
bool m_useCustomHTTPHeaders;
QVector<CustomHTTPHeader> m_customHTTPHeaders; QVector<CustomHTTPHeader> m_prebuiltHeaders;
}; };

Loading…
Cancel
Save