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.
|
||||
// Copying credentialsbetween authenticators would mess things up.
|
||||
if (fromChannel >= 0) {
|
||||
const QHttpNetworkConnectionChannel &channel = channels[fromChannel];
|
||||
const QAuthenticatorPrivate::Method method = isProxy ? channel.proxyAuthMethod : channel.authMethod;
|
||||
if (method == QAuthenticatorPrivate::Ntlm || method == QAuthenticatorPrivate::Negotiate)
|
||||
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*auth);
|
||||
if (priv
|
||||
&& (priv->method == QAuthenticatorPrivate::Ntlm
|
||||
|| priv->method == QAuthenticatorPrivate::Negotiate)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// select another channel
|
||||
@ -432,19 +434,16 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
|
||||
//create the response header to be used with QAuthenticatorPrivate.
|
||||
QList<QPair<QByteArray, QByteArray> > fields = reply->header();
|
||||
|
||||
//find out the type of authentication protocol requested.
|
||||
QAuthenticatorPrivate::Method authMethod = reply->d_func()->authenticationMethod(isProxy);
|
||||
if (authMethod != QAuthenticatorPrivate::None) {
|
||||
// Check that any of the proposed authenticate methods are supported
|
||||
const QByteArray header = isProxy ? "proxy-authenticate" : "www-authenticate";
|
||||
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);
|
||||
//Use a single authenticator for all domains. ### change later to use domain/realm
|
||||
QAuthenticator* auth = nullptr;
|
||||
if (isProxy) {
|
||||
auth = &channels[i].proxyAuthenticator;
|
||||
channels[i].proxyAuthMethod = authMethod;
|
||||
} else {
|
||||
auth = &channels[i].authenticator;
|
||||
channels[i].authMethod = authMethod;
|
||||
}
|
||||
QAuthenticator *auth = isProxy ? &channels[i].proxyAuthenticator
|
||||
: &channels[i].authenticator;
|
||||
//proceed with the authentication.
|
||||
if (auth->isNull())
|
||||
auth->detach();
|
||||
@ -453,10 +452,6 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
|
||||
// Update method in case it changed
|
||||
if (priv->method == QAuthenticatorPrivate::None)
|
||||
return false;
|
||||
if (isProxy)
|
||||
channels[i].proxyAuthMethod = priv->method;
|
||||
else
|
||||
channels[i].authMethod = priv->method;
|
||||
|
||||
if (priv->phase == QAuthenticatorPrivate::Done) {
|
||||
pauseConnection();
|
||||
@ -591,28 +586,30 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *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.
|
||||
if (channels[i].authMethod != QAuthenticatorPrivate::None) {
|
||||
if ((channels[i].authMethod != QAuthenticatorPrivate::Ntlm && request.headerField("Authorization").isEmpty()) || channels[i].lastStatus == 401) {
|
||||
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].authenticator);
|
||||
if (priv && priv->method != QAuthenticatorPrivate::None) {
|
||||
QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false), request.url().host());
|
||||
request.setHeaderField("Authorization", response);
|
||||
channels[i].authenticationCredentialsSent = true;
|
||||
}
|
||||
if (priv && priv->method != QAuthenticatorPrivate::None) {
|
||||
if ((priv->method != QAuthenticatorPrivate::Ntlm
|
||||
&& request.headerField("Authorization").isEmpty())
|
||||
|| channels[i].lastStatus == 401) {
|
||||
QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false),
|
||||
request.url().host());
|
||||
request.setHeaderField("Authorization", response);
|
||||
channels[i].authenticationCredentialsSent = true;
|
||||
}
|
||||
}
|
||||
|
||||
#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.
|
||||
if (channels[i].proxyAuthMethod != QAuthenticatorPrivate::None) {
|
||||
if (!(channels[i].proxyAuthMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) {
|
||||
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].proxyAuthenticator);
|
||||
if (priv && priv->method != QAuthenticatorPrivate::None) {
|
||||
QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false), networkProxy.hostName());
|
||||
request.setHeaderField("Proxy-Authorization", response);
|
||||
channels[i].proxyCredentialsSent = true;
|
||||
}
|
||||
if (priv && priv->method != QAuthenticatorPrivate::None) {
|
||||
if (priv->method != QAuthenticatorPrivate::Ntlm || channels[i].lastStatus == 407) {
|
||||
QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false),
|
||||
networkProxy.hostName());
|
||||
request.setHeaderField("Proxy-Authorization", response);
|
||||
channels[i].proxyCredentialsSent = true;
|
||||
}
|
||||
}
|
||||
#endif // QT_CONFIG(networkproxy)
|
||||
|
@ -93,8 +93,6 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
|
||||
, lastStatus(0)
|
||||
, pendingEncrypt(false)
|
||||
, reconnectAttempts(reconnectAttemptsDefault)
|
||||
, authMethod(QAuthenticatorPrivate::None)
|
||||
, proxyAuthMethod(QAuthenticatorPrivate::None)
|
||||
, authenticationCredentialsSent(false)
|
||||
, proxyCredentialsSent(false)
|
||||
, protocolHandler(nullptr)
|
||||
|
@ -116,8 +116,6 @@ public:
|
||||
int lastStatus; // last status received on this channel
|
||||
bool pendingEncrypt; // for https (send after encrypted)
|
||||
int reconnectAttempts; // maximum 2 reconnection attempts
|
||||
QAuthenticatorPrivate::Method authMethod;
|
||||
QAuthenticatorPrivate::Method proxyAuthMethod;
|
||||
QAuthenticator authenticator;
|
||||
QAuthenticator proxyAuthenticator;
|
||||
bool authenticationCredentialsSent;
|
||||
|
@ -411,31 +411,6 @@ bool QHttpNetworkReplyPrivate::findChallenge(bool forProxy, QByteArray &challeng
|
||||
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)
|
||||
{
|
||||
if (fragment.isEmpty()) {
|
||||
|
@ -207,7 +207,6 @@ public:
|
||||
qint64 readBodyVeryFast(QAbstractSocket *socket, char *b);
|
||||
qint64 readBodyFast(QAbstractSocket *socket, QByteDataBuffer *rb);
|
||||
bool findChallenge(bool forProxy, QByteArray &challenge) const;
|
||||
QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const;
|
||||
void clear();
|
||||
void clearHttpLayerInformation();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user