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/" };
66 for (
const auto & dir : s_dirs)
69 QDirIterator it(
m_config.
m_rootDir + dir, QDir::Dirs | QDir::Readable | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
100 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Server is using port %1 - expected %2")
113 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Server is using port %1 - expected %2")
169 LOG(VB_HTTP, LOG_INFO,
LOC +
"SSL is disabled");
177 QString server = QStringLiteral(
"Windows");
179 struct utsname uname_info {};
181 QString server = QStringLiteral(
"%1/%2").arg(uname_info.sysname, uname_info.release);
199 [[maybe_unused]]
bool Ssl)
206 m_bonjourSSL =
nullptr;
210 auto host = QHostInfo::localHostName();
212 host = tr(
"Unknown");
217 m_bonjour->Register(
m_config.
m_port, QByteArrayLiteral(
"_http._tcp"),
218 QStringLiteral(
"%1 on %2").arg(QCoreApplication::applicationName(), host).toLatin1().constData(), {});
225 QStringLiteral(
"%1 on %2").arg(QCoreApplication::applicationName(), host).toLatin1().constData(), {});
245 m_bonjourSSL =
nullptr;
263 auto name = QString(
"HTTP%1%2").arg(entry.m_ssl ?
"S" :
"").arg(
m_threadNum++);
277 auto * server = qobject_cast<PrivTcpServer*>(QObject::sender());
288 if (s_reservedPaths.contains(Path, Qt::CaseInsensitive))
290 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Server path '%1' is reserved - ignoring").arg(Path));
321 for (
const auto & path : std::as_const(Paths))
326 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"'%1' is already registered").arg(path));
328 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding path: '%1'").arg(path));
338 for (
const auto & path : std::as_const(Paths))
342 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Removing path: '%1'").arg(path));
372 bool newhandlers =
false;
373 for (
const auto & handler : std::as_const(Handlers))
378 [&handler](
const HTTPHandler& Handler) { return Handler.first == handler.first; }))
380 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding handler for '%1'").arg(handler.first));
386 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Handler '%1' already registered - ignoring")
387 .arg(handler.first));
396 bool stalehandlers =
false;
397 for (
const auto & handler : std::as_const(Handlers))
400 &HTTPHandler::first);
404 stalehandlers =
true;
413 bool newservices =
false;
414 for (
const auto & service : std::as_const(Services))
421 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding service for '%1'").arg(service.first));
427 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Service '%1' already registered - ignoring")
428 .arg(service.first));
437 bool staleservices =
false;
438 for (
const auto & service : std::as_const(Services))
441 &HTTPService::first);
445 staleservices =
true;
461 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding error page handler"));
474 bool allipv4 =
false;
475 bool allipv6 =
false;
476 for (
const auto & address : std::as_const(defaults))
478 if (address == QHostAddress::AnyIPv4)
480 else if (address == QHostAddress::AnyIPv6)
483 lookups.append(address.toString());
488 if (allipv4 || allipv6)
490 auto addresses = QNetworkInterface::allAddresses();
491 for (
const auto & address : std::as_const(addresses))
493 if ((allipv4 && address.protocol() == QAbstractSocket::IPv4Protocol) ||
494 (allipv6 && address.protocol() == QAbstractSocket::IPv6Protocol))
496 lookups.append(address.toString());
501 lookups.removeDuplicates();
504 for (
const auto & address : lookups)
533 "https://chromecast.mythtv.org"
535 for (
const auto & extra : std::as_const(extras))
537 QString clean = extra.trimmed();
538 if (clean.startsWith(
"http://") || clean.startsWith(
"https://"))
545 bool addhostname =
true;
548 auto ipaddresses = Info.addresses();
549 for(
auto & address : ipaddresses)
555 results.append(result.toLower());
572 for (
const auto & address : std::as_const(addresses))
592 LOG(VB_GENERAL, LOG_INFO,
LOC +
595 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Allowed origin: %1").arg(address));
604 for (
const auto & address : std::as_const(addresses))
624 LOG(VB_GENERAL, LOG_INFO,
LOC +
625 QString(
"Name resolution complete: %1 'Hosts' found").arg(
m_config.
m_hosts.size()));
627 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Host: %1").arg(address));
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()