Implement robust acceptsGzipEncoding()

Adhere more to http/1.1 standard
This commit is contained in:
Chocobo1 2017-04-14 18:31:18 +08:00
parent 129172453b
commit 4600e679d1
2 changed files with 39 additions and 10 deletions

View file

@ -61,7 +61,7 @@ void Connection::read()
m_receivedData.append(m_socket->readAll()); m_receivedData.append(m_socket->readAll());
Request request; Request request;
RequestParser::ErrorCode err = RequestParser::parse(m_receivedData, request); RequestParser::ErrorCode err = RequestParser::parse(m_receivedData, request); // TODO: transform request headers to lowercase
switch (err) { switch (err) {
case RequestParser::IncompleteRequest: case RequestParser::IncompleteRequest:
@ -100,15 +100,44 @@ bool Connection::isClosed() const
return (m_socket->state() == QAbstractSocket::UnconnectedState); return (m_socket->state() == QAbstractSocket::UnconnectedState);
} }
bool Connection::acceptsGzipEncoding(const QString &encoding) bool Connection::acceptsGzipEncoding(QString codings)
{ {
QRegExp rx("(gzip)(;q=([^,]+))?"); // [rfc7231] 5.3.4. Accept-Encoding
if (rx.indexIn(encoding) >= 0) {
if (rx.cap(2).size() > 0) const auto isCodingAvailable = [](const QStringList &list, const QString &encoding) -> bool
// check if quality factor > 0 {
return (rx.cap(3).toDouble() > 0); foreach (const QString &str, list) {
// if quality factor is not specified, then it's 1 if (!str.startsWith(encoding))
continue;
// without quality values
if (str == encoding)
return true;
// [rfc7231] 5.3.1. Quality Values
const QStringRef substr = str.midRef(encoding.size() + 3); // ex. skip over "gzip;q="
bool ok = false;
const double qvalue = substr.toDouble(&ok);
if (!ok || (qvalue <= 0.0))
return false;
return true;
}
return false;
};
const QStringList list = codings.remove(' ').remove('\t').split(',', QString::SkipEmptyParts);
if (list.isEmpty())
return false;
const bool canGzip = isCodingAvailable(list, QLatin1String("gzip"));
if (canGzip)
return true; return true;
}
const bool canAny = isCodingAvailable(list, QLatin1String("*"));
if (canAny)
return true;
return false; return false;
} }

View file

@ -60,7 +60,7 @@ namespace Http
void read(); void read();
private: private:
static bool acceptsGzipEncoding(const QString &encoding); static bool acceptsGzipEncoding(QString codings);
void sendResponse(const Response &response); void sendResponse(const Response &response);
QTcpSocket *m_socket; QTcpSocket *m_socket;