6#if QT_VERSION >= QT_VERSION_CHECK(6,5,0)
7#include <QtSystemDetection>
10#include <QNetworkInterface>
11#include <QCoreApplication>
14#include <QSslCertificate>
17#include "mythconfig.h"
18#include "mythversion.h"
34#include <sys/utsname.h>
37#define LOC QString("HTTPServer: ")
63 static const QStringList s_dirs = {
"/assets/",
"/3rdParty/",
"/css/",
"/images/",
"/apps/",
"/xslt/" };
68 static constexpr int approximate_count {60};
70 dirs.reserve(approximate_count);
71 for (
const auto & dir : s_dirs)
74 QDirIterator it(
m_config.
m_rootDir + dir, QDir::Dirs | QDir::Readable | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
105 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Server is using port %1 - expected %2")
118 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Server is using port %1 - expected %2")
174 LOG(VB_HTTP, LOG_INFO,
LOC +
"SSL is disabled");
182 QString server = QStringLiteral(
"Windows");
184 struct utsname uname_info {};
186 QString server = QStringLiteral(
"%1/%2").arg(uname_info.sysname, uname_info.release);
204 [[maybe_unused]]
bool Ssl)
211 m_bonjourSSL =
nullptr;
215 auto host = QHostInfo::localHostName();
217 host = tr(
"Unknown");
222 m_bonjour->Register(
m_config.
m_port, QByteArrayLiteral(
"_http._tcp"),
223 QStringLiteral(
"%1 on %2").arg(QCoreApplication::applicationName(), host).toLatin1().constData(), {});
230 QStringLiteral(
"%1 on %2").arg(QCoreApplication::applicationName(), host).toLatin1().constData(), {});
250 m_bonjourSSL =
nullptr;
268 auto name = QString(
"HTTP%1%2").arg(entry.m_ssl ?
"S" :
"").arg(
m_threadNum++);
282 auto * server = qobject_cast<PrivTcpServer*>(QObject::sender());
293 if (s_reservedPaths.contains(Path, Qt::CaseInsensitive))
295 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Server path '%1' is reserved - ignoring").arg(Path));
326 for (
const auto & path : std::as_const(Paths))
331 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"'%1' is already registered").arg(path));
333 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding path: '%1'").arg(path));
343 for (
const auto & path : std::as_const(Paths))
347 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Removing path: '%1'").arg(path));
377 bool newhandlers =
false;
378 for (
const auto & handler : std::as_const(Handlers))
383 [&handler](
const HTTPHandler& Handler) { return Handler.first == handler.first; }))
385 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding handler for '%1'").arg(handler.first));
391 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Handler '%1' already registered - ignoring")
392 .arg(handler.first));
401 bool stalehandlers =
false;
402 for (
const auto & handler : std::as_const(Handlers))
405 &HTTPHandler::first);
409 stalehandlers =
true;
418 bool newservices =
false;
419 for (
const auto & service : std::as_const(Services))
426 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding service for '%1'").arg(service.first));
432 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Service '%1' already registered - ignoring")
433 .arg(service.first));
442 bool staleservices =
false;
443 for (
const auto & service : std::as_const(Services))
446 &HTTPService::first);
450 staleservices =
true;
466 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding error page handler"));
479 bool allipv4 =
false;
480 bool allipv6 =
false;
481 for (
const auto & address : std::as_const(defaults))
483 if (address == QHostAddress::AnyIPv4)
485 else if (address == QHostAddress::AnyIPv6)
488 lookups.append(address.toString());
493 if (allipv4 || allipv6)
495 auto addresses = QNetworkInterface::allAddresses();
496 for (
const auto & address : std::as_const(addresses))
498 if ((allipv4 && address.protocol() == QAbstractSocket::IPv4Protocol) ||
499 (allipv6 && address.protocol() == QAbstractSocket::IPv6Protocol))
501 lookups.append(address.toString());
506 lookups.removeDuplicates();
509 for (
const auto & address : lookups)
538 "https://chromecast.mythtv.org"
540 for (
const auto & extra : std::as_const(extras))
542 QString clean = extra.trimmed();
543 if (clean.startsWith(
"http://") || clean.startsWith(
"https://"))
550 bool addhostname =
true;
553 auto ipaddresses = Info.addresses();
554 results.reserve(ipaddresses.count() + 1);
555 for(
auto & address : ipaddresses)
561 results.append(result.toLower());
578 for (
const auto & address : std::as_const(addresses))
598 LOG(VB_GENERAL, LOG_INFO,
LOC +
601 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Allowed origin: %1").arg(address));
610 for (
const auto & address : std::as_const(addresses))
630 LOG(VB_GENERAL, LOG_INFO,
LOC +
631 QString(
"Name resolution complete: %1 'Hosts' found").arg(
m_config.
m_hosts.size()));
633 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Host: %1").arg(address));
637#include "moc_mythhttpserver.cpp"
bool IsFrontend(void) const
is this process a frontend process
QString GetMasterServerIP(void)
Returns the Master Backend IP address If the address is an IPv6 address, the scope Id is removed.
QString GetSetting(const QString &key, const QString &defaultval="")
int GetBackendStatusPort(void)
Returns the locally defined backend status port.
bool IsBackend(void) const
is this process a backend process
int GetMasterServerStatusPort(void)
Returns the Master Backend status port If no master server status port has been defined in the databa...
int GetNumSetting(const QString &key, int defaultval=0)
QString GetLanguageAndVariant(void)
Returns the user-set language and variant.
QSslConfiguration m_sslConfig
std::chrono::milliseconds m_timeout
HTTPHandler m_errorPageHandler
QStringList m_allowedOrigins
static bool InitSSLServer(QSslConfiguration &Config)
void EnableDisable(bool Enable)
void RemoveServices(const HTTPServices &Services)
void NewErrorPageHandler(const HTTPHandler &Handler)
Add new error page handler.
~MythHTTPServer() override
void ServicesChanged(const HTTPServices &Services)
void MasterResolved(QHostInfo Info)
static bool ReservedPath(const QString &Path)
void Started(bool Tcp, bool Ssl)
void RemovePaths(const QStringList &Paths)
QQueue< MythTcpQueueEntry > m_connectionQueue
void Init()
Initialise server configuration.
void BuildOrigins()
Generate a list of allowed 'Origins' for validating CORS requests.
void StalePaths(const QStringList &Paths)
void StaleHandlers(const HTTPHandlers &Handlers)
void EnableHTTP(bool Enable)
void HandlersChanged(const HTTPHandlers &Handlers)
void StaleServices(const HTTPServices &Services)
void ErrorHandlerChanged(const HTTPHandler &Handler)
void AddHandlers(const HTTPHandlers &Handlers)
void OriginsChanged(const QStringList &Origins)
void AddServices(const HTTPServices &Services)
void AddErrorPageHandler(const HTTPHandler &Handler)
static QStringList BuildAddressList(QHostInfo &Info)
void newTcpConnection(qintptr socket) override
void NewPaths(const QStringList &Paths)
Add new paths that will serve simple files.
void ResolveMaster(QHostInfo Info)
Add master backend addresses to the allowed Origins list.
void RemoveHandlers(const HTTPHandlers &Handlers)
void NewServices(const HTTPServices &Services)
void PathsChanged(const QStringList &Paths)
void ResolveHost(QHostInfo Info)
Add the results of a reverse lookup to our allowed list.
void ProcessTCPQueueHandler()
void AddPaths(const QStringList &Paths)
void HostResolved(QHostInfo Info)
QString m_masterIPAddress
void HostsChanged(const QStringList &Hosts)
void NewHandlers(const HTTPHandlers &Handlers)
Add new handlers.
size_t MaxThreads() const
size_t AvailableThreads() const
void AddThread(MythHTTPThread *Thread)
static QString AddressToString(QHostAddress &Address)
static QList< QHostAddress > DefaultListen(void)
bool listen(QList< QHostAddress > addrs, quint16 port, bool requireall=true, PoolServerType type=kTCPServer)
bool isListening(void) const
quint16 serverPort(void) const
QString GetValue(const QString &setting)
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString GetShareDir(void)
static constexpr int HTTP_SOCKET_TIMEOUT_MS
std::pair< QString, HTTPServiceCtor > HTTPService
std::vector< HTTPHandler > HTTPHandlers
std::vector< HTTPService > HTTPServices
std::pair< QString, HTTPFunction > HTTPHandler
#define HTTP_SERVICES_DIR
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
const char * GetMythSourceVersion()