diff --git a/CMakeLists.txt b/CMakeLists.txt index 22fab10c3..8ba991137 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ find_package(Qt5 REQUIRED Multimedia Svg Concurrent + HttpServer ) if (WIN32) diff --git a/chatterino.pro b/chatterino.pro index 032423d65..67c2b6271 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -20,7 +20,7 @@ MINIMUM_REQUIRED_QT_VERSION = 5.12.0 error("You're trying to compile with Qt $$QT_VERSION, but minimum required Qt version is $$MINIMUM_REQUIRED_QT_VERSION") } -QT += widgets core gui network multimedia svg concurrent +QT += widgets core gui network multimedia svg concurrent httpserver CONFIG += communi COMMUNI += core model util diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 207f8c104..11cfe7c6d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -483,6 +483,7 @@ target_link_libraries(${LIBRARY_PROJECT} Qt5::Multimedia Qt5::Svg Qt5::Concurrent + Qt5::HttpServer LibCommuni::LibCommuni qt5keychain diff --git a/src/widgets/dialogs/LoginDialog.cpp b/src/widgets/dialogs/LoginDialog.cpp index 1fc9611dd..6fd68e834 100644 --- a/src/widgets/dialogs/LoginDialog.cpp +++ b/src/widgets/dialogs/LoginDialog.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace chatterino { @@ -79,66 +80,27 @@ namespace { } // namespace -LoginServer::LoginServer(QObject *parent) - : QTcpServer(parent) -{ - server_ = new QTcpServer(this); - - connect(server_, &QTcpServer::newConnection, this, - &LoginServer::slotNewConnection); -} - -QTcpServer *LoginServer::getServer() -{ - return this->server_; -} - -void LoginServer::slotNewConnection() -{ - qDebug() << "HONDETEDTED!!!"; - socket_ = server_->nextPendingConnection(); - - connect(socket_, &QTcpSocket::readyRead, this, - &LoginServer::slotServerRead); - connect(socket_, &QTcpSocket::disconnected, this, - &LoginServer::slotClientDisconnected); -} - -void LoginServer::slotServerRead() -{ - qDebug() << "reading data..."; - while (socket_->bytesAvailable() > 0) - { - QByteArray array = socket_->readAll(); - qDebug() << array; - } - - // Write data back - socket_->write( - "HTTP/1.1 200 OK\r\nServer: nginx/1.14.2\r\nDate: Wed, 21 Jul " - "2021 20:19:05 GMT\r\nContent-Type: text/plain\r\nContent-Length: " - "4\r\nConnection: close\r\n\r\nxd\r\n"); - socket_->waitForBytesWritten(5000); - socket_->close(); - - // socket_->write("HTTP/1.1 204 No Content\r\n"); -} - -void LoginServer::slotBytesWritten() -{ - qDebug() << "bytes written!"; -} - -void LoginServer::slotClientDisconnected() -{ - qDebug() << "HEDISCONNECTED!"; - socket_->close(); -} - BasicLoginWidget::BasicLoginWidget() { - // init tcp server - this->loginServer_ = new LoginServer(this); + // Initialize HTTP server and its routes + qCDebug(chatterinoWidget) << "Creating new HTTP server"; + this->httpServer_ = new QHttpServer(this); + this->tcpServer_ = new QTcpServer(this->httpServer_); + this->httpServer_->bind(this->tcpServer_); + + qCDebug(chatterinoWidget) << "Initializing HTTP server's routes"; + this->httpServer_->route( + "/code", QHttpServerRequest::Method::GET, + [this](const QHttpServerRequest &req, QHttpServerResponder &&resp) { + qDebug() << "got credentials!"; + resp.write("KKona", "text/plain", + QHttpServerResponder::StatusCode::Ok); + qDebug() << req.url().fragment(); + qDebug() << req.url(); + + this->ui_.loginButton.setText("Logged in!"); + this->ui_.loginButton.setEnabled(true); + }); const QString loginLink = "http://localhost:1234"; this->setLayout(&this->ui_.layout); @@ -163,17 +125,20 @@ BasicLoginWidget::BasicLoginWidget() this->ui_.layout.addWidget(&this->ui_.unableToOpenBrowserHelper); connect(&this->ui_.loginButton, &QPushButton::clicked, [this, loginLink]() { - qDebug() << "penis"; - - // Initialize the server - if (!this->loginServer_->getServer()->listen(QHostAddress::LocalHost, - 52107)) + // Start listening for credentials + qDebug() << this->tcpServer_->isListening(); + if (!this->tcpServer_->listen(serverAddress, serverPort)) { - qDebug() << "failed to start server"; - return; + qCWarning(chatterinoWidget) << "Failed to start HTTP server"; + } + else + { + qInfo(chatterinoWidget) << QString("HTTP server Listening on %1:%2") + .arg(serverAddress.toString()) + .arg(serverPort); + this->ui_.loginButton.setText("Listening..."); + this->ui_.loginButton.setDisabled(true); } - qDebug() << "listening!"; - return; // Open login page if (!QDesktopServices::openUrl(QUrl(loginLink))) @@ -227,10 +192,17 @@ BasicLoginWidget::BasicLoginWidget() }); } -BasicLoginWidget::~BasicLoginWidget() +void BasicLoginWidget::closeHttpServer() { - qDebug() << "BasicLoinWidget was destroyed, closing connection"; - this->loginServer_->close(); + // Revert login button + this->ui_.loginButton.setText("Log in (Opens in browser)"); + this->ui_.loginButton.setEnabled(true); + + qCDebug(chatterinoWidget) << "Closing TCP servers bind to HTTP server"; + for (const auto &server : this->httpServer_->servers()) + { + server->close(); + } } AdvancedLoginWidget::AdvancedLoginWidget() @@ -344,8 +316,7 @@ LoginWidget::LoginWidget(QWidget *parent) void LoginWidget::hideEvent(QHideEvent *event) { // Make the port free - qDebug() << "closing server"; - this->ui_.basic.loginServer_->getServer()->close(); + this->ui_.basic.closeHttpServer(); } } // namespace chatterino diff --git a/src/widgets/dialogs/LoginDialog.hpp b/src/widgets/dialogs/LoginDialog.hpp index 11467f1de..e02bebb7a 100644 --- a/src/widgets/dialogs/LoginDialog.hpp +++ b/src/widgets/dialogs/LoginDialog.hpp @@ -18,36 +18,14 @@ #include #include #include +#include namespace chatterino { -class LoginServer : public QTcpServer -{ -public: - static constexpr int chatterinoPort = 52107; - - explicit LoginServer(QObject *parent = {}); - QTcpServer *getServer(); - // void incomingConnection(qintptr handle) override; -public slots: - void slotNewConnection(); - void slotServerRead(); - void slotBytesWritten(); - void slotClientDisconnected(); - - //public slots: - // void newConnection(); - -private: - QTcpServer *server_; - QTcpSocket *socket_; -}; - class BasicLoginWidget : public QWidget { public: BasicLoginWidget(); - ~BasicLoginWidget(); struct { QVBoxLayout layout; @@ -57,9 +35,14 @@ public: QLabel unableToOpenBrowserHelper; } ui_; - //private: + void closeHttpServer(); + +private: // Local server listening to login data - LoginServer *loginServer_; + const QHostAddress serverAddress{QHostAddress::LocalHost}; + static const int serverPort = 52107; + QHttpServer *httpServer_; + QTcpServer *tcpServer_; }; class AdvancedLoginWidget : public QWidget