diff options
Diffstat (limited to 'src/network/access/qhsts.cpp')
-rw-r--r-- | src/network/access/qhsts.cpp | 104 |
1 files changed, 34 insertions, 70 deletions
diff --git a/src/network/access/qhsts.cpp b/src/network/access/qhsts.cpp index 99c4c605dd..21ed08ce4a 100644 --- a/src/network/access/qhsts.cpp +++ b/src/network/access/qhsts.cpp @@ -1,44 +1,10 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNetwork module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qhsts_p.h" +#include "qhttpheaders.h" + #include "QtCore/private/qipaddress_p.h" #include "QtCore/qlist.h" @@ -76,7 +42,7 @@ static bool is_valid_domain_name(const QString &host) return true; } -void QHstsCache::updateFromHeaders(const QList<QPair<QByteArray, QByteArray>> &headers, +void QHstsCache::updateFromHeaders(const QHttpHeaders &headers, const QUrl &url) { if (!url.isValid()) @@ -210,7 +176,7 @@ bool QHstsCache::isKnownHost(const QUrl &url) const } } - const int dot = nameToTest.fragment.indexOf(QLatin1Char('.')); + const qsizetype dot = nameToTest.fragment.indexOf(u'.'); if (dot == -1) break; @@ -322,7 +288,7 @@ static bool isSeparator(char c) return isLWS(c) || std::find(separators, end, c) != end; } -static QByteArray unescapeMaxAge(const QByteArray &value) +static QByteArrayView unescapeMaxAge(QByteArrayView value) { if (value.size() < 2 || value[0] != '"') return value; @@ -360,27 +326,25 @@ quoted-pair = "\" CHAR */ -bool QHstsHeaderParser::parse(const QList<QPair<QByteArray, QByteArray>> &headers) +bool QHstsHeaderParser::parse(const QHttpHeaders &headers) { - for (const auto &h : headers) { - // We use '==' since header name was already 'trimmed' for us: - if (h.first == "Strict-Transport-Security") { - header = h.second; - // RFC6797, 8.1: - // - // The UA MUST ignore any STS header fields not conforming to the - // grammar specified in Section 6.1 ("Strict-Transport-Security HTTP - // Response Header Field"). - // - // If a UA receives more than one STS header field in an HTTP - // response message over secure transport, then the UA MUST process - // only the first such header field. - // - // We read this as: ignore all invalid headers and take the first valid: - if (parseSTSHeader() && maxAgeFound) { - expiry = QDateTime::currentDateTimeUtc().addSecs(maxAge); - return true; - } + for (const auto &value : headers.values( + QHttpHeaders::WellKnownHeader::StrictTransportSecurity)) { + header = value; + // RFC6797, 8.1: + // + // The UA MUST ignore any STS header fields not conforming to the + // grammar specified in Section 6.1 ("Strict-Transport-Security HTTP + // Response Header Field"). + // + // If a UA receives more than one STS header field in an HTTP + // response message over secure transport, then the UA MUST process + // only the first such header field. + // + // We read this as: ignore all invalid headers and take the first valid: + if (parseSTSHeader() && maxAgeFound) { + expiry = QDateTime::currentDateTimeUtc().addSecs(maxAge); + return true; } } @@ -436,7 +400,7 @@ bool QHstsHeaderParser::parseDirective() if (token == ";") // That's a weird grammar, but that's what it is. return true; - if (!isTOKEN(token[0])) // Not a valid directive-name. + if (!isTOKEN(token.at(0))) // Not a valid directive-name. return false; const QByteArray directiveName = token; @@ -481,7 +445,7 @@ bool QHstsHeaderParser::processDirective(const QByteArray &name, const QByteArra return false; } - const QByteArray unescapedValue = unescapeMaxAge(value); + const QByteArrayView unescapedValue = unescapeMaxAge(value); if (!unescapedValue.size()) return false; @@ -517,13 +481,13 @@ bool QHstsHeaderParser::nextToken() // Fortunately enough, by this point qhttpnetworkreply already got rid of // [CRLF] parts, but we can have 1*(SP|HT) yet. - while (tokenPos < header.size() && isLWS(header[tokenPos])) + while (tokenPos < header.size() && isLWS(header.at(tokenPos))) ++tokenPos; if (tokenPos == header.size()) return true; - const char ch = header[tokenPos]; + const char ch = header.at(tokenPos); if (ch == ';' || ch == '=') { token.append(ch); ++tokenPos; @@ -537,17 +501,17 @@ bool QHstsHeaderParser::nextToken() if (ch == '"') { int last = tokenPos + 1; while (last < header.size()) { - if (header[last] == '"') { + if (header.at(last) == '"') { // The end of a quoted-string. break; - } else if (header[last] == '\\') { + } else if (header.at(last) == '\\') { // quoted-pair = "\" CHAR - if (last + 1 < header.size() && isCHAR(header[last + 1])) + if (last + 1 < header.size() && isCHAR(header.at(last + 1))) last += 2; else return false; } else { - if (!isTEXT(header[last])) + if (!isTEXT(header.at(last))) return false; ++last; } @@ -568,7 +532,7 @@ bool QHstsHeaderParser::nextToken() return false; int last = tokenPos + 1; - while (last < header.size() && isTOKEN(header[last])) + while (last < header.size() && isTOKEN(header.at(last))) ++last; token = header.mid(tokenPos, last - tokenPos); |