From 15913ee6af03fd6c889d0042f520111e4f700693 Mon Sep 17 00:00:00 2001 From: Hannah von Reth Date: Mon, 8 Apr 2024 16:43:07 +0200 Subject: [PATCH] HttpLogger: Log redirects --- changelog/unreleased/11581 | 5 +++ src/libsync/httplogger.cpp | 62 +++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 18 deletions(-) create mode 100644 changelog/unreleased/11581 diff --git a/changelog/unreleased/11581 b/changelog/unreleased/11581 new file mode 100644 index 00000000000..993a189beef --- /dev/null +++ b/changelog/unreleased/11581 @@ -0,0 +1,5 @@ +Bugfix: Support logging redirect + +We now log when all urls when a request was redirected. + +https://github.com/owncloud/client/pull/11581 diff --git a/src/libsync/httplogger.cpp b/src/libsync/httplogger.cpp index 1318bbcb838..dca76c38083 100644 --- a/src/libsync/httplogger.cpp +++ b/src/libsync/httplogger.cpp @@ -18,6 +18,7 @@ #include "common/utility.h" #include +#include #include #include #include @@ -42,12 +43,21 @@ bool isTextBody(const QString &s) struct HttpContext { HttpContext(const QNetworkRequest &request) - : url(request.url().toString()) + : originalUrl(request.url().toString()) + , lastUrl(request.url()) , id(QString::fromUtf8(request.rawHeader(QByteArrayLiteral("X-Request-ID")))) { } - const QString url; + void addRedirect(const QUrl &url) + { + lastUrl = url; + redirectUrls.append(url.toString()); + } + + const QString originalUrl; + QUrl lastUrl; + QStringList redirectUrls; const QString id; OCC::Utility::ChronoElapsedTimer timer; @@ -66,7 +76,11 @@ void logHttp(const QByteArray &verb, HttpContext *ctx, QJsonObject &&header, QIO header.insert(authKey, auth.startsWith(QStringLiteral("Bearer ")) ? QStringLiteral("Bearer [redacted]") : QStringLiteral("Basic [redacted]")); } - QJsonObject info{{QStringLiteral("method"), QString::fromUtf8(verb)}, {QStringLiteral("id"), ctx->id}, {QStringLiteral("url"), ctx->url}}; + QJsonObject info{{QStringLiteral("method"), QString::fromUtf8(verb)}, {QStringLiteral("id"), ctx->id}, {QStringLiteral("url"), ctx->originalUrl}}; + + if (!ctx->redirectUrls.isEmpty()) { + info.insert(QStringLiteral("redirects"), QJsonArray::fromStringList(ctx->redirectUrls)); + } if (reply) { // respond @@ -130,9 +144,17 @@ void HttpLogger::logRequest(QNetworkReply *reply, QNetworkAccessManager::Operati // device should still exist, lets still use a qpointer to ensure we have valid data const auto logSend = [ctx = ctx.get(), operation, reply, device = QPointer(device), deviceRaw = device](bool cached = false) { Q_ASSERT(!deviceRaw || device); - Q_ASSERT(!ctx->send); - ctx->send = true; - ctx->timer.reset(); + if (!ctx->send) { + ctx->send = true; + ctx->timer.reset(); + } else { + // this is a redirect + if (ctx->lastUrl != reply->url()) { + ctx->addRedirect(reply->url()); + } else { + Q_UNREACHABLE(); + } + } const auto request = reply->request(); QJsonObject header; @@ -141,19 +163,23 @@ void HttpLogger::logRequest(QNetworkReply *reply, QNetworkAccessManager::Operati } logHttp(requestVerb(operation, request), ctx, std::move(header), device, cached); }; - QObject::connect(reply, &QNetworkReply::requestSent, reply, logSend); + QObject::connect(reply, &QNetworkReply::requestSent, reply, logSend, Qt::DirectConnection); - QObject::connect(reply, &QNetworkReply::finished, reply, [reply, ctx = std::move(ctx), logSend] { - ctx->timer.stop(); - if (!ctx->send) { - logSend(true); - } - QJsonObject header; - for (const auto &[key, value] : reply->rawHeaderPairs()) { - header[QString::fromUtf8(key)] = QString::fromUtf8(value); - } - logHttp(requestVerb(*reply), ctx.get(), std::move(header), reply); - }); + + QObject::connect( + reply, &QNetworkReply::finished, reply, + [reply, ctx = std::move(ctx), logSend] { + ctx->timer.stop(); + if (!ctx->send) { + logSend(true); + } + QJsonObject header; + for (const auto &[key, value] : reply->rawHeaderPairs()) { + header[QString::fromUtf8(key)] = QString::fromUtf8(value); + } + logHttp(requestVerb(*reply), ctx.get(), std::move(header), reply); + }, + Qt::DirectConnection); } QByteArray HttpLogger::requestVerb(QNetworkAccessManager::Operation operation, const QNetworkRequest &request)