mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-05-04 00:45:46 +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;
|
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)
|
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)
|
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());
|
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);
|
QNetworkReply *reply = nam.post(request, multiPart);
|
||||||
Q_ASSERT(reply);
|
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()
|
void CApplication::deleteAllCookies()
|
||||||
@@ -1079,9 +1079,9 @@ namespace BlackCore
|
|||||||
static const QString extension = CBuildConfig::isRunningOnWindowsNtPlatform() ? ".exe" : QString();
|
static const QString extension = CBuildConfig::isRunningOnWindowsNtPlatform() ? ".exe" : QString();
|
||||||
static const QString handler = CDirectoryUtils::applicationDirectoryPath() + "/" + "swift_crashpad_handler" + extension;
|
static const QString handler = CDirectoryUtils::applicationDirectoryPath() + "/" + "swift_crashpad_handler" + extension;
|
||||||
static const QString crashpadPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) +
|
static const QString crashpadPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) +
|
||||||
"/org.swift-project/" +
|
"/org.swift-project/" +
|
||||||
CDirectoryUtils::normalizedApplicationDirectory() +
|
CDirectoryUtils::normalizedApplicationDirectory() +
|
||||||
"/crashpad";
|
"/crashpad";
|
||||||
static const QString database = crashpadPath + "/database";
|
static const QString database = crashpadPath + "/database";
|
||||||
static const QString metrics = crashpadPath + "/metrics";
|
static const QString metrics = crashpadPath + "/metrics";
|
||||||
|
|
||||||
@@ -1119,7 +1119,7 @@ namespace BlackCore
|
|||||||
#endif
|
#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->m_shutdown) { return nullptr; }
|
||||||
if (!this->isNetworkConnectedAndAccessible()) { 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");
|
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())
|
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
|
return nullptr; // not yet started
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT_X(QThread::currentThread() == m_accessManager.thread(), Q_FUNC_INFO, "Network manager thread mismatch");
|
Q_ASSERT_X(QThread::currentThread() == m_accessManager.thread(), Q_FUNC_INFO, "Network manager thread mismatch");
|
||||||
QNetworkRequest r(request); // no QObject
|
QNetworkRequest copiedRequest(request); // no QObject
|
||||||
CNetworkUtils::ignoreSslVerification(r);
|
CNetworkUtils::ignoreSslVerification(copiedRequest);
|
||||||
CNetworkUtils::setSwiftUserAgent(r);
|
CNetworkUtils::setSwiftUserAgent(copiedRequest);
|
||||||
|
|
||||||
// If url is one of the shared urls, add swift client SSL certificate
|
// If URL is one of the shared urls, add swift client SSL certificate
|
||||||
const CUrlList swiftSharedUrls = getGlobalSetup().getSwiftSharedUrls();
|
CNetworkUtils::setSwiftClientSslCertificate(copiedRequest, getGlobalSetup().getSwiftSharedUrls());
|
||||||
for (const CUrl &sharedUrl : swiftSharedUrls)
|
|
||||||
{
|
|
||||||
QString urlString = request.url().toString();
|
|
||||||
if (urlString.startsWith(sharedUrl.toQString()))
|
|
||||||
{
|
|
||||||
CNetworkUtils::setSwiftClientSslCertificate(r);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkReply *reply = method(this->m_accessManager, r);
|
QNetworkReply *reply = requestOrPostMethod(this->m_accessManager, copiedRequest);
|
||||||
reply->setProperty("started", QVariant(QDateTime::currentMSecsSinceEpoch()));
|
reply->setProperty("started", QVariant(QDateTime::currentMSecsSinceEpoch()));
|
||||||
if (callback)
|
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;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,12 +326,12 @@ namespace BlackCore
|
|||||||
//! Request to get network reply
|
//! Request to get network reply
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
QNetworkReply *getFromNetwork(const BlackMisc::Network::CUrl &url,
|
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
|
//! Request to get network reply
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
QNetworkReply *getFromNetwork(const QNetworkRequest &request,
|
QNetworkReply *getFromNetwork(const QNetworkRequest &request,
|
||||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback);
|
const BlackMisc::CSlot<void(QNetworkReply *)> &callback, int maxRedirects = 2);
|
||||||
|
|
||||||
//! Post to network
|
//! Post to network
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
@@ -347,12 +347,12 @@ namespace BlackCore
|
|||||||
//! Request to get network repy using HTTP's HEADER method
|
//! Request to get network repy using HTTP's HEADER method
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
QNetworkReply *headerFromNetwork(const BlackMisc::Network::CUrl &url,
|
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
|
//! Request to get network repy using HTTP's HEADER method
|
||||||
//! \threadsafe
|
//! \threadsafe
|
||||||
QNetworkReply *headerFromNetwork(const QNetworkRequest &request,
|
QNetworkReply *headerFromNetwork(const QNetworkRequest &request,
|
||||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback);
|
const BlackMisc::CSlot<void(QNetworkReply *)> &callback, int maxRedirects = -1);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
//! Setup available (cache, web load, ..) or failed to load setup
|
//! Setup available (cache, web load, ..) or failed to load setup
|
||||||
@@ -447,7 +447,8 @@ namespace BlackCore
|
|||||||
//! Implementation for getFromNetwork(), postToNetwork() and headerFromNetwork()
|
//! Implementation for getFromNetwork(), postToNetwork() and headerFromNetwork()
|
||||||
QNetworkReply *httpRequestImpl(const QNetworkRequest &request,
|
QNetworkReply *httpRequestImpl(const QNetworkRequest &request,
|
||||||
const BlackMisc::CSlot<void(QNetworkReply *)> &callback,
|
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<CCoreFacade> m_coreFacade; //!< core facade if any
|
||||||
QScopedPointer<CSetupReader> m_setupReader; //!< setup reader
|
QScopedPointer<CSetupReader> m_setupReader; //!< setup reader
|
||||||
|
|||||||
Reference in New Issue
Block a user