QHttpNetworkConnectionChannel: remove *authMethod
We store the authenticator right alongside it, which knows the method. The biggest change from this is changing a, self-proclaimed, duplicate method from QHttpNetworkReply. Finding the method name ahead-of-time is not actually needed, all we need to know is that a supported authentication method is requested. Also moved that specific functionality to a more logical location: QAuthenticatorPrivate. Change-Id: I11627803ccb42b8ec33a28ef1d1e00bf60dc6da9 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
parent
5a701f5a7e
commit
55feb0d08a
@ -397,10 +397,12 @@ void QHttpNetworkConnectionPrivate::copyCredentials(int fromChannel, QAuthentica
|
|||||||
// NTLM and Negotiate do multi-phase authentication.
|
// NTLM and Negotiate do multi-phase authentication.
|
||||||
// Copying credentialsbetween authenticators would mess things up.
|
// Copying credentialsbetween authenticators would mess things up.
|
||||||
if (fromChannel >= 0) {
|
if (fromChannel >= 0) {
|
||||||
const QHttpNetworkConnectionChannel &channel = channels[fromChannel];
|
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*auth);
|
||||||
const QAuthenticatorPrivate::Method method = isProxy ? channel.proxyAuthMethod : channel.authMethod;
|
if (priv
|
||||||
if (method == QAuthenticatorPrivate::Ntlm || method == QAuthenticatorPrivate::Negotiate)
|
&& (priv->method == QAuthenticatorPrivate::Ntlm
|
||||||
|
|| priv->method == QAuthenticatorPrivate::Negotiate)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// select another channel
|
// select another channel
|
||||||
@ -432,19 +434,16 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
|
|||||||
//create the response header to be used with QAuthenticatorPrivate.
|
//create the response header to be used with QAuthenticatorPrivate.
|
||||||
QList<QPair<QByteArray, QByteArray> > fields = reply->header();
|
QList<QPair<QByteArray, QByteArray> > fields = reply->header();
|
||||||
|
|
||||||
//find out the type of authentication protocol requested.
|
// Check that any of the proposed authenticate methods are supported
|
||||||
QAuthenticatorPrivate::Method authMethod = reply->d_func()->authenticationMethod(isProxy);
|
const QByteArray header = isProxy ? "proxy-authenticate" : "www-authenticate";
|
||||||
if (authMethod != QAuthenticatorPrivate::None) {
|
const QByteArrayList &authenticationMethods = reply->d_func()->headerFieldValues(header);
|
||||||
|
const bool isSupported = std::any_of(authenticationMethods.begin(), authenticationMethods.end(),
|
||||||
|
QAuthenticatorPrivate::isMethodSupported);
|
||||||
|
if (isSupported) {
|
||||||
int i = indexOf(socket);
|
int i = indexOf(socket);
|
||||||
//Use a single authenticator for all domains. ### change later to use domain/realm
|
//Use a single authenticator for all domains. ### change later to use domain/realm
|
||||||
QAuthenticator* auth = nullptr;
|
QAuthenticator *auth = isProxy ? &channels[i].proxyAuthenticator
|
||||||
if (isProxy) {
|
: &channels[i].authenticator;
|
||||||
auth = &channels[i].proxyAuthenticator;
|
|
||||||
channels[i].proxyAuthMethod = authMethod;
|
|
||||||
} else {
|
|
||||||
auth = &channels[i].authenticator;
|
|
||||||
channels[i].authMethod = authMethod;
|
|
||||||
}
|
|
||||||
//proceed with the authentication.
|
//proceed with the authentication.
|
||||||
if (auth->isNull())
|
if (auth->isNull())
|
||||||
auth->detach();
|
auth->detach();
|
||||||
@ -453,10 +452,6 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
|
|||||||
// Update method in case it changed
|
// Update method in case it changed
|
||||||
if (priv->method == QAuthenticatorPrivate::None)
|
if (priv->method == QAuthenticatorPrivate::None)
|
||||||
return false;
|
return false;
|
||||||
if (isProxy)
|
|
||||||
channels[i].proxyAuthMethod = priv->method;
|
|
||||||
else
|
|
||||||
channels[i].authMethod = priv->method;
|
|
||||||
|
|
||||||
if (priv->phase == QAuthenticatorPrivate::Done) {
|
if (priv->phase == QAuthenticatorPrivate::Done) {
|
||||||
pauseConnection();
|
pauseConnection();
|
||||||
@ -591,28 +586,30 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket,
|
|||||||
|
|
||||||
int i = indexOf(socket);
|
int i = indexOf(socket);
|
||||||
|
|
||||||
|
QAuthenticator *authenticator = &channels[i].authenticator;
|
||||||
|
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*authenticator);
|
||||||
// Send "Authorization" header, but not if it's NTLM and the socket is already authenticated.
|
// Send "Authorization" header, but not if it's NTLM and the socket is already authenticated.
|
||||||
if (channels[i].authMethod != QAuthenticatorPrivate::None) {
|
if (priv && priv->method != QAuthenticatorPrivate::None) {
|
||||||
if ((channels[i].authMethod != QAuthenticatorPrivate::Ntlm && request.headerField("Authorization").isEmpty()) || channels[i].lastStatus == 401) {
|
if ((priv->method != QAuthenticatorPrivate::Ntlm
|
||||||
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].authenticator);
|
&& request.headerField("Authorization").isEmpty())
|
||||||
if (priv && priv->method != QAuthenticatorPrivate::None) {
|
|| channels[i].lastStatus == 401) {
|
||||||
QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false), request.url().host());
|
QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false),
|
||||||
request.setHeaderField("Authorization", response);
|
request.url().host());
|
||||||
channels[i].authenticationCredentialsSent = true;
|
request.setHeaderField("Authorization", response);
|
||||||
}
|
channels[i].authenticationCredentialsSent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(networkproxy)
|
#if QT_CONFIG(networkproxy)
|
||||||
|
authenticator = &channels[i].proxyAuthenticator;
|
||||||
|
priv = QAuthenticatorPrivate::getPrivate(*authenticator);
|
||||||
// Send "Proxy-Authorization" header, but not if it's NTLM and the socket is already authenticated.
|
// Send "Proxy-Authorization" header, but not if it's NTLM and the socket is already authenticated.
|
||||||
if (channels[i].proxyAuthMethod != QAuthenticatorPrivate::None) {
|
if (priv && priv->method != QAuthenticatorPrivate::None) {
|
||||||
if (!(channels[i].proxyAuthMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) {
|
if (priv->method != QAuthenticatorPrivate::Ntlm || channels[i].lastStatus == 407) {
|
||||||
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].proxyAuthenticator);
|
QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false),
|
||||||
if (priv && priv->method != QAuthenticatorPrivate::None) {
|
networkProxy.hostName());
|
||||||
QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false), networkProxy.hostName());
|
request.setHeaderField("Proxy-Authorization", response);
|
||||||
request.setHeaderField("Proxy-Authorization", response);
|
channels[i].proxyCredentialsSent = true;
|
||||||
channels[i].proxyCredentialsSent = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // QT_CONFIG(networkproxy)
|
#endif // QT_CONFIG(networkproxy)
|
||||||
|
@ -93,8 +93,6 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
|
|||||||
, lastStatus(0)
|
, lastStatus(0)
|
||||||
, pendingEncrypt(false)
|
, pendingEncrypt(false)
|
||||||
, reconnectAttempts(reconnectAttemptsDefault)
|
, reconnectAttempts(reconnectAttemptsDefault)
|
||||||
, authMethod(QAuthenticatorPrivate::None)
|
|
||||||
, proxyAuthMethod(QAuthenticatorPrivate::None)
|
|
||||||
, authenticationCredentialsSent(false)
|
, authenticationCredentialsSent(false)
|
||||||
, proxyCredentialsSent(false)
|
, proxyCredentialsSent(false)
|
||||||
, protocolHandler(nullptr)
|
, protocolHandler(nullptr)
|
||||||
|
@ -116,8 +116,6 @@ public:
|
|||||||
int lastStatus; // last status received on this channel
|
int lastStatus; // last status received on this channel
|
||||||
bool pendingEncrypt; // for https (send after encrypted)
|
bool pendingEncrypt; // for https (send after encrypted)
|
||||||
int reconnectAttempts; // maximum 2 reconnection attempts
|
int reconnectAttempts; // maximum 2 reconnection attempts
|
||||||
QAuthenticatorPrivate::Method authMethod;
|
|
||||||
QAuthenticatorPrivate::Method proxyAuthMethod;
|
|
||||||
QAuthenticator authenticator;
|
QAuthenticator authenticator;
|
||||||
QAuthenticator proxyAuthenticator;
|
QAuthenticator proxyAuthenticator;
|
||||||
bool authenticationCredentialsSent;
|
bool authenticationCredentialsSent;
|
||||||
|
@ -411,31 +411,6 @@ bool QHttpNetworkReplyPrivate::findChallenge(bool forProxy, QByteArray &challeng
|
|||||||
return !challenge.isEmpty();
|
return !challenge.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
QAuthenticatorPrivate::Method QHttpNetworkReplyPrivate::authenticationMethod(bool isProxy) const
|
|
||||||
{
|
|
||||||
// The logic is same as the one used in void QAuthenticatorPrivate::parseHttpResponse()
|
|
||||||
QAuthenticatorPrivate::Method method = QAuthenticatorPrivate::None;
|
|
||||||
QByteArray header = isProxy ? "proxy-authenticate" : "www-authenticate";
|
|
||||||
QList<QByteArray> challenges = headerFieldValues(header);
|
|
||||||
for (int i = 0; i<challenges.size(); i++) {
|
|
||||||
QByteArray line = challenges.at(i).trimmed().toLower();
|
|
||||||
if (method < QAuthenticatorPrivate::Basic
|
|
||||||
&& line.startsWith("basic")) {
|
|
||||||
method = QAuthenticatorPrivate::Basic;
|
|
||||||
} else if (method < QAuthenticatorPrivate::Ntlm
|
|
||||||
&& line.startsWith("ntlm")) {
|
|
||||||
method = QAuthenticatorPrivate::Ntlm;
|
|
||||||
} else if (method < QAuthenticatorPrivate::DigestMd5
|
|
||||||
&& line.startsWith("digest")) {
|
|
||||||
method = QAuthenticatorPrivate::DigestMd5;
|
|
||||||
} else if (method < QAuthenticatorPrivate::Negotiate
|
|
||||||
&& line.startsWith("negotiate")) {
|
|
||||||
method = QAuthenticatorPrivate::Negotiate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket)
|
qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket)
|
||||||
{
|
{
|
||||||
if (fragment.isEmpty()) {
|
if (fragment.isEmpty()) {
|
||||||
|
@ -207,7 +207,6 @@ public:
|
|||||||
qint64 readBodyVeryFast(QAbstractSocket *socket, char *b);
|
qint64 readBodyVeryFast(QAbstractSocket *socket, char *b);
|
||||||
qint64 readBodyFast(QAbstractSocket *socket, QByteDataBuffer *rb);
|
qint64 readBodyFast(QAbstractSocket *socket, QByteDataBuffer *rb);
|
||||||
bool findChallenge(bool forProxy, QByteArray &challenge) const;
|
bool findChallenge(bool forProxy, QByteArray &challenge) const;
|
||||||
QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const;
|
|
||||||
void clear();
|
void clear();
|
||||||
void clearHttpLayerInformation();
|
void clearHttpLayerInformation();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user