Prova connessione: timeout 30s, busy indicator, normalizzazione https://, log qDebug per debug su device

This commit is contained in:
2026-08-12 10:58:34 +02:00
parent 40fa34a0d2
commit 5f97cb45bf
2 changed files with 39 additions and 2 deletions
+20 -1
View File
@@ -6,6 +6,7 @@ Page {
property string testResult: "" property string testResult: ""
property bool testOk: false property bool testOk: false
property bool testing: false
SilicaFlickable { SilicaFlickable {
anchors.fill: parent anchors.fill: parent
@@ -58,9 +59,20 @@ Page {
Button { Button {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
text: "Prova connessione" text: "Prova connessione"
enabled: !page.testing
onClicked: testConnection() onClicked: testConnection()
} }
Item {
width: parent.width
height: page.testing ? Theme.itemSizeSmall : 0
BusyIndicator {
anchors.horizontalCenter: parent.horizontalCenter
running: page.testing
size: BusyIndicatorSize.Small
}
}
Label { Label {
x: Theme.horizontalPageMargin x: Theme.horizontalPageMargin
width: parent.width - 2 * Theme.horizontalPageMargin width: parent.width - 2 * Theme.horizontalPageMargin
@@ -75,12 +87,17 @@ Page {
} }
function testConnection() { function testConnection() {
var base = appSettings.baseUrl var base = appSettings.serverUrl.trim()
if (base.length === 0) { if (base.length === 0) {
page.testResult = "Inserisci l'indirizzo del server" page.testResult = "Inserisci l'indirizzo del server"
page.testOk = false page.testOk = false
return return
} }
// normalizza: senza schema aggiunge https:// e lo salva nel campo
if (base.indexOf("http://") !== 0 && base.indexOf("https://") !== 0)
base = "https://" + base
appSettings.serverUrl = base
page.testing = true
page.testResult = "Verifica in corso…" page.testResult = "Verifica in corso…"
apiClient.getFeed(base + "/opds") apiClient.getFeed(base + "/opds")
} }
@@ -90,12 +107,14 @@ Page {
onFeedReady: { onFeedReady: {
if (pageStack.currentPage !== page) if (pageStack.currentPage !== page)
return return
page.testing = false
page.testOk = true page.testOk = true
page.testResult = "Connessione OK: " + entries.length + " sezioni trovate" page.testResult = "Connessione OK: " + entries.length + " sezioni trovate"
} }
onFeedError: { onFeedError: {
if (pageStack.currentPage !== page) if (pageStack.currentPage !== page)
return return
page.testing = false
page.testOk = false page.testOk = false
page.testResult = message page.testResult = message
} }
+19 -1
View File
@@ -4,6 +4,7 @@
#include "settings.h" #include "settings.h"
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QDebug>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
@@ -11,6 +12,7 @@
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QSslError> #include <QSslError>
#include <QStandardPaths> #include <QStandardPaths>
#include <QTimer>
#include <QUrl> #include <QUrl>
ApiClient::ApiClient(Settings *settings, QObject *parent) ApiClient::ApiClient(Settings *settings, QObject *parent)
@@ -56,24 +58,37 @@ QNetworkReply *ApiClient::startGet(const QUrl &url)
static_cast<void (QNetworkReply::*)(const QList<QSslError> &)>( static_cast<void (QNetworkReply::*)(const QList<QSslError> &)>(
&QNetworkReply::ignoreSslErrors)); &QNetworkReply::ignoreSslErrors));
} }
// timeout di sicurezza (30 s): senza, una richiesta verso un host irraggiungibile
// resta appesa all'infinito
QTimer *timer = new QTimer(reply);
timer->setSingleShot(true);
timer->setInterval(30000);
connect(timer, &QTimer::timeout, reply, &QNetworkReply::abort);
timer->start();
return reply; return reply;
} }
void ApiClient::getFeed(const QString &url) void ApiClient::getFeed(const QString &url)
{ {
qDebug() << "getFeed request:" << url;
QNetworkReply *reply = startGet(QUrl(url)); QNetworkReply *reply = startGet(QUrl(url));
connect(reply, &QNetworkReply::finished, this, [this, reply]() { connect(reply, &QNetworkReply::finished, this, [this, reply]() {
reply->deleteLater(); reply->deleteLater();
const int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); const int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (reply->error() != QNetworkReply::NoError || status >= 400) { if (reply->error() != QNetworkReply::NoError || status >= 400) {
QString message; QString message;
if (status == 401) if (reply->error() == QNetworkReply::OperationCanceledError)
message = QStringLiteral("Timeout: il server non risponde (30 s)");
else if (status == 401)
message = QStringLiteral( message = QStringLiteral(
"Autenticazione richiesta (401). Controlla utente e password."); "Autenticazione richiesta (401). Controlla utente e password.");
else if (status == 404) else if (status == 404)
message = QStringLiteral("Endpoint non trovato (404). Controlla l'indirizzo."); message = QStringLiteral("Endpoint non trovato (404). Controlla l'indirizzo.");
else else
message = reply->errorString(); message = reply->errorString();
qDebug() << "getFeed ERROR status:" << status
<< "error:" << reply->error() << "-" << message;
emit feedError(message); emit feedError(message);
return; return;
} }
@@ -84,8 +99,11 @@ void ApiClient::getFeed(const QString &url)
QString feedTitle; QString feedTitle;
QString parseError; QString parseError;
if (OpdsParser::parse(body, &entries, &nextUrl, &feedTitle, &parseError)) { if (OpdsParser::parse(body, &entries, &nextUrl, &feedTitle, &parseError)) {
qDebug() << "getFeed OK status:" << status
<< "entries:" << entries.size();
emit feedReady(entries, resolveUrl(nextUrl), feedTitle); emit feedReady(entries, resolveUrl(nextUrl), feedTitle);
} else { } else {
qDebug() << "getFeed parse error:" << parseError;
emit feedError(parseError.isEmpty() emit feedError(parseError.isEmpty()
? QStringLiteral("Risposta non valida dal server") ? QStringLiteral("Risposta non valida dal server")
: parseError); : parseError);