Risoluzione URL RFC 3986: fix sottopath raddoppiato (/calibre/calibre) + messaggio chiaro per risposte HTML

This commit is contained in:
2026-08-12 12:13:56 +02:00
parent dea79aff49
commit 62452b470e
2 changed files with 27 additions and 8 deletions
+5
View File
@@ -121,6 +121,11 @@ Page {
if (u.indexOf("http://") === 0 || u.indexOf("https://") === 0)
return u
var base = appSettings.baseUrl
// il server dietro sottopath (es. /calibre) emette link che lo includono già:
// evita di raddoppiarlo
var basePath = base.replace(/^https?:\/\/[^\/]+/, "")
if (basePath.length > 1 && u.indexOf(basePath) === 0)
return base + u.substring(basePath.length)
return base + (u.charAt(0) === "/" ? u : "/" + u)
}
+22 -8
View File
@@ -31,10 +31,10 @@ QString ApiClient::resolveUrl(const QString &relative) const
if (relative.startsWith(QLatin1String("http://"))
|| relative.startsWith(QLatin1String("https://")))
return relative;
const QString base = m_settings->baseUrl();
if (relative.startsWith(QLatin1Char('/')))
return base + relative;
return base + QLatin1Char('/') + relative;
// risoluzione RFC 3986: gestisce i path assoluti del server (es. /calibre/opds/books)
// senza raddoppiare il sottopath già presente nel baseUrl
QUrl base(m_settings->baseUrl());
return base.resolved(QUrl(relative)).toString();
}
void ApiClient::applyAuth(QNetworkRequest &request)
@@ -105,10 +105,24 @@ void ApiClient::getFeed(const QString &url)
<< "entries:" << entries.size();
emit feedReady(entries, resolveUrl(nextUrl), feedTitle);
} else {
qDebug() << "getFeed parse error:" << parseError;
emit feedError(parseError.isEmpty()
? QStringLiteral("Risposta non valida dal server")
: parseError);
// risposta 2xx ma non XML: quasi sempre una pagina HTML (redirect/login/URL errato)
const QByteArray contentType = reply->header(
QNetworkRequest::ContentTypeHeader).toByteArray();
QString message;
if (contentType.contains("html") || body.trimmed().startsWith("<!DOCTYPE")
|| body.trimmed().startsWith("<html")) {
message = QStringLiteral(
"Il server ha risposto con una pagina HTML, non OPDS. "
"Controlla l'indirizzo (es. sottopath /calibre) e che il browse anonimo "
"o le credenziali siano corretti.");
} else {
message = parseError.isEmpty()
? QStringLiteral("Risposta non valida dal server")
: parseError;
}
qDebug() << "getFeed parse error:" << parseError
<< "content-type:" << contentType;
emit feedError(message);
}
});
}