mirror of
https://github.com/zealdocs/zeal.git
synced 2024-11-23 06:13:35 +03:00
feat(core): add HttpServer
Includes cpp-httplib v0.5.6.
This commit is contained in:
parent
58b92765ce
commit
090f527054
@ -3,8 +3,12 @@ add_library(Core STATIC
|
|||||||
applicationsingleton.cpp
|
applicationsingleton.cpp
|
||||||
extractor.cpp
|
extractor.cpp
|
||||||
filemanager.cpp
|
filemanager.cpp
|
||||||
|
httpserver.cpp
|
||||||
networkaccessmanager.cpp
|
networkaccessmanager.cpp
|
||||||
settings.cpp
|
settings.cpp
|
||||||
|
|
||||||
|
# Show headers without .cpp in Qt Creator.
|
||||||
|
httplib.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(Core Registry Ui)
|
target_link_libraries(Core Registry Ui)
|
||||||
@ -15,3 +19,10 @@ target_link_libraries(Core Qt5::Network Qt5::WebKit Qt5::Widgets)
|
|||||||
find_package(LibArchive REQUIRED)
|
find_package(LibArchive REQUIRED)
|
||||||
include_directories(${LibArchive_INCLUDE_DIRS})
|
include_directories(${LibArchive_INCLUDE_DIRS})
|
||||||
target_link_libraries(Core ${LibArchive_LIBRARIES})
|
target_link_libraries(Core ${LibArchive_LIBRARIES})
|
||||||
|
|
||||||
|
# Required by cpp-httplib.
|
||||||
|
if(NOT WIN32)
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
target_link_libraries(Core Threads::Threads)
|
||||||
|
endif()
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "extractor.h"
|
#include "extractor.h"
|
||||||
#include "filemanager.h"
|
#include "filemanager.h"
|
||||||
|
#include "httpserver.h"
|
||||||
#include "networkaccessmanager.h"
|
#include "networkaccessmanager.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ Application::Application(QObject *parent)
|
|||||||
m_networkManager = new NetworkAccessManager(this);
|
m_networkManager = new NetworkAccessManager(this);
|
||||||
|
|
||||||
m_fileManager = new FileManager(this);
|
m_fileManager = new FileManager(this);
|
||||||
|
m_httpServer = new HttpServer(this);
|
||||||
|
|
||||||
// Extractor setup
|
// Extractor setup
|
||||||
m_extractorThread = new QThread(this);
|
m_extractorThread = new QThread(this);
|
||||||
@ -134,6 +136,11 @@ FileManager *Application::fileManager() const
|
|||||||
return m_fileManager;
|
return m_fileManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HttpServer *Application::httpServer() const
|
||||||
|
{
|
||||||
|
return m_httpServer;
|
||||||
|
}
|
||||||
|
|
||||||
QString Application::cacheLocation()
|
QString Application::cacheLocation()
|
||||||
{
|
{
|
||||||
#ifndef PORTABLE_BUILD
|
#ifndef PORTABLE_BUILD
|
||||||
|
@ -45,6 +45,7 @@ namespace Core {
|
|||||||
|
|
||||||
class Extractor;
|
class Extractor;
|
||||||
class FileManager;
|
class FileManager;
|
||||||
|
class HttpServer;
|
||||||
class Settings;
|
class Settings;
|
||||||
|
|
||||||
class Application final : public QObject
|
class Application final : public QObject
|
||||||
@ -64,6 +65,7 @@ public:
|
|||||||
|
|
||||||
Registry::DocsetRegistry *docsetRegistry();
|
Registry::DocsetRegistry *docsetRegistry();
|
||||||
FileManager *fileManager() const;
|
FileManager *fileManager() const;
|
||||||
|
HttpServer *httpServer() const;
|
||||||
|
|
||||||
static QString cacheLocation();
|
static QString cacheLocation();
|
||||||
static QString configLocation();
|
static QString configLocation();
|
||||||
@ -96,6 +98,7 @@ private:
|
|||||||
QNetworkAccessManager *m_networkManager = nullptr;
|
QNetworkAccessManager *m_networkManager = nullptr;
|
||||||
|
|
||||||
FileManager *m_fileManager = nullptr;
|
FileManager *m_fileManager = nullptr;
|
||||||
|
HttpServer *m_httpServer = nullptr;
|
||||||
|
|
||||||
QThread *m_extractorThread = nullptr;
|
QThread *m_extractorThread = nullptr;
|
||||||
Extractor *m_extractor = nullptr;
|
Extractor *m_extractor = nullptr;
|
||||||
|
4786
src/libs/core/httplib.h
Normal file
4786
src/libs/core/httplib.h
Normal file
File diff suppressed because it is too large
Load Diff
100
src/libs/core/httpserver.cpp
Normal file
100
src/libs/core/httpserver.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 Oleg Shparber
|
||||||
|
** Contact: https://go.zealdocs.org/l/contact
|
||||||
|
**
|
||||||
|
** This file is part of Zeal.
|
||||||
|
**
|
||||||
|
** Zeal is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Zeal is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with Zeal. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "httpserver.h"
|
||||||
|
|
||||||
|
#include "application.h"
|
||||||
|
#include "httplib.h"
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
using namespace Zeal::Core;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr char LocalHttpServerHost[] = "127.0.0.22";
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
static Q_LOGGING_CATEGORY(log, "zeal.core.httpserver")
|
||||||
|
|
||||||
|
HttpServer::HttpServer(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
m_server = std::make_unique<httplib::Server>();
|
||||||
|
|
||||||
|
const int port = m_server->bind_to_any_port(LocalHttpServerHost);
|
||||||
|
|
||||||
|
m_baseUrl.setScheme(QStringLiteral("http"));
|
||||||
|
m_baseUrl.setHost(LocalHttpServerHost);
|
||||||
|
m_baseUrl.setPort(port);
|
||||||
|
|
||||||
|
m_server->set_error_handler([](const auto& req, auto& res) {
|
||||||
|
const QString html = QStringLiteral("<b>ERROR %1</b><br><pre>Request path: %2</pre>")
|
||||||
|
.arg(res.status)
|
||||||
|
.arg(QString::fromStdString(req.path));
|
||||||
|
res.set_content(html.toUtf8().data(), "text/html");
|
||||||
|
});
|
||||||
|
|
||||||
|
m_future = std::async(std::launch::async, &httplib::Server::listen_after_bind, m_server.get());
|
||||||
|
|
||||||
|
qCDebug(log, "Listening on %s...", qPrintable(m_baseUrl.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpServer::~HttpServer()
|
||||||
|
{
|
||||||
|
m_server->stop();
|
||||||
|
|
||||||
|
auto status = m_future.wait_for(std::chrono::seconds(2));
|
||||||
|
if (status != std::future_status::ready) {
|
||||||
|
qCWarning(log) << "Failed to stop server within timeout.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl HttpServer::baseUrl() const
|
||||||
|
{
|
||||||
|
return m_baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl HttpServer::mount(const QString &prefix, const QString &path)
|
||||||
|
{
|
||||||
|
const QString pfx = sanitizePrefix(prefix);
|
||||||
|
const bool ok = m_server->set_mount_point(pfx.toUtf8(), path.toUtf8());
|
||||||
|
if (!ok) {
|
||||||
|
qCWarning(log, "Failed to mount '%s' to '%s'.", qPrintable(path), qPrintable(pfx));
|
||||||
|
return QUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(log, "Mounted '%s' to '%s'.", qPrintable(path), qPrintable(pfx));
|
||||||
|
|
||||||
|
QUrl mountUrl = m_baseUrl;
|
||||||
|
mountUrl.setPath(m_baseUrl.path() + pfx);
|
||||||
|
return mountUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString HttpServer::sanitizePrefix(const QString &prefix)
|
||||||
|
{
|
||||||
|
QString pfx = (prefix.startsWith(QLatin1String("/")) ? prefix.right(1) : prefix).toLower();
|
||||||
|
pfx.replace(QRegularExpression(QStringLiteral("[^a-zA-Z0-9-_]")), QStringLiteral("_"));
|
||||||
|
pfx.prepend(QLatin1Char('/'));
|
||||||
|
|
||||||
|
return pfx;
|
||||||
|
}
|
63
src/libs/core/httpserver.h
Normal file
63
src/libs/core/httpserver.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 Oleg Shparber
|
||||||
|
** Contact: https://go.zealdocs.org/l/contact
|
||||||
|
**
|
||||||
|
** This file is part of Zeal.
|
||||||
|
**
|
||||||
|
** Zeal is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Zeal is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with Zeal. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef ZEAL_CORE_HTTPSERVER_H
|
||||||
|
#define ZEAL_CORE_HTTPSERVER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace httplib {
|
||||||
|
class Server;
|
||||||
|
} // namespace httplib
|
||||||
|
|
||||||
|
namespace Zeal {
|
||||||
|
namespace Core {
|
||||||
|
|
||||||
|
class HttpServer : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(HttpServer)
|
||||||
|
public:
|
||||||
|
explicit HttpServer(QObject *parent = nullptr);
|
||||||
|
~HttpServer() override;
|
||||||
|
|
||||||
|
QUrl baseUrl() const;
|
||||||
|
|
||||||
|
QUrl mount(const QString &prefix, const QString &path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QString sanitizePrefix(const QString &prefix);
|
||||||
|
|
||||||
|
std::unique_ptr<httplib::Server> m_server;
|
||||||
|
std::future<bool> m_future;
|
||||||
|
|
||||||
|
QUrl m_baseUrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core
|
||||||
|
} // namespace Zeal
|
||||||
|
|
||||||
|
#endif // ZEAL_CORE_HTTPSERVER_H
|
Loading…
Reference in New Issue
Block a user