fix broadcast of UPnP information

also fixes a Unexpected null receiver warning which might happen now
because of the timing of various deleteLater() calls on disconnect
This commit is contained in:
Michael Zanetti 2017-09-08 16:52:08 +02:00
parent c605bf15fe
commit d74f208a30
2 changed files with 80 additions and 56 deletions

View File

@ -136,18 +136,30 @@ void UpnpDiscovery::requestDeviceInformation(const QNetworkRequest &networkReque
void UpnpDiscovery::respondToSearchRequest(QHostAddress host, int port) void UpnpDiscovery::respondToSearchRequest(QHostAddress host, int port)
{ {
// TODO: Once DeviceManager (and with that this can be moved into the server, use GuhCore's configuration manager instead of parsing the config here...
GuhSettings globalSettings(GuhSettings::SettingsRoleGlobal); GuhSettings globalSettings(GuhSettings::SettingsRoleGlobal);
globalSettings.beginGroup("guhd"); globalSettings.beginGroup("guhd");
QByteArray uuid = globalSettings.value("uuid", QUuid()).toByteArray(); QByteArray uuid = globalSettings.value("uuid", QUuid()).toByteArray();
globalSettings.endGroup(); globalSettings.endGroup();
globalSettings.beginGroup("SSL"); globalSettings.beginGroup("WebServer");
bool useSsl = globalSettings.value("enabled", true).toBool(); int serverPort = -1;
bool useSsl = false;
foreach (const QString &group, globalSettings.childGroups()) {
globalSettings.beginGroup(group);
QHostAddress serverInterface = QHostAddress(globalSettings.value("address").toString());
if (serverInterface == host || serverInterface == QHostAddress("0.0.0.0")) {
serverPort = globalSettings.value("port", -1).toInt();
useSsl = globalSettings.value("sslEnabled", true).toBool();
}
globalSettings.endGroup();
}
globalSettings.endGroup(); globalSettings.endGroup();
globalSettings.beginGroup("WebServer"); if (serverPort == -1) {
int serverPort = globalSettings.value("port", 3333).toInt(); qCWarning(dcConnection) << "No matching WebServer configuration found. Discarding UPnP request!";
globalSettings.endGroup(); return;
}
foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) { foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
foreach (QNetworkAddressEntry entry, interface.addressEntries()) { foreach (QNetworkAddressEntry entry, interface.addressEntries()) {
@ -324,82 +336,94 @@ void UpnpDiscovery::notificationTimeout()
void UpnpDiscovery::sendByeByeMessage() void UpnpDiscovery::sendByeByeMessage()
{ {
// TODO: Once DeviceManager (and with that this can be moved into the server, use GuhCore's configuration manager instead of parsing the config here...
GuhSettings globalSettings(GuhSettings::SettingsRoleGlobal); GuhSettings globalSettings(GuhSettings::SettingsRoleGlobal);
globalSettings.beginGroup("guhd"); globalSettings.beginGroup("guhd");
QByteArray uuid = globalSettings.value("uuid", QUuid()).toByteArray(); QByteArray uuid = globalSettings.value("uuid", QUuid()).toByteArray();
globalSettings.endGroup(); globalSettings.endGroup();
globalSettings.beginGroup("WebServer"); globalSettings.beginGroup("WebServer");
int port = globalSettings.value("port", 3333).toInt(); foreach (const QString &group, globalSettings.childGroups()) {
bool useSsl = globalSettings.value("https", false).toBool(); globalSettings.beginGroup(group);
globalSettings.endGroup(); QHostAddress serverInterface = QHostAddress(globalSettings.value("address").toString());
int serverPort = globalSettings.value("port", -1).toInt();
bool useSsl = globalSettings.value("sslEnabled", true).toBool();
globalSettings.endGroup();
foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) { foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
// listen only on IPv4 foreach (QNetworkAddressEntry entry, interface.addressEntries()) {
foreach (QNetworkAddressEntry entry, interface.addressEntries()) { if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && (serverInterface == QHostAddress("0.0.0.0") || entry.ip() == serverInterface)) {
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
QString locationString; QString locationString;
if (useSsl) { if (useSsl) {
locationString = "https://" + entry.ip().toString() + ":" + QString::number(port) + "/server.xml"; locationString = "https://" + entry.ip().toString() + ":" + QString::number(serverPort) + "/server.xml";
} else { } else {
locationString = "http://" + entry.ip().toString() + ":" + QString::number(port) + "/server.xml"; locationString = "http://" + entry.ip().toString() + ":" + QString::number(serverPort) + "/server.xml";
}
// http://upnp.org/specs/basic/UPnP-basic-Basic-v1-Device.pdf
QByteArray byebyeMessage = QByteArray("NOTIFY * HTTP/1.1\r\n"
"HOST:239.255.255.250:1900\r\n"
"CACHE-CONTROL: max-age=1900\r\n"
"LOCATION: " + locationString.toUtf8() + "\r\n"
"NT:urn:schemas-upnp-org:device:Basic:1\r\n"
"USN:uuid:" + uuid + "::urn:schemas-upnp-org:device:Basic:1\r\n"
"NTS: ssdp:byebye\r\n"
"SERVER: guh/" + QByteArray(GUH_VERSION_STRING) + " UPnP/1.1 \r\n"
"\r\n");
sendToMulticast(byebyeMessage);
} }
// http://upnp.org/specs/basic/UPnP-basic-Basic-v1-Device.pdf
QByteArray byebyeMessage = QByteArray("NOTIFY * HTTP/1.1\r\n"
"HOST:239.255.255.250:1900\r\n"
"CACHE-CONTROL: max-age=1900\r\n"
"LOCATION: " + locationString.toUtf8() + "\r\n"
"NT:urn:schemas-upnp-org:device:Basic:1\r\n"
"USN:uuid:" + uuid + "::urn:schemas-upnp-org:device:Basic:1\r\n"
"NTS: ssdp:byebye\r\n"
"SERVER: guh/" + QByteArray(GUH_VERSION_STRING) + " UPnP/1.1 \r\n"
"\r\n");
sendToMulticast(byebyeMessage);
} }
} }
} }
globalSettings.endGroup();
} }
void UpnpDiscovery::sendAliveMessage() void UpnpDiscovery::sendAliveMessage()
{ {
// TODO: Once DeviceManager (and with that this can be moved into the server, use GuhCore's configuration manager instead of parsing the config here...
GuhSettings globalSettings(GuhSettings::SettingsRoleGlobal); GuhSettings globalSettings(GuhSettings::SettingsRoleGlobal);
globalSettings.beginGroup("guhd"); globalSettings.beginGroup("guhd");
QByteArray uuid = globalSettings.value("uuid", QUuid()).toByteArray(); QByteArray uuid = globalSettings.value("uuid", QUuid()).toByteArray();
globalSettings.endGroup(); globalSettings.endGroup();
globalSettings.beginGroup("WebServer"); globalSettings.beginGroup("WebServer");
int port = globalSettings.value("port", 3333).toInt(); foreach (const QString &group, globalSettings.childGroups()) {
bool useSsl = globalSettings.value("https", false).toBool(); globalSettings.beginGroup(group);
globalSettings.endGroup(); QHostAddress serverInterface = QHostAddress(globalSettings.value("address").toString());
int serverPort = globalSettings.value("port", -1).toInt();
bool useSsl = globalSettings.value("sslEnabled", true).toBool();
globalSettings.endGroup();
foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) { foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
// listen only on IPv4 foreach (QNetworkAddressEntry entry, interface.addressEntries()) {
foreach (QNetworkAddressEntry entry, interface.addressEntries()) { if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && (serverInterface == QHostAddress("0.0.0.0") || entry.ip() == serverInterface)) {
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
QString locationString; QString locationString;
if (useSsl) { if (useSsl) {
locationString = "https://" + entry.ip().toString() + ":" + QString::number(port) + "/server.xml"; locationString = "https://" + entry.ip().toString() + ":" + QString::number(serverPort) + "/server.xml";
} else { } else {
locationString = "http://" + entry.ip().toString() + ":" + QString::number(port) + "/server.xml"; locationString = "http://" + entry.ip().toString() + ":" + QString::number(serverPort) + "/server.xml";
}
// http://upnp.org/specs/basic/UPnP-basic-Basic-v1-Device.pdf
QByteArray aliveMessage = QByteArray("NOTIFY * HTTP/1.1\r\n"
"HOST:239.255.255.250:1900\r\n"
"CACHE-CONTROL: max-age=1900\r\n"
"LOCATION: " + locationString.toUtf8() + "\r\n"
"NT:urn:schemas-upnp-org:device:Basic:1\r\n"
"USN:uuid:" + uuid + "::urn:schemas-upnp-org:device:Basic:1\r\n"
"NTS: ssdp:alive\r\n"
"SERVER: guh/" + QByteArray(GUH_VERSION_STRING) + " UPnP/1.1 \r\n"
"\r\n");
sendToMulticast(aliveMessage);
} }
// http://upnp.org/specs/basic/UPnP-basic-Basic-v1-Device.pdf
QByteArray aliveMessage = QByteArray("NOTIFY * HTTP/1.1\r\n"
"HOST:239.255.255.250:1900\r\n"
"CACHE-CONTROL: max-age=1900\r\n"
"LOCATION: " + locationString.toUtf8() + "\r\n"
"NT:urn:schemas-upnp-org:device:Basic:1\r\n"
"USN:uuid:" + uuid + "::urn:schemas-upnp-org:device:Basic:1\r\n"
"NTS: ssdp:alive\r\n"
"SERVER: guh/" + QByteArray(GUH_VERSION_STRING) + " UPnP/1.1 \r\n"
"\r\n");
sendToMulticast(aliveMessage);
} }
} }
} }
globalSettings.endGroup();
} }
void UpnpDiscovery::discoverTimeout() void UpnpDiscovery::discoverTimeout()

View File

@ -768,7 +768,7 @@ void WebServerClient::removeConnection(QSslSocket *socket)
m_runningConnections.remove(timer); m_runningConnections.remove(timer);
m_connections.removeAll(socket); m_connections.removeAll(socket);
timer->deleteLater(); delete timer;
} }
/*! Resets the connection timeout for the given \a socket. If the socket will not be used for 12 seconds the /*! Resets the connection timeout for the given \a socket. If the socket will not be used for 12 seconds the