mirror of
https://github.com/zealdocs/zeal.git
synced 2024-11-22 21:53:03 +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
|
||||
extractor.cpp
|
||||
filemanager.cpp
|
||||
httpserver.cpp
|
||||
networkaccessmanager.cpp
|
||||
settings.cpp
|
||||
|
||||
# Show headers without .cpp in Qt Creator.
|
||||
httplib.h
|
||||
)
|
||||
|
||||
target_link_libraries(Core Registry Ui)
|
||||
@ -15,3 +19,10 @@ target_link_libraries(Core Qt5::Network Qt5::WebKit Qt5::Widgets)
|
||||
find_package(LibArchive REQUIRED)
|
||||
include_directories(${LibArchive_INCLUDE_DIRS})
|
||||
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 "filemanager.h"
|
||||
#include "httpserver.h"
|
||||
#include "networkaccessmanager.h"
|
||||
#include "settings.h"
|
||||
|
||||
@ -63,6 +64,7 @@ Application::Application(QObject *parent)
|
||||
m_networkManager = new NetworkAccessManager(this);
|
||||
|
||||
m_fileManager = new FileManager(this);
|
||||
m_httpServer = new HttpServer(this);
|
||||
|
||||
// Extractor setup
|
||||
m_extractorThread = new QThread(this);
|
||||
@ -134,6 +136,11 @@ FileManager *Application::fileManager() const
|
||||
return m_fileManager;
|
||||
}
|
||||
|
||||
HttpServer *Application::httpServer() const
|
||||
{
|
||||
return m_httpServer;
|
||||
}
|
||||
|
||||
QString Application::cacheLocation()
|
||||
{
|
||||
#ifndef PORTABLE_BUILD
|
||||
|
@ -45,6 +45,7 @@ namespace Core {
|
||||
|
||||
class Extractor;
|
||||
class FileManager;
|
||||
class HttpServer;
|
||||
class Settings;
|
||||
|
||||
class Application final : public QObject
|
||||
@ -64,6 +65,7 @@ public:
|
||||
|
||||
Registry::DocsetRegistry *docsetRegistry();
|
||||
FileManager *fileManager() const;
|
||||
HttpServer *httpServer() const;
|
||||
|
||||
static QString cacheLocation();
|
||||
static QString configLocation();
|
||||
@ -96,6 +98,7 @@ private:
|
||||
QNetworkAccessManager *m_networkManager = nullptr;
|
||||
|
||||
FileManager *m_fileManager = nullptr;
|
||||
HttpServer *m_httpServer = nullptr;
|
||||
|
||||
QThread *m_extractorThread = 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