Improve coding style

This commit is contained in:
Vladimir Golovnev (Glassez)
2020-11-16 10:02:11 +03:00
parent acad35c5bc
commit c41df9ffbd
147 changed files with 4454 additions and 2227 deletions

View File

@@ -59,13 +59,17 @@ void Connection::read()
m_idleTimer.restart();
m_receivedData.append(m_socket->readAll());
while (!m_receivedData.isEmpty()) {
while (!m_receivedData.isEmpty())
{
const RequestParser::ParseResult result = RequestParser::parse(m_receivedData);
switch (result.status) {
case RequestParser::ParseStatus::Incomplete: {
switch (result.status)
{
case RequestParser::ParseStatus::Incomplete:
{
const long bufferLimit = RequestParser::MAX_CONTENT_SIZE * 1.1; // some margin for headers
if (m_receivedData.size() > bufferLimit) {
if (m_receivedData.size() > bufferLimit)
{
Logger::instance()->addMessage(tr("Http request size exceeds limitation, closing socket. Limit: %1, IP: %2")
.arg(bufferLimit).arg(m_socket->peerAddress().toString()), Log::WARNING);
@@ -78,7 +82,8 @@ void Connection::read()
}
return;
case RequestParser::ParseStatus::BadRequest: {
case RequestParser::ParseStatus::BadRequest:
{
Logger::instance()->addMessage(tr("Bad Http request, closing socket. IP: %1")
.arg(m_socket->peerAddress().toString()), Log::WARNING);
@@ -90,7 +95,8 @@ void Connection::read()
}
return;
case RequestParser::ParseStatus::OK: {
case RequestParser::ParseStatus::OK:
{
const Environment env {m_socket->localAddress(), m_socket->localPort(), m_socket->peerAddress(), m_socket->peerPort()};
Response resp = m_requestHandler->processRequest(result.request, env);
@@ -133,7 +139,8 @@ bool Connection::acceptsGzipEncoding(QString codings)
const auto isCodingAvailable = [](const QVector<QStringRef> &list, const QString &encoding) -> bool
{
for (const QStringRef &str : list) {
for (const QStringRef &str : list)
{
if (!str.startsWith(encoding))
continue;

View File

@@ -61,7 +61,8 @@ namespace
{
// [rfc7230] 3.2. Header Fields
const int i = line.indexOf(':');
if (i <= 0) {
if (i <= 0)
{
qWarning() << Q_FUNC_INFO << "invalid http header:" << line;
return false;
}
@@ -88,13 +89,15 @@ RequestParser::ParseResult RequestParser::doParse(const QByteArray &data)
{
// we don't handle malformed requests which use double `LF` as delimiter
const int headerEnd = data.indexOf(EOH);
if (headerEnd < 0) {
if (headerEnd < 0)
{
qDebug() << Q_FUNC_INFO << "incomplete request";
return {ParseStatus::Incomplete, Request(), 0};
}
const QString httpHeaders = QString::fromLatin1(data.constData(), headerEnd);
if (!parseStartLines(httpHeaders)) {
if (!parseStartLines(httpHeaders))
{
qWarning() << Q_FUNC_INFO << "header parsing error";
return {ParseStatus::BadRequest, Request(), 0};
}
@@ -104,26 +107,32 @@ RequestParser::ParseResult RequestParser::doParse(const QByteArray &data)
// handle supported methods
if ((m_request.method == HEADER_REQUEST_METHOD_GET) || (m_request.method == HEADER_REQUEST_METHOD_HEAD))
return {ParseStatus::OK, m_request, headerLength};
if (m_request.method == HEADER_REQUEST_METHOD_POST) {
if (m_request.method == HEADER_REQUEST_METHOD_POST)
{
bool ok = false;
const int contentLength = m_request.headers[HEADER_CONTENT_LENGTH].toInt(&ok);
if (!ok || (contentLength < 0)) {
if (!ok || (contentLength < 0))
{
qWarning() << Q_FUNC_INFO << "bad request: content-length invalid";
return {ParseStatus::BadRequest, Request(), 0};
}
if (contentLength > MAX_CONTENT_SIZE) {
if (contentLength > MAX_CONTENT_SIZE)
{
qWarning() << Q_FUNC_INFO << "bad request: message too long";
return {ParseStatus::BadRequest, Request(), 0};
}
if (contentLength > 0) {
if (contentLength > 0)
{
const QByteArray httpBodyView = midView(data, headerLength, contentLength);
if (httpBodyView.length() < contentLength) {
if (httpBodyView.length() < contentLength)
{
qDebug() << Q_FUNC_INFO << "incomplete request";
return {ParseStatus::Incomplete, Request(), 0};
}
if (!parsePostMessage(httpBodyView)) {
if (!parsePostMessage(httpBodyView))
{
qWarning() << Q_FUNC_INFO << "message body parsing error";
return {ParseStatus::BadRequest, Request(), 0};
}
@@ -143,12 +152,15 @@ bool RequestParser::parseStartLines(const QString &data)
// [rfc7230] 3.2.2. Field Order
QStringList requestLines;
for (const auto &line : lines) {
if (line.at(0).isSpace() && !requestLines.isEmpty()) {
for (const auto &line : lines)
{
if (line.at(0).isSpace() && !requestLines.isEmpty())
{
// continuation of previous line
requestLines.last() += line.toString();
}
else {
else
{
requestLines += line.toString();
}
}
@@ -159,7 +171,8 @@ bool RequestParser::parseStartLines(const QString &data)
if (!parseRequestLine(requestLines[0]))
return false;
for (auto i = ++(requestLines.begin()); i != requestLines.end(); ++i) {
for (auto i = ++(requestLines.begin()); i != requestLines.end(); ++i)
{
if (!parseHeaderLine(*i, m_request.headers))
return false;
}
@@ -174,7 +187,8 @@ bool RequestParser::parseRequestLine(const QString &line)
const QRegularExpression re(QLatin1String("^([A-Z]+)\\s+(\\S+)\\s+HTTP\\/(\\d\\.\\d)$"));
const QRegularExpressionMatch match = re.match(line);
if (!match.hasMatch()) {
if (!match.hasMatch())
{
qWarning() << Q_FUNC_INFO << "invalid http header:" << line;
return false;
}
@@ -189,12 +203,14 @@ bool RequestParser::parseRequestLine(const QString &line)
m_request.path = QString::fromUtf8(QByteArray::fromPercentEncoding(pathComponent));
if (sepPos >= 0) {
if (sepPos >= 0)
{
const QByteArray query = midView(url, (sepPos + 1));
// [rfc3986] 2.4 When to Encode or Decode
// URL components should be separated before percent-decoding
for (const QByteArray &param : asConst(splitToViews(query, "&"))) {
for (const QByteArray &param : asConst(splitToViews(query, "&")))
{
const int eqCharPos = param.indexOf('=');
if (eqCharPos <= 0) continue; // ignores params without name
@@ -222,12 +238,14 @@ bool RequestParser::parsePostMessage(const QByteArray &data)
const QString contentTypeLower = contentType.toLower();
// application/x-www-form-urlencoded
if (contentTypeLower.startsWith(CONTENT_TYPE_FORM_ENCODED)) {
if (contentTypeLower.startsWith(CONTENT_TYPE_FORM_ENCODED))
{
// [URL Standard] 5.1 application/x-www-form-urlencoded parsing
const QByteArray processedData = QByteArray(data).replace('+', ' ');
QListIterator<QStringPair> i(QUrlQuery(processedData).queryItems(QUrl::FullyDecoded));
while (i.hasNext()) {
while (i.hasNext())
{
const QStringPair pair = i.next();
m_request.posts[pair.first] = pair.second;
}
@@ -236,19 +254,22 @@ bool RequestParser::parsePostMessage(const QByteArray &data)
}
// multipart/form-data
if (contentTypeLower.startsWith(CONTENT_TYPE_FORM_DATA)) {
if (contentTypeLower.startsWith(CONTENT_TYPE_FORM_DATA))
{
// [rfc2046] 5.1.1. Common Syntax
// find boundary delimiter
const QLatin1String boundaryFieldName("boundary=");
const int idx = contentType.indexOf(boundaryFieldName);
if (idx < 0) {
if (idx < 0)
{
qWarning() << Q_FUNC_INFO << "Could not find boundary in multipart/form-data header!";
return false;
}
const QByteArray delimiter = Utils::String::unquote(contentType.midRef(idx + boundaryFieldName.size())).toLatin1();
if (delimiter.isEmpty()) {
if (delimiter.isEmpty())
{
qWarning() << Q_FUNC_INFO << "boundary delimiter field empty!";
return false;
}
@@ -256,7 +277,8 @@ bool RequestParser::parsePostMessage(const QByteArray &data)
// split data by "dash-boundary"
const QByteArray dashDelimiter = QByteArray("--") + delimiter + CRLF;
QVector<QByteArray> multipart = splitToViews(data, dashDelimiter, QString::SkipEmptyParts);
if (multipart.isEmpty()) {
if (multipart.isEmpty())
{
qWarning() << Q_FUNC_INFO << "multipart empty";
return false;
}
@@ -279,7 +301,8 @@ bool RequestParser::parseFormData(const QByteArray &data)
{
const QVector<QByteArray> list = splitToViews(data, EOH, QString::KeepEmptyParts);
if (list.size() != 2) {
if (list.size() != 2)
{
qWarning() << Q_FUNC_INFO << "multipart/form-data format error";
return false;
}
@@ -289,12 +312,15 @@ bool RequestParser::parseFormData(const QByteArray &data)
HeaderMap headersMap;
const QVector<QStringRef> headerLines = headers.splitRef(CRLF, QString::SkipEmptyParts);
for (const auto &line : headerLines) {
if (line.trimmed().startsWith(HEADER_CONTENT_DISPOSITION, Qt::CaseInsensitive)) {
for (const auto &line : headerLines)
{
if (line.trimmed().startsWith(HEADER_CONTENT_DISPOSITION, Qt::CaseInsensitive))
{
// extract out filename & name
const QVector<QStringRef> directives = line.split(';', QString::SkipEmptyParts);
for (const auto &directive : directives) {
for (const auto &directive : directives)
{
const int idx = directive.indexOf('=');
if (idx < 0)
continue;
@@ -304,7 +330,8 @@ bool RequestParser::parseFormData(const QByteArray &data)
headersMap[name] = value;
}
}
else {
else
{
if (!parseHeaderLine(line.toString(), headersMap))
return false;
}
@@ -314,13 +341,16 @@ bool RequestParser::parseFormData(const QByteArray &data)
const QLatin1String filename("filename");
const QLatin1String name("name");
if (headersMap.contains(filename)) {
if (headersMap.contains(filename))
{
m_request.files.append({headersMap[filename], headersMap[HEADER_CONTENT_TYPE], payload});
}
else if (headersMap.contains(name)) {
else if (headersMap.contains(name))
{
m_request.posts[headersMap[name]] = payload;
}
else {
else
{
// malformed
qWarning() << Q_FUNC_INFO << "multipart/form-data header error";
return false;

View File

@@ -93,12 +93,14 @@ void Server::incomingConnection(const qintptr socketDescriptor)
else
serverSocket = new QTcpSocket(this);
if (!serverSocket->setSocketDescriptor(socketDescriptor)) {
if (!serverSocket->setSocketDescriptor(socketDescriptor))
{
delete serverSocket;
return;
}
if (m_https) {
if (m_https)
{
static_cast<QSslSocket *>(serverSocket)->setProtocol(QSsl::SecureProtocols);
static_cast<QSslSocket *>(serverSocket)->setPrivateKey(m_key);
static_cast<QSslSocket *>(serverSocket)->setLocalCertificateChain(m_certificates);
@@ -134,7 +136,8 @@ bool Server::setupHttps(const QByteArray &certificates, const QByteArray &privat
const QList<QSslCertificate> certs {Utils::Net::loadSSLCertificate(certificates)};
const QSslKey key {Utils::Net::loadSSLKey(privateKey)};
if (certs.isEmpty() || key.isNull()) {
if (certs.isEmpty() || key.isNull())
{
disableHttps();
return false;
}