File indexing completed on 2024-12-22 04:57:54
0001 /* 0002 SPDX-License-Identifier: BSD-2-Clause 0003 */ 0004 0005 #include "debug.h" 0006 #include <QPair> 0007 #include <QTcpSocket> 0008 #include <QUrl> 0009 #if QT_VERSION >= 0x050000 0010 #include <QUrlQuery> 0011 #endif 0012 0013 #include "o2/o2replyserver.h" 0014 0015 O2ReplyServer::O2ReplyServer(QObject *parent) 0016 : QTcpServer(parent) 0017 { 0018 connect(this, &QTcpServer::newConnection, this, &O2ReplyServer::onIncomingConnection); 0019 replyContent_ = QByteArrayLiteral("<HTML></HTML>"); 0020 } 0021 0022 void O2ReplyServer::onIncomingConnection() 0023 { 0024 QTcpSocket *socket = nextPendingConnection(); 0025 connect(socket, &QIODevice::readyRead, this, &O2ReplyServer::onBytesReady, Qt::UniqueConnection); 0026 connect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater); 0027 } 0028 0029 void O2ReplyServer::onBytesReady() 0030 { 0031 qCDebug(TOMBOYNOTESRESOURCE_LOG) << "O2ReplyServer::onBytesReady"; 0032 auto socket = qobject_cast<QTcpSocket *>(sender()); 0033 if (!socket) { 0034 return; 0035 } 0036 QByteArray reply; 0037 reply.append("HTTP/1.0 200 OK \r\n"); 0038 reply.append("Content-Type: text/html; charset=\"utf-8\"\r\n"); 0039 reply.append(QByteArray("Content-Length: ") + QByteArray::number(replyContent_.size()) + "\r\n\r\n"); 0040 reply.append(replyContent_); 0041 socket->write(reply); 0042 0043 QByteArray data = socket->readAll(); 0044 QMultiMap<QString, QString> queryParams = parseQueryParams(&data); 0045 socket->disconnectFromHost(); 0046 close(); 0047 Q_EMIT verificationReceived(queryParams); 0048 } 0049 0050 QMultiMap<QString, QString> O2ReplyServer::parseQueryParams(QByteArray *data) 0051 { 0052 qCDebug(TOMBOYNOTESRESOURCE_LOG) << "O2ReplyServer::parseQueryParams"; 0053 0054 QString splitGetLine = QString::fromLatin1(*data).split(QStringLiteral("\r\n")).first(); 0055 splitGetLine.remove(QStringLiteral("GET ")); 0056 splitGetLine.remove(QStringLiteral("HTTP/1.1")); 0057 splitGetLine.remove(QStringLiteral("\r\n")); 0058 splitGetLine.prepend(QStringLiteral("http://localhost")); 0059 QUrl getTokenUrl(splitGetLine); 0060 0061 QList<QPair<QString, QString>> tokens; 0062 #if QT_VERSION < 0x050000 0063 tokens = getTokenUrl.queryItems(); 0064 #else 0065 QUrlQuery query(getTokenUrl); 0066 tokens = query.queryItems(); 0067 #endif 0068 QMultiMap<QString, QString> queryParams; 0069 for (const auto &tokenPair : std::as_const(tokens)) { 0070 // FIXME: We are decoding key and value again. This helps with Google OAuth, but is it mandated by the standard? 0071 const QString key = QUrl::fromPercentEncoding(tokenPair.first.trimmed().toLatin1()); 0072 const QString value = QUrl::fromPercentEncoding(tokenPair.second.trimmed().toLatin1()); 0073 queryParams.insert(key, value); 0074 } 0075 return queryParams; 0076 } 0077 0078 QByteArray O2ReplyServer::replyContent() const 0079 { 0080 return replyContent_; 0081 } 0082 0083 void O2ReplyServer::setReplyContent(const QByteArray &value) 0084 { 0085 replyContent_ = value; 0086 } 0087 0088 #include "moc_o2replyserver.cpp"