fix upnp server t0 be more standard compliant
This commit is contained in:
parent
f160a92f92
commit
80b444a62a
@ -128,27 +128,41 @@ void UpnpDiscoveryImplementation::respondToSearchRequest(QHostAddress host, int
|
||||
// TODO: Once DeviceManager (and with that this can be moved into the server, use NymeaCore's configuration manager instead of parsing the config here...
|
||||
NymeaSettings globalSettings(NymeaSettings::SettingsRoleGlobal);
|
||||
globalSettings.beginGroup("nymead");
|
||||
QByteArray uuid = globalSettings.value("uuid", QUuid()).toByteArray();
|
||||
QByteArray uuid = globalSettings.value("uuid", QUuid()).toString().remove(QRegExp("[{}]")).toUtf8();
|
||||
globalSettings.endGroup();
|
||||
|
||||
globalSettings.beginGroup("WebServer");
|
||||
int serverPort = -1;
|
||||
bool useSsl = false;
|
||||
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();
|
||||
}
|
||||
bool ssl = globalSettings.value("sslEnabled", true).toBool();
|
||||
int port = globalSettings.value("port", -1).toInt();
|
||||
globalSettings.endGroup();
|
||||
|
||||
// We prefer unencrypted WebServers in this case. Most UPnP clients will bail out on our certificate...
|
||||
// However, if there is none without encryption, still use one with, so that at least our own clients find it.
|
||||
if (serverPort == -1) { // Don't have a better option yet. Use this.
|
||||
serverPort = port;
|
||||
useSSL = ssl;
|
||||
continue;
|
||||
}
|
||||
if (!ssl && useSSL) { // There is one without ssl. Use that.
|
||||
serverPort = port;
|
||||
useSSL = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
globalSettings.endGroup();
|
||||
|
||||
if (serverPort == -1) {
|
||||
qCWarning(dcConnection) << "No matching WebServer configuration found. Discarding UPnP request!";
|
||||
qCWarning(dcUpnp()) << "No matching WebServer configuration found. Discarding UPnP request! UPnP requires a plaintext webserver.";
|
||||
return;
|
||||
}
|
||||
if (useSSL) {
|
||||
qCWarning(dcUpnp()) << "Could not find a WebServer without SSL. Using one with SSL. This will not work with many clients.";
|
||||
}
|
||||
|
||||
foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
|
||||
foreach (QNetworkAddressEntry entry, interface.addressEntries()) {
|
||||
@ -157,7 +171,7 @@ void UpnpDiscoveryImplementation::respondToSearchRequest(QHostAddress host, int
|
||||
// check subnet
|
||||
if (host.isInSubnet(QHostAddress::parseSubnet(entry.ip().toString() + "/24"))) {
|
||||
QString locationString;
|
||||
if (useSsl) {
|
||||
if (useSSL) {
|
||||
locationString = "https://" + entry.ip().toString() + ":" + QString::number(serverPort) + "/server.xml";
|
||||
} else {
|
||||
locationString = "http://" + entry.ip().toString() + ":" + QString::number(serverPort) + "/server.xml";
|
||||
@ -168,11 +182,10 @@ void UpnpDiscoveryImplementation::respondToSearchRequest(QHostAddress host, int
|
||||
"CACHE-CONTROL: max-age=1900\r\n"
|
||||
"DATE: " + QDateTime::currentDateTime().toString("ddd, dd MMM yyyy hh:mm:ss").toUtf8() + " GMT\r\n"
|
||||
"EXT:\r\n"
|
||||
"CONTENT-LENGTH:0\r\n"
|
||||
"LOCATION: " + locationString.toUtf8() + "\r\n"
|
||||
"SERVER: nymea/" + QByteArray(NYMEA_VERSION_STRING) + " UPnP/1.1 \r\n"
|
||||
"ST:upnp:rootdevice\r\n"
|
||||
"USN:uuid:" + uuid + "::urn:schemas-upnp-org:device:Basic:1\r\n"
|
||||
"ST: upnp:rootdevice\r\n"
|
||||
"USN: uuid:" + uuid + "::urn:schemas-upnp-org:device:Basic:1\r\n"
|
||||
"\r\n");
|
||||
|
||||
qCDebug(dcUpnp()) << QString("Sending response to %1:%2").arg(host.toString()).arg(port);
|
||||
|
||||
@ -605,7 +605,7 @@ bool WebServer::stopServer()
|
||||
|
||||
QByteArray WebServer::createServerXmlDocument(QHostAddress address)
|
||||
{
|
||||
QByteArray uuid = NymeaCore::instance()->configuration()->serverUuid().toByteArray();
|
||||
QByteArray uuid = NymeaCore::instance()->configuration()->serverUuid().toString().remove(QRegExp("[{}]")).toUtf8();
|
||||
|
||||
QByteArray data;
|
||||
QXmlStreamWriter writer(&data);
|
||||
@ -619,57 +619,12 @@ QByteArray WebServer::createServerXmlDocument(QHostAddress address)
|
||||
writer.writeTextElement("minor", "1");
|
||||
writer.writeEndElement(); // specVersion
|
||||
|
||||
if (m_configuration.sslEnabled) {
|
||||
writer.writeTextElement("URLBase", "https://" + address.toString() + ":" + QString::number(m_configuration.port));
|
||||
} else {
|
||||
writer.writeTextElement("URLBase", "http://" + address.toString() + ":" + QString::number(m_configuration.port));
|
||||
}
|
||||
|
||||
ServerConfiguration websocketConfiguration;
|
||||
bool webSocketServerFound = false;
|
||||
foreach (const ServerConfiguration &config, NymeaCore::instance()->configuration()->webSocketServerConfigurations()) {
|
||||
if (config.address == QHostAddress("0.0.0.0") || config.address == address) {
|
||||
if (!webSocketServerFound) {
|
||||
websocketConfiguration = config;
|
||||
webSocketServerFound = true;
|
||||
} else if (!websocketConfiguration.sslEnabled && config.sslEnabled) {
|
||||
// If the previous one is plaintext but we also have a secure one, upgrade to that.
|
||||
websocketConfiguration = config;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (webSocketServerFound) {
|
||||
if (websocketConfiguration.sslEnabled) {
|
||||
writer.writeTextElement("websocketURL", "wss://" + address.toString() + ":" + QString::number(websocketConfiguration.port));
|
||||
} else {
|
||||
writer.writeTextElement("websocketURL", "ws://" + address.toString() + ":" + QString::number(websocketConfiguration.port));
|
||||
}
|
||||
}
|
||||
|
||||
ServerConfiguration tcpServerConfiguration;
|
||||
bool tcpServerFound = false;
|
||||
foreach (const ServerConfiguration &config, NymeaCore::instance()->configuration()->tcpServerConfigurations()) {
|
||||
if (config.address == QHostAddress("0.0.0.0") || config.address == address) {
|
||||
if (!tcpServerFound) {
|
||||
tcpServerConfiguration = config;
|
||||
tcpServerFound = true;
|
||||
} else if (!tcpServerConfiguration.sslEnabled && config.sslEnabled) {
|
||||
// If the previous one is plaintext but we also have a secure one, upgrade to that.
|
||||
tcpServerConfiguration = config;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tcpServerFound) {
|
||||
if (tcpServerConfiguration.sslEnabled) {
|
||||
writer.writeTextElement("nymeaRpcURL", "nymeas://" + address.toString() + ":" + QString::number(tcpServerConfiguration.port));
|
||||
} else {
|
||||
writer.writeTextElement("nymeaRpcURL", "nymea://" + address.toString() + ":" + QString::number(tcpServerConfiguration.port));
|
||||
}
|
||||
}
|
||||
|
||||
writer.writeTextElement("presentationURL", "/");
|
||||
|
||||
QString presentationUrl = QString("%1://%2:%3")
|
||||
.arg(m_configuration.sslEnabled ? "https" : "http")
|
||||
.arg(address.toString())
|
||||
.arg(m_configuration.port);
|
||||
writer.writeStartElement("device");
|
||||
writer.writeTextElement("presentationURL", presentationUrl);
|
||||
writer.writeTextElement("deviceType", "urn:schemas-upnp-org:device:Basic:1");
|
||||
writer.writeTextElement("friendlyName", NymeaCore::instance()->configuration()->serverName());
|
||||
writer.writeTextElement("manufacturer", "guh GmbH");
|
||||
@ -764,6 +719,36 @@ QByteArray WebServer::createServerXmlDocument(QHostAddress address)
|
||||
|
||||
writer.writeEndElement(); // iconList
|
||||
|
||||
writer.writeStartElement("serviceList");
|
||||
|
||||
int counter = 1;
|
||||
int sslCounter = 1;
|
||||
foreach (const ServerConfiguration &config, NymeaCore::instance()->configuration()->webSocketServerConfigurations()) {
|
||||
if (config.address == QHostAddress("0.0.0.0") || config.address == address) {
|
||||
writer.writeStartElement("service");
|
||||
writer.writeTextElement("serviceType", QString("urn:nymea.io:service:%1:%2").arg(config.sslEnabled ? "wss" : "ws").arg(config.sslEnabled ? sslCounter : counter));
|
||||
writer.writeTextElement("serviceId", QString("urn:nymea.io:serviceId:%1:%2").arg(config.sslEnabled ? "wss" : "ws").arg(config.sslEnabled ? sslCounter++ : counter++));
|
||||
QString url = QString("%1%2:%3").arg(config.sslEnabled ? "wss://" : "ws://").arg(address.toString()).arg(config.port);
|
||||
writer.writeTextElement("SCPDURL", url);
|
||||
writer.writeEndElement(); // service
|
||||
}
|
||||
}
|
||||
|
||||
counter = 1;
|
||||
sslCounter = 1;
|
||||
foreach (const ServerConfiguration &config, NymeaCore::instance()->configuration()->tcpServerConfigurations()) {
|
||||
if (config.address == QHostAddress("0.0.0.0") || config.address == address) {
|
||||
writer.writeStartElement("service");
|
||||
writer.writeTextElement("serviceType", QString("urn:nymea.io:service:%1:%2").arg(config.sslEnabled ? "nymeas" : "nymea").arg(config.sslEnabled ? sslCounter : counter));
|
||||
writer.writeTextElement("serviceId", QString("urn:nymea.io:serviceId:%1:%2").arg(config.sslEnabled ? "nymeas" : "nymea").arg(config.sslEnabled ? sslCounter++ : counter++));
|
||||
QString url = QString("%1%2:%3").arg(config.sslEnabled ? "nymeas://" : "nymea://").arg(address.toString()).arg(config.port);
|
||||
writer.writeTextElement("SCPDURL", url);
|
||||
writer.writeEndElement(); // service
|
||||
}
|
||||
}
|
||||
|
||||
writer.writeEndElement(); // serviceList
|
||||
|
||||
writer.writeEndElement(); // device
|
||||
writer.writeEndElement(); // root
|
||||
writer.writeEndDocument();
|
||||
|
||||
Reference in New Issue
Block a user