mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-02 15:15:50 +08:00
refs #882, support redirect transparently in CApplication
* SSL client certificate functionality used from utils * support for max redirects Remark: QNetworkRequest::FollowRedirectsAttribute would allow auto redirect, but we use our approach as it gives us better control
This commit is contained in:
committed by
Mathew Sutcliffe
parent
74db515802
commit
f73ee87e13
@@ -474,19 +474,19 @@ namespace BlackCore
|
||||
return str;
|
||||
}
|
||||
|
||||
QNetworkReply *CApplication::getFromNetwork(const CUrl &url, const CSlot<void(QNetworkReply *)> &callback)
|
||||
QNetworkReply *CApplication::getFromNetwork(const CUrl &url, const CSlot<void(QNetworkReply *)> &callback, int maxRedirects)
|
||||
{
|
||||
return httpRequestImpl(url.toNetworkRequest(), callback, [ ](QNetworkAccessManager & nam, const QNetworkRequest & request) { return nam.get(request); });
|
||||
return httpRequestImpl(url.toNetworkRequest(), callback, maxRedirects, [ ](QNetworkAccessManager & nam, const QNetworkRequest & request) { return nam.get(request); });
|
||||
}
|
||||
|
||||
QNetworkReply *CApplication::getFromNetwork(const QNetworkRequest &request, const CSlot<void(QNetworkReply *)> &callback)
|
||||
QNetworkReply *CApplication::getFromNetwork(const QNetworkRequest &request, const CSlot<void(QNetworkReply *)> &callback, int maxRedirects)
|
||||
{
|
||||
return httpRequestImpl(request, callback, [ ](QNetworkAccessManager & nam, const QNetworkRequest & request) { return nam.get(request); });
|
||||
return httpRequestImpl(request, callback, maxRedirects, [ ](QNetworkAccessManager & nam, const QNetworkRequest & request) { return nam.get(request); });
|
||||
}
|
||||
|
||||
QNetworkReply *CApplication::postToNetwork(const QNetworkRequest &request, const QByteArray &data, const CSlot<void(QNetworkReply *)> &callback)
|
||||
{
|
||||
return httpRequestImpl(request, callback, [ data ](QNetworkAccessManager & nam, const QNetworkRequest & request) { return nam.post(request, data); });
|
||||
return httpRequestImpl(request, callback, -1, [ data ](QNetworkAccessManager & nam, const QNetworkRequest & request) { return nam.post(request, data); });
|
||||
}
|
||||
|
||||
QNetworkReply *CApplication::postToNetwork(const QNetworkRequest &request, QHttpMultiPart *multiPart, const CSlot<void(QNetworkReply *)> &callback)
|
||||
@@ -497,7 +497,7 @@ namespace BlackCore
|
||||
multiPart->moveToThread(this->m_accessManager.thread());
|
||||
}
|
||||
|
||||
return httpRequestImpl(request, callback, [ this, multiPart ](QNetworkAccessManager & nam, const QNetworkRequest & request)
|
||||
return httpRequestImpl(request, callback, -1, [ this, multiPart ](QNetworkAccessManager & nam, const QNetworkRequest & request)
|
||||
{
|
||||
QNetworkReply *reply = nam.post(request, multiPart);
|
||||
Q_ASSERT(reply);
|
||||
@@ -506,14 +506,14 @@ namespace BlackCore
|
||||
});
|
||||
}
|
||||
|
||||
QNetworkReply *CApplication::headerFromNetwork(const CUrl &url, const CSlot<void (QNetworkReply *)> &callback)
|
||||
QNetworkReply *CApplication::headerFromNetwork(const CUrl &url, const CSlot<void (QNetworkReply *)> &callback, int maxRedirects)
|
||||
{
|
||||
return httpRequestImpl(url.toNetworkRequest(), callback, [ ](QNetworkAccessManager & nam, const QNetworkRequest & request) { return nam.head(request); });
|
||||
return httpRequestImpl(url.toNetworkRequest(), callback, maxRedirects, [ ](QNetworkAccessManager & nam, const QNetworkRequest & request) { return nam.head(request); });
|
||||
}
|
||||
|
||||
QNetworkReply *CApplication::headerFromNetwork(const QNetworkRequest &request, const CSlot<void (QNetworkReply *)> &callback)
|
||||
QNetworkReply *CApplication::headerFromNetwork(const QNetworkRequest &request, const CSlot<void (QNetworkReply *)> &callback, int maxRedirects)
|
||||
{
|
||||
return httpRequestImpl(request, callback, [ ](QNetworkAccessManager & nam, const QNetworkRequest & request) { return nam.head(request); });
|
||||
return httpRequestImpl(request, callback, maxRedirects, [ ](QNetworkAccessManager & nam, const QNetworkRequest & request) { return nam.head(request); });
|
||||
}
|
||||
|
||||
void CApplication::deleteAllCookies()
|
||||
@@ -1079,9 +1079,9 @@ namespace BlackCore
|
||||
static const QString extension = CBuildConfig::isRunningOnWindowsNtPlatform() ? ".exe" : QString();
|
||||
static const QString handler = CDirectoryUtils::applicationDirectoryPath() + "/" + "swift_crashpad_handler" + extension;
|
||||
static const QString crashpadPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) +
|
||||
"/org.swift-project/" +
|
||||
CDirectoryUtils::normalizedApplicationDirectory() +
|
||||
"/crashpad";
|
||||
"/org.swift-project/" +
|
||||
CDirectoryUtils::normalizedApplicationDirectory() +
|
||||
"/crashpad";
|
||||
static const QString database = crashpadPath + "/database";
|
||||
static const QString metrics = crashpadPath + "/metrics";
|
||||
|
||||
@@ -1119,7 +1119,7 @@ namespace BlackCore
|
||||
#endif
|
||||
}
|
||||
|
||||
QNetworkReply *CApplication::httpRequestImpl(const QNetworkRequest &request, const BlackMisc::CSlot<void (QNetworkReply *)> &callback, std::function<QNetworkReply *(QNetworkAccessManager &, const QNetworkRequest &)> method)
|
||||
QNetworkReply *CApplication::httpRequestImpl(const QNetworkRequest &request, const BlackMisc::CSlot<void (QNetworkReply *)> &callback, int maxRedirects, std::function<QNetworkReply *(QNetworkAccessManager &, const QNetworkRequest &)> requestOrPostMethod)
|
||||
{
|
||||
if (this->m_shutdown) { return nullptr; }
|
||||
if (!this->isNetworkConnectedAndAccessible()) { return nullptr; }
|
||||
@@ -1127,32 +1127,43 @@ namespace BlackCore
|
||||
Q_ASSERT_X(QCoreApplication::instance()->thread() == m_accessManager.thread(), Q_FUNC_INFO, "Network manager supposed to be in main thread");
|
||||
if (QThread::currentThread() != this->m_accessManager.thread())
|
||||
{
|
||||
QTimer::singleShot(0, this, std::bind(&CApplication::httpRequestImpl, this, request, callback, method));
|
||||
QTimer::singleShot(0, this, std::bind(&CApplication::httpRequestImpl, this, request, callback, maxRedirects, requestOrPostMethod));
|
||||
return nullptr; // not yet started
|
||||
}
|
||||
|
||||
Q_ASSERT_X(QThread::currentThread() == m_accessManager.thread(), Q_FUNC_INFO, "Network manager thread mismatch");
|
||||
QNetworkRequest r(request); // no QObject
|
||||
CNetworkUtils::ignoreSslVerification(r);
|
||||
CNetworkUtils::setSwiftUserAgent(r);
|
||||
QNetworkRequest copiedRequest(request); // no QObject
|
||||
CNetworkUtils::ignoreSslVerification(copiedRequest);
|
||||
CNetworkUtils::setSwiftUserAgent(copiedRequest);
|
||||
|
||||
// If url is one of the shared urls, add swift client SSL certificate
|
||||
const CUrlList swiftSharedUrls = getGlobalSetup().getSwiftSharedUrls();
|
||||
for (const CUrl &sharedUrl : swiftSharedUrls)
|
||||
{
|
||||
QString urlString = request.url().toString();
|
||||
if (urlString.startsWith(sharedUrl.toQString()))
|
||||
{
|
||||
CNetworkUtils::setSwiftClientSslCertificate(r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If URL is one of the shared urls, add swift client SSL certificate
|
||||
CNetworkUtils::setSwiftClientSslCertificate(copiedRequest, getGlobalSetup().getSwiftSharedUrls());
|
||||
|
||||
QNetworkReply *reply = method(this->m_accessManager, r);
|
||||
QNetworkReply *reply = requestOrPostMethod(this->m_accessManager, copiedRequest);
|
||||
reply->setProperty("started", QVariant(QDateTime::currentMSecsSinceEpoch()));
|
||||
if (callback)
|
||||
{
|
||||
connect(reply, &QNetworkReply::finished, callback.object(), [ = ] { callback(reply); }, Qt::QueuedConnection);
|
||||
connect(reply, &QNetworkReply::finished, callback.object(), [ = ]
|
||||
{
|
||||
// Called when finished!
|
||||
// QNetworkRequest::FollowRedirectsAttribute would allow auto redirect
|
||||
// but we use our approach as it gives us better control
|
||||
const bool isRedirect = CNetworkUtils::isHttpStatusRedirect(reply);
|
||||
if (isRedirect && maxRedirects > 0)
|
||||
{
|
||||
const QUrl redirectUrl = CNetworkUtils::getHttpRedirectUrl(reply);
|
||||
if (!redirectUrl.isEmpty())
|
||||
{
|
||||
QNetworkRequest redirectRequest(redirectUrl);
|
||||
const int redirectsLeft = maxRedirects - 1;
|
||||
QTimer::singleShot(0, this, std::bind(&CApplication::httpRequestImpl, this, redirectRequest, callback, redirectsLeft, requestOrPostMethod));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// called when there are no more callbacks
|
||||
callback(reply);
|
||||
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
@@ -326,12 +326,12 @@ namespace BlackCore
|
||||
//! Request to get network reply
|
||||
//! \threadsafe
|
||||
QNetworkReply *getFromNetwork(const BlackMisc::Network::CUrl &url,
|
||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback);
|
||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback, int maxRedirects = 2);
|
||||
|
||||
//! Request to get network reply
|
||||
//! \threadsafe
|
||||
QNetworkReply *getFromNetwork(const QNetworkRequest &request,
|
||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback);
|
||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback, int maxRedirects = 2);
|
||||
|
||||
//! Post to network
|
||||
//! \threadsafe
|
||||
@@ -347,12 +347,12 @@ namespace BlackCore
|
||||
//! Request to get network repy using HTTP's HEADER method
|
||||
//! \threadsafe
|
||||
QNetworkReply *headerFromNetwork(const BlackMisc::Network::CUrl &url,
|
||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback);
|
||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback, int maxRedirects = -1);
|
||||
|
||||
//! Request to get network repy using HTTP's HEADER method
|
||||
//! \threadsafe
|
||||
QNetworkReply *headerFromNetwork(const QNetworkRequest &request,
|
||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback);
|
||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback, int maxRedirects = -1);
|
||||
|
||||
signals:
|
||||
//! Setup available (cache, web load, ..) or failed to load setup
|
||||
@@ -447,7 +447,8 @@ namespace BlackCore
|
||||
//! Implementation for getFromNetwork(), postToNetwork() and headerFromNetwork()
|
||||
QNetworkReply *httpRequestImpl(const QNetworkRequest &request,
|
||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback,
|
||||
std::function<QNetworkReply *(QNetworkAccessManager &, const QNetworkRequest &)> method);
|
||||
int maxRedirects,
|
||||
std::function<QNetworkReply *(QNetworkAccessManager &, const QNetworkRequest &)> requestOrPostMethod);
|
||||
|
||||
QScopedPointer<CCoreFacade> m_coreFacade; //!< core facade if any
|
||||
QScopedPointer<CSetupReader> m_setupReader; //!< setup reader
|
||||
|
||||
Reference in New Issue
Block a user