ping server
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
#include "ApiClient.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QNetworkReply>
|
||||
#include <QRandomGenerator>
|
||||
#include <QRegularExpression>
|
||||
#include <QUrl>
|
||||
#include <QUrlQuery>
|
||||
|
||||
ApiClient::ApiClient(QObject* parent) : QObject(parent) {}
|
||||
|
||||
static QString md5Hex(const QByteArray& data) {
|
||||
return QString(
|
||||
QCryptographicHash::hash(data, QCryptographicHash::Md5).toHex());
|
||||
}
|
||||
|
||||
// Subsonic/OpenSubsonic Token-Auth: t = md5(password + salt), s = salt
|
||||
// :contentReference[oaicite:5]{index=5}
|
||||
QString ApiClient::buildAuthQuery(const QString& user,
|
||||
const QString& password) const {
|
||||
const QString salt =
|
||||
QString::number(QRandomGenerator::global()->generate(), 16);
|
||||
const QString token = md5Hex((password + salt).toUtf8());
|
||||
|
||||
QUrlQuery q;
|
||||
q.addQueryItem("u", user);
|
||||
q.addQueryItem("t", token);
|
||||
q.addQueryItem("s", salt);
|
||||
q.addQueryItem("v", "1.16.1"); // Navidrome ist kompatibel zu 1.16.1
|
||||
// :contentReference[oaicite:6]{index=6}
|
||||
q.addQueryItem("c", "myQtClient");
|
||||
q.addQueryItem("f", "json");
|
||||
return q.toString(QUrl::FullyEncoded);
|
||||
}
|
||||
|
||||
void ApiClient::setLastStatus(const QString& s) {
|
||||
if (m_lastStatus == s) return;
|
||||
m_lastStatus = s;
|
||||
emit lastStatusChanged();
|
||||
}
|
||||
|
||||
void ApiClient::ping(const QString& host, const QString& user,
|
||||
const QString& password) {
|
||||
if (host.trimmed().isEmpty()) {
|
||||
emit pingFinished(false, "Host ist leer.");
|
||||
return;
|
||||
}
|
||||
|
||||
QUrl base(host);
|
||||
if (!base.isValid()) {
|
||||
emit pingFinished(false, "Host-URL ist ungültig.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Sauber zusammensetzen, egal ob host mit/ohne trailing slash kommt
|
||||
QUrl url(base.toString().remove(QRegularExpression("/+$")) +
|
||||
"/rest/ping.view");
|
||||
QUrlQuery q(buildAuthQuery(user, password));
|
||||
url.setQuery(q);
|
||||
|
||||
setLastStatus("Sende Ping…");
|
||||
|
||||
QNetworkRequest req(url);
|
||||
req.setHeader(QNetworkRequest::UserAgentHeader, "navidrome_client/0.1");
|
||||
|
||||
QNetworkReply* reply = m_manager.get(req);
|
||||
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||
const auto err = reply->error();
|
||||
const QByteArray body = reply->readAll();
|
||||
reply->deleteLater();
|
||||
|
||||
if (err != QNetworkReply::NoError) {
|
||||
const QString msg = "Netzwerkfehler: " + reply->errorString();
|
||||
setLastStatus(msg);
|
||||
emit pingFinished(false, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fürs Erste: “kommt was zurück?” reicht. Später kannst du JSON parsen und
|
||||
// "status":"ok" prüfen.
|
||||
const QString msg =
|
||||
"Ping OK, Antwort: " + QString::fromUtf8(body.left(300));
|
||||
setLastStatus("Ping OK");
|
||||
emit pingFinished(true, msg);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef APICLIENT_H
|
||||
#define APICLIENT_H
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QObject>
|
||||
|
||||
class ApiClient : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString lastStatus READ lastStatus NOTIFY lastStatusChanged)
|
||||
|
||||
public:
|
||||
explicit ApiClient(QObject* parent = nullptr);
|
||||
|
||||
Q_INVOKABLE void ping(const QString& host, const QString& user,
|
||||
const QString& password);
|
||||
|
||||
QString lastStatus() const { return m_lastStatus; }
|
||||
|
||||
signals:
|
||||
void pingFinished(bool ok, QString message);
|
||||
void lastStatusChanged();
|
||||
|
||||
private:
|
||||
QString buildAuthQuery(const QString& user, const QString& password) const;
|
||||
void setLastStatus(const QString& s);
|
||||
|
||||
QNetworkAccessManager m_manager;
|
||||
QString m_lastStatus;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user