Go to the documentation of this file.
2 #include <QDirIterator>
3 #include <QNetworkInterface>
4 #include <QCoreApplication>
7 #include <QSslCertificate>
10 #include "mythversion.h"
15 #ifdef USING_LIBDNS_SD
26 #include <sys/utsname.h>
29 #define LOC QString("HTTPServer: ")
55 static const QStringList s_dirs = {
"/assets/",
"/3rdParty/",
"/css/",
"/images/",
"/js/",
"/misc/",
"/apps/",
"/xslt/" };
58 for (
const auto & dir : s_dirs)
61 QDirIterator it(
m_config.
m_rootDir + dir, QDir::Dirs | QDir::Readable | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
92 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Server is using port %1 - expected %2")
105 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Server is using port %1 - expected %2")
153 #ifndef QT_NO_OPENSSL
161 LOG(VB_HTTP, LOG_INFO,
LOC +
"SSL is disabled");
169 QString server = QStringLiteral(
"Windows");
171 struct utsname uname_info {};
173 QString server = QStringLiteral(
"%1/%2").arg(uname_info.sysname, uname_info.release);
191 [[maybe_unused]]
bool Ssl)
193 #ifdef USING_LIBDNS_SD
198 m_bonjourSSL =
nullptr;
202 auto host = QHostInfo::localHostName();
204 host = tr(
"Unknown");
209 m_bonjour->Register(
m_config.
m_port, QByteArrayLiteral(
"_http._tcp"),
210 QStringLiteral(
"%1 on %2").arg(QCoreApplication::applicationName(), host).toLatin1().constData(), {});
217 QStringLiteral(
"%1 on %2").arg(QCoreApplication::applicationName(), host).toLatin1().constData(), {});
232 #ifdef USING_LIBDNS_SD
237 m_bonjourSSL =
nullptr;
254 auto * server = qobject_cast<PrivTcpServer*>(QObject::sender());
255 auto ssl = server ? server->GetServerType() ==
kSSLServer :
false;
257 auto name = QString(
"HTTP%1%2").arg(ssl ?
"S" :
"").arg(
m_threadNum++);
279 if (s_reservedPaths.contains(Path, Qt::CaseInsensitive))
281 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Server path '%1' is reserved - ignoring").arg(Path));
312 for (
const auto & path : qAsConst(Paths))
317 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"'%1' is already registered").arg(path));
319 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding path: '%1'").arg(path));
329 for (
const auto & path : qAsConst(Paths))
333 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Removing path: '%1'").arg(path));
363 bool newhandlers =
false;
364 for (
const auto & handler : qAsConst(Handlers))
369 [&handler](
const HTTPHandler& Handler) { return Handler.first == handler.first; }))
371 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding handler for '%1'").arg(handler.first));
377 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Handler '%1' already registered - ignoring")
378 .arg(handler.first));
387 bool stalehandlers =
false;
388 for (
const auto & handler : qAsConst(Handlers))
391 [&handler](
const HTTPHandler& Handler) { return Handler.first == handler.first; });
395 stalehandlers =
true;
404 bool newservices =
false;
405 for (
const auto & service : qAsConst(Services))
412 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding service for '%1'").arg(service.first));
418 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Service '%1' already registered - ignoring")
419 .arg(service.first));
428 bool staleservices =
false;
429 for (
const auto & service : qAsConst(Services))
436 staleservices =
true;
452 LOG(VB_HTTP, LOG_INFO,
LOC + QString(
"Adding error page handler"));
465 bool allipv4 =
false;
466 bool allipv6 =
false;
467 for (
const auto & address : qAsConst(defaults))
469 if (address == QHostAddress::AnyIPv4)
471 else if (address == QHostAddress::AnyIPv6)
474 lookups.append(address.toString());
479 if (allipv4 || allipv6)
481 auto addresses = QNetworkInterface::allAddresses();
482 for (
const auto & address : qAsConst(addresses))
484 if ((allipv4 && address.protocol() == QAbstractSocket::IPv4Protocol) ||
485 (allipv6 && address.protocol() == QAbstractSocket::IPv6Protocol))
487 lookups.append(address.toString());
492 lookups.removeDuplicates();
495 for (
const auto & address : lookups)
524 "https://chromecast.mythtv.org"
526 for (
const auto & extra : extras)
528 QString clean = extra.trimmed();
529 if (clean.startsWith(
"http://") || clean.startsWith(
"https://"))
536 bool addhostname =
true;
539 auto ipaddresses = Info.addresses();
540 for(
auto & address : ipaddresses)
546 results.append(result.toLower());
563 for (
const auto & address : addresses)
583 LOG(VB_GENERAL, LOG_INFO,
LOC +
586 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Allowed origin: %1").arg(address));
595 for (
const auto & address : addresses)
615 LOG(VB_GENERAL, LOG_INFO,
LOC +
616 QString(
"Name resolution complete: %1 'Hosts' found").arg(
m_config.
m_hosts.size()));
618 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Host: %1").arg(address));
~MythHTTPServer() override
void StaleServices(const HTTPServices &Services)
void HostsChanged(const QStringList &Hosts)
QStringList m_allowedOrigins
std::chrono::milliseconds m_timeout
void newTcpConnection(qintptr socket) override
static bool InitSSLServer(QSslConfiguration &Config)
bool isListening(void) const
int GetBackendStatusPort(void)
Returns the locally defined backend status port.
void EnableHTTP(bool Enable)
const char * GetMythSourceVersion()
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
HTTPHandler m_errorPageHandler
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static bool ReservedPath(const QString &Path)
void RemovePaths(const QStringList &Paths)
void AddErrorPageHandler(const HTTPHandler &Handler)
size_t AvailableThreads() const
QSslConfiguration m_sslConfig
QString m_masterIPAddress
int GetMasterServerStatusPort(void)
Returns the Master Backend status port If no master server status port has been defined in the databa...
void AddHandlers(const HTTPHandlers &Handlers)
void NewHandlers(const HTTPHandlers &Handlers)
Add new handlers.
void AddPaths(const QStringList &Paths)
void ServicesChanged(const HTTPServices &Services)
void ResolveMaster(QHostInfo Info)
Add master backend addresses to the allowed Origins list.
void NewServices(const HTTPServices &Services)
void ResolveHost(QHostInfo Info)
Add the results of a reverse lookup to our allowed list.
void ProcessTCPQueueHandler()
void StalePaths(const QStringList &Paths)
size_t MaxThreads() const
void Started(bool Tcp, bool Ssl)
QString GetMasterServerIP(void)
Returns the Master Backend IP address If the address is an IPv6 address, the scope Id is removed.
void HostResolved(QHostInfo Info)
QString GetShareDir(void)
bool IsFrontend(void) const
is this process a frontend process
static QList< QHostAddress > DefaultListen(void)
static QString AddressToString(QHostAddress &Address)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QQueue< qintptr > m_connectionQueue
int GetNumSetting(const QString &key, int defaultval=0)
void MasterResolved(QHostInfo Info)
static QStringList BuildAddressList(QHostInfo &Info)
void HandlersChanged(const HTTPHandlers &Handlers)
#define HTTP_SOCKET_TIMEOUT_MS
void NewErrorPageHandler(const HTTPHandler &Handler)
Add new error page handler.
QString GetValue(const QString &setting)
#define HTTP_SERVICES_DIR
bool IsBackend(void) const
is this process a backend process
void RemoveHandlers(const HTTPHandlers &Handlers)
void StaleHandlers(const HTTPHandlers &Handlers)
QString GetLanguageAndVariant(void)
Returns the user-set language and variant.
void ErrorHandlerChanged(const HTTPHandler &Handler)
void AddThread(MythHTTPThread *Thread)
void EnableDisable(bool Enable)
void NewPaths(const QStringList &Paths)
Add new paths that will serve simple files.
bool listen(QList< QHostAddress > addrs, quint16 port, bool requireall=true, PoolServerType type=kTCPServer)
void AddServices(const HTTPServices &Services)
std::vector< HTTPService > HTTPServices
void RemoveServices(const HTTPServices &Services)
quint16 serverPort(void) const
void PathsChanged(const QStringList &Paths)
std::pair< QString, HTTPFunction > HTTPHandler
void OriginsChanged(const QStringList &Origins)
void BuildOrigins()
Generate a list of allowed 'Origins' for validating CORS requests.
std::pair< QString, HTTPServiceCtor > HTTPService
QString GetSetting(const QString &key, const QString &defaultval="")
std::vector< HTTPHandler > HTTPHandlers
void Init()
Initialise server configuration.