Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
27 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/network/kernel/kernel.pri

    r561 r846  
    2929mac:SOURCES += kernel/qnetworkproxy_mac.cpp
    3030else:win32:SOURCES += kernel/qnetworkproxy_win.cpp
     31else:symbian:SOURCES += kernel/qnetworkproxy_symbian.cpp
    3132else:SOURCES += kernel/qnetworkproxy_generic.cpp
    3233
     34symbian: LIBS += -lcommsdat
  • trunk/src/network/kernel/qauthenticator.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    5151#include <qendian.h>
    5252#include <qstring.h>
     53#include <qdatetime.h>
     54
     55//#define NTLMV1_CLIENT
    5356
    5457QT_BEGIN_NAMESPACE
    5558
     59#ifdef NTLMV1_CLIENT
    5660#include "../../3rdparty/des/des.cpp"
     61#endif
    5762
    5863static QByteArray qNtlmPhase1();
     
    8489  Note that, in particular, NTLM version 2 is not supported.
    8590
     91  \section1 Options
     92
     93  In addition to the username and password required for authentication, a
     94  QAuthenticator object can also contain additional options. The
     95  options() function can be used to query incoming options sent by
     96  the server; the setOption() function can
     97  be used to set outgoing options, to be processed by the authenticator
     98  calculation. The options accepted and provided depend on the authentication
     99  type (see method()).
     100
     101  The following tables list known incoming options as well as accepted
     102  outgoing options. The list of incoming options is not exhaustive, since
     103  servers may include additional information at any time. The list of
     104  outgoing options is exhaustive, however, and no unknown options will be
     105  treated or sent back to the server.
     106
     107  \section2 Basic
     108
     109  \table
     110    \header \o Option \o Direction \o Description
     111    \row \o \tt{realm} \o Incoming \o Contains the realm of the authentication, the same as realm()
     112  \endtable
     113
     114  The Basic authentication mechanism supports no outgoing options.
     115
     116  \section2 NTLM version 1
     117
     118  The NTLM authentication mechanism currently supports no incoming or outgoing options.
     119
     120  \section2 Digest-MD5
     121
     122  \table
     123    \header \o Option \o Direction \o Description
     124    \row \o \tt{realm} \o Incoming \o Contains the realm of the authentication, the same as realm()
     125  \endtable
     126
     127  The Digest-MD5 authentication mechanism supports no outgoing options.
     128
    86129  \sa QSslSocket
    87130*/
     
    122165    if (d == other.d)
    123166        return *this;
    124     detach();
    125     d->user = other.d->user;
    126     d->password = other.d->password;
     167
     168    if (d && !d->ref.deref())
     169        delete d;
     170
     171    d = other.d;
     172    if (d)
     173        d->ref.ref();
    127174    return *this;
    128175}
     
    139186        && d->password == other.d->password
    140187        && d->realm == other.d->realm
    141         && d->method == other.d->method;
     188        && d->method == other.d->method
     189        && d->options == other.d->options;
    142190}
    143191
     
    163211{
    164212    detach();
    165     d->user = user;
     213    int separatorPosn = 0;
     214
     215    switch(d->method) {
     216    case QAuthenticatorPrivate::Ntlm:
     217        if((separatorPosn = user.indexOf(QLatin1String("\\"))) != -1) {
     218            //domain name is present
     219            d->realm.clear();
     220            d->userDomain = user.left(separatorPosn);
     221            d->extractedUser = user.mid(separatorPosn + 1);
     222            d->user = user;
     223        } else if((separatorPosn = user.indexOf(QLatin1String("@"))) != -1) {
     224            //domain name is present
     225            d->realm.clear();
     226            d->userDomain = user.left(separatorPosn);
     227            d->extractedUser = user.left(separatorPosn);
     228            d->user = user;
     229        } else {
     230            d->extractedUser = user;
     231            d->user = user;
     232            d->realm.clear();
     233            d->userDomain.clear();
     234        }
     235        break;
     236    default:
     237        d->user = user;
     238        d->userDomain.clear();
     239        break;
     240    }
    166241}
    167242
     
    206281}
    207282
    208 
    209 /*!
    210   returns true if the authenticator is null.
     283/*!
     284    \since 4.7
     285    Returns the value related to option \a opt if it was set by the server.
     286    See \l{QAuthenticator#Options} for more information on incoming options.
     287    If option \a opt isn't found, an invalid QVariant will be returned.
     288
     289    \sa options(), QAuthenticator#Options
     290*/
     291QVariant QAuthenticator::option(const QString &opt) const
     292{
     293    return d ? d->options.value(opt) : QVariant();
     294}
     295
     296/*!
     297    \since 4.7
     298    Returns all incoming options set in this QAuthenticator object by parsing
     299    the server reply. See \l{QAuthenticator#Options} for more information
     300    on incoming options.
     301
     302    \sa option(), QAuthenticator#Options
     303*/
     304QVariantHash QAuthenticator::options() const
     305{
     306    return d ? d->options : QVariantHash();
     307}
     308
     309/*!
     310    \since 4.7
     311
     312    Sets the outgoing option \a opt to value \a value.
     313    See \l{QAuthenticator#Options} for more information on outgoing options.
     314
     315    \sa options(), option(), QAuthenticator#Options
     316*/
     317void QAuthenticator::setOption(const QString &opt, const QVariant &value)
     318{
     319    detach();
     320    d->options.insert(opt, value);
     321}
     322
     323
     324/*!
     325    Returns true if the authenticator is null.
    211326*/
    212327bool QAuthenticator::isNull() const
     
    229344void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header, bool isProxy)
    230345{
    231     QList<QPair<QString, QString> > values = header.values();
     346    const QList<QPair<QString, QString> > values = header.values();
     347    QList<QPair<QByteArray, QByteArray> > rawValues;
     348
     349    QList<QPair<QString, QString> >::const_iterator it, end;
     350    for (it = values.constBegin(), end = values.constEnd(); it != end; ++it)
     351        rawValues.append(qMakePair(it->first.toLatin1(), it->second.toUtf8()));
     352
     353    // continue in byte array form
     354    parseHttpResponse(rawValues, isProxy);
     355}
     356#endif
     357
     358void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByteArray> > &values, bool isProxy)
     359{
    232360    const char *search = isProxy ? "proxy-authenticate" : "www-authenticate";
    233361
     
    243371    */
    244372
    245     QString headerVal;
     373    QByteArray headerVal;
    246374    for (int i = 0; i < values.size(); ++i) {
    247         const QPair<QString, QString> &current = values.at(i);
    248         if (current.first.toLower() != QLatin1String(search))
     375        const QPair<QByteArray, QByteArray> &current = values.at(i);
     376        if (current.first.toLower() != search)
    249377            continue;
    250         QString str = current.second;
    251         if (method < Basic && str.startsWith(QLatin1String("Basic"), Qt::CaseInsensitive)) {
    252             method = Basic; headerVal = str.mid(6);
    253         } else if (method < Ntlm && str.startsWith(QLatin1String("NTLM"), Qt::CaseInsensitive)) {
     378        QByteArray str = current.second.toLower();
     379        if (method < Basic && str.startsWith("basic")) {
     380            method = Basic;
     381            headerVal = current.second.mid(6);
     382        } else if (method < Ntlm && str.startsWith("ntlm")) {
    254383            method = Ntlm;
    255             headerVal = str.mid(5);
    256         } else if (method < DigestMd5 && str.startsWith(QLatin1String("Digest"), Qt::CaseInsensitive)) {
     384            headerVal = current.second.mid(5);
     385        } else if (method < DigestMd5 && str.startsWith("digest")) {
    257386            method = DigestMd5;
    258             headerVal = str.mid(7);
     387            headerVal = current.second.mid(7);
    259388        }
    260389    }
    261390
    262     challenge = headerVal.trimmed().toLatin1();
     391    challenge = headerVal.trimmed();
    263392    QHash<QByteArray, QByteArray> options = parseDigestAuthenticationChallenge(challenge);
    264393
    265394    switch(method) {
    266395    case Basic:
    267         realm = QString::fromLatin1(options.value("realm"));
     396        if(realm.isEmpty())
     397            this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
    268398        if (user.isEmpty())
    269399            phase = Done;
     
    271401    case Ntlm:
    272402        // #### extract from header
    273         realm.clear();
    274403        break;
    275404    case DigestMd5: {
    276         realm = QString::fromLatin1(options.value("realm"));
     405        if(realm.isEmpty())
     406            this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
    277407        if (options.value("stale").toLower() == "true")
    278408            phase = Start;
     
    287417    }
    288418}
    289 #endif
    290419
    291420QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMethod, const QByteArray &path)
     
    662791#define NTLMSSP_NEGOTIATE_56 0x80000000
    663792
     793/*
     794 * AvId values
     795 */
     796#define AVTIMESTAMP 7
     797
     798//#define NTLMV1_CLIENT
     799
     800
     801//************************Global variables***************************
     802
     803const int blockSize = 64; //As per RFC2104 Block-size is 512 bits
     804const int nDigestLen = 16; //Trunctaion Length of the Hmac-Md5 digest
     805const quint8 respversion = 1;
     806const quint8 hirespversion = 1;
    664807
    665808/* usage:
     
    804947    // extracted
    805948    QString targetNameStr, targetInfoStr;
     949    QByteArray targetInfoBuff;
    806950};
    807951
     
    819963    QByteArray lmResponseBuf, ntlmResponseBuf;
    820964    QString domainStr, userStr, workstationStr, sessionKeyStr;
     965    QByteArray v2Hash;
    821966};
    822967
     
    9001045}
    9011046
    902 
     1047#ifdef NTLMV1_CLIENT
    9031048static QByteArray qEncodeNtlmResponse(const QAuthenticatorPrivate *ctx, const QNtlmPhase2Block& ch)
    9041049{
     
    9421087    return rc;
    9431088}
    944 
     1089#endif
     1090
     1091/*********************************************************************
     1092* Function Name: qEncodeHmacMd5
     1093* Params:
     1094*    key:   Type - QByteArray
     1095*         - It is the Authentication key
     1096*    message:   Type - QByteArray
     1097*         - This is the actual message which will be encoded
     1098*           using HMacMd5 hash algorithm
     1099*
     1100* Return Value:
     1101*    hmacDigest:   Type - QByteArray
     1102*
     1103* Description:
     1104*    This function will be used to encode the input message using
     1105*    HMacMd5 hash algorithm.
     1106*
     1107*    As per the RFC2104 the HMacMd5 algorithm can be specified
     1108*        ---------------------------------------
     1109*         MD5(K XOR opad, MD5(K XOR ipad, text))
     1110*        ---------------------------------------
     1111*
     1112*********************************************************************/
     1113QByteArray qEncodeHmacMd5(QByteArray &key, const QByteArray &message)
     1114{
     1115    Q_ASSERT_X(!(message.isEmpty()),"qEncodeHmacMd5", "Empty message check");
     1116    Q_ASSERT_X(!(key.isEmpty()),"qEncodeHmacMd5", "Empty key check");
     1117
     1118    QCryptographicHash hash(QCryptographicHash::Md5);
     1119    QByteArray hMsg;
     1120
     1121    QByteArray iKeyPad(blockSize, 0x36);
     1122    QByteArray oKeyPad(blockSize, 0x5c);
     1123
     1124    hash.reset();
     1125    // Adjust the key length to blockSize
     1126
     1127    if(blockSize < key.length()) {
     1128        hash.addData(key);
     1129        key = hash.result(); //MD5 will always return 16 bytes length output
     1130    }
     1131
     1132    //Key will be <= 16 or 20 bytes as hash function (MD5 or SHA hash algorithms)
     1133    //key size can be max of Block size only
     1134    key = key.leftJustified(blockSize,0,true);
     1135
     1136    //iKeyPad, oKeyPad and key are all of same size "blockSize"
     1137
     1138    //xor of iKeyPad with Key and store the result into iKeyPad
     1139    for(int i = 0; i<key.size();i++) {
     1140        iKeyPad[i] = key[i]^iKeyPad[i];
     1141    }
     1142
     1143    //xor of oKeyPad with Key and store the result into oKeyPad
     1144    for(int i = 0; i<key.size();i++) {
     1145        oKeyPad[i] = key[i]^oKeyPad[i];
     1146    }
     1147
     1148    iKeyPad.append(message); // (K0 xor ipad) || text
     1149
     1150    hash.reset();
     1151    hash.addData(iKeyPad);
     1152    hMsg = hash.result();
     1153                    //Digest gen after pass-1: H((K0 xor ipad)||text)
     1154
     1155    QByteArray hmacDigest;
     1156    oKeyPad.append(hMsg);
     1157    hash.reset();
     1158    hash.addData(oKeyPad);
     1159    hmacDigest = hash.result();
     1160                    // H((K0 xor opad )|| H((K0 xor ipad) || text))
     1161
     1162    /*hmacDigest should not be less than half the length of the HMAC output
     1163      (to match the birthday attack bound) and not less than 80 bits
     1164      (a suitable lower bound on the number of bits that need to be
     1165      predicted by an attacker).
     1166      Refer RFC 2104 for more details on truncation part */
     1167
     1168    /*MD5 hash always returns 16 byte digest only and HMAC-MD5 spec
     1169      (RFC 2104) also says digest length should be 16 bytes*/
     1170    return hmacDigest;
     1171}
     1172
     1173static QByteArray qCreatev2Hash(const QAuthenticatorPrivate *ctx,
     1174                                QNtlmPhase3Block *phase3)
     1175{
     1176    Q_ASSERT(phase3 != 0);
     1177    // since v2 Hash is need for both NTLMv2 and LMv2 it is calculated
     1178    // only once and stored and reused
     1179    if(phase3->v2Hash.size() == 0) {
     1180        QCryptographicHash md4(QCryptographicHash::Md4);
     1181        QByteArray passUnicode = qStringAsUcs2Le(ctx->password);
     1182        md4.addData(passUnicode.data(), passUnicode.size());
     1183
     1184        QByteArray hashKey = md4.result();
     1185        Q_ASSERT(hashKey.size() == 16);
     1186        // Assuming the user and domain is always unicode in challenge
     1187        QByteArray message =
     1188                qStringAsUcs2Le(ctx->extractedUser.toUpper()) +
     1189                qStringAsUcs2Le(phase3->domainStr);
     1190
     1191        phase3->v2Hash = qEncodeHmacMd5(hashKey, message);
     1192    }
     1193    return phase3->v2Hash;
     1194}
     1195
     1196static QByteArray clientChallenge(const QAuthenticatorPrivate *ctx)
     1197{
     1198    Q_ASSERT(ctx->cnonce.size() >= 8);
     1199    QByteArray clientCh = ctx->cnonce.right(8);
     1200    return clientCh;
     1201}
     1202
     1203// caller has to ensure a valid targetInfoBuff
     1204static QByteArray qExtractServerTime(const QByteArray& targetInfoBuff)
     1205{
     1206    QByteArray timeArray;
     1207    QDataStream ds(targetInfoBuff);
     1208    ds.setByteOrder(QDataStream::LittleEndian);
     1209
     1210    quint16 avId;
     1211    quint16 avLen;
     1212
     1213    ds >> avId;
     1214    ds >> avLen;
     1215    while(avId != 0) {
     1216        if(avId == AVTIMESTAMP) {
     1217            timeArray.resize(avLen);
     1218            //avLen size of QByteArray is allocated
     1219            ds.readRawData(timeArray.data(), avLen);
     1220            break;
     1221        }
     1222        ds.skipRawData(avLen);
     1223        ds >> avId;
     1224        ds >> avLen;
     1225    }
     1226    return timeArray;
     1227}
     1228
     1229static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx,
     1230                                        const QNtlmPhase2Block& ch,
     1231                                        QNtlmPhase3Block *phase3)
     1232{
     1233    Q_ASSERT(phase3 != 0);
     1234    // return value stored in phase3
     1235    qCreatev2Hash(ctx, phase3);
     1236
     1237    QByteArray temp;
     1238    QDataStream ds(&temp, QIODevice::WriteOnly);
     1239    ds.setByteOrder(QDataStream::LittleEndian);
     1240
     1241    ds << respversion;
     1242    ds << hirespversion;
     1243
     1244    //Reserved
     1245    QByteArray reserved1(6, 0);
     1246    ds.writeRawData(reserved1.constData(), reserved1.size());
     1247
     1248    quint64 time = 0;
     1249    QByteArray timeArray;
     1250
     1251    if(ch.targetInfo.len)
     1252    {
     1253        timeArray = qExtractServerTime(ch.targetInfoBuff);
     1254    }
     1255
     1256    //if server sends time, use it instead of current time
     1257    if(timeArray.size()) {
     1258        ds.writeRawData(timeArray.constData(), timeArray.size());
     1259    } else {
     1260        QDateTime currentTime(QDate::currentDate(),
     1261                              QTime::currentTime(), Qt::UTC);
     1262
     1263        // number of seconds between 1601 and epoc(1970)
     1264        // 369 years, 89 leap years
     1265        // ((369 * 365) + 89) * 24 * 3600 = 11644473600
     1266
     1267        time = Q_UINT64_C(currentTime.toTime_t() + 11644473600);
     1268
     1269        // represented as 100 nano seconds
     1270        time = Q_UINT64_C(time * 10000000);
     1271        ds << time;
     1272    }
     1273
     1274    //8 byte client challenge
     1275    QByteArray clientCh = clientChallenge(ctx);
     1276    ds.writeRawData(clientCh.constData(), clientCh.size());
     1277
     1278    //Reserved
     1279    QByteArray reserved2(4, 0);
     1280    ds.writeRawData(reserved2.constData(), reserved2.size());
     1281
     1282    if (ch.targetInfo.len > 0) {
     1283        ds.writeRawData(ch.targetInfoBuff.constData(),
     1284                        ch.targetInfoBuff.size());
     1285    }
     1286
     1287    //Reserved
     1288    QByteArray reserved3(4, 0);
     1289    ds.writeRawData(reserved3.constData(), reserved3.size());
     1290
     1291    QByteArray message((const char*)ch.challenge, sizeof(ch.challenge));
     1292    message.append(temp);
     1293
     1294    QByteArray ntChallengeResp = qEncodeHmacMd5(phase3->v2Hash, message);
     1295    ntChallengeResp.append(temp);
     1296
     1297    return ntChallengeResp;
     1298}
     1299
     1300static QByteArray qEncodeLmv2Response(const QAuthenticatorPrivate *ctx,
     1301                                      const QNtlmPhase2Block& ch,
     1302                                      QNtlmPhase3Block *phase3)
     1303{
     1304    Q_ASSERT(phase3 != 0);
     1305    // return value stored in phase3
     1306    qCreatev2Hash(ctx, phase3);
     1307
     1308    QByteArray message((const char*)ch.challenge, sizeof(ch.challenge));
     1309    QByteArray clientCh = clientChallenge(ctx);
     1310
     1311    message.append(clientCh);
     1312
     1313    QByteArray lmChallengeResp = qEncodeHmacMd5(phase3->v2Hash, message);
     1314    lmChallengeResp.append(clientCh);
     1315
     1316    return lmChallengeResp;
     1317}
    9451318
    9461319static bool qNtlmDecodePhase2(const QByteArray& data, QNtlmPhase2Block& ch)
     
    9771350
    9781351    if (ch.targetInfo.len > 0) {
    979         // UNUSED right now
     1352        if (ch.targetInfo.len + ch.targetInfo.offset > (unsigned)data.size())
     1353            return false;
     1354
     1355        ch.targetInfoBuff = data.mid(ch.targetInfo.offset, ch.targetInfo.len);
    9801356    }
    9811357
     
    9961372
    9971373    bool unicode = ch.flags & NTLMSSP_NEGOTIATE_UNICODE;
    998 
    999     ctx->realm = ch.targetNameStr;
    10001374
    10011375    pb.flags = NTLMSSP_NEGOTIATE_NTLM;
     
    10091383    Q_ASSERT(QNtlmPhase3BlockBase::Size == sizeof(QNtlmPhase3BlockBase));
    10101384   
    1011     offset = qEncodeNtlmString(pb.domain, offset, ctx->realm, unicode);
    1012     pb.domainStr = ctx->realm;
    1013     offset = qEncodeNtlmString(pb.user, offset, ctx->user, unicode);
    1014     pb.userStr = ctx->user;
     1385    if(ctx->userDomain.isEmpty()) {
     1386        offset = qEncodeNtlmString(pb.domain, offset, ch.targetNameStr, unicode);
     1387        pb.domainStr = ch.targetNameStr;
     1388    } else {
     1389        offset = qEncodeNtlmString(pb.domain, offset, ctx->userDomain, unicode);
     1390        pb.domainStr = ctx->userDomain;
     1391    }
     1392
     1393    offset = qEncodeNtlmString(pb.user, offset, ctx->extractedUser, unicode);
     1394    pb.userStr = ctx->extractedUser;
    10151395
    10161396    offset = qEncodeNtlmString(pb.workstation, offset, ctx->workstation, unicode);
     
    10181398
    10191399    // Get LM response
     1400#ifdef NTLMV1_CLIENT
    10201401    pb.lmResponseBuf = qEncodeLmResponse(ctx, ch);
     1402#else
     1403    if (ch.targetInfo.len > 0) {
     1404        pb.lmResponseBuf = QByteArray();
     1405    } else {
     1406        pb.lmResponseBuf = qEncodeLmv2Response(ctx, ch, &pb);
     1407    }
     1408#endif
    10211409    offset = qEncodeNtlmBuffer(pb.lmResponse, offset, pb.lmResponseBuf);
    10221410
    10231411    // Get NTLM response
     1412#ifdef NTLMV1_CLIENT
    10241413    pb.ntlmResponseBuf = qEncodeNtlmResponse(ctx, ch);
     1414#else
     1415    pb.ntlmResponseBuf = qEncodeNtlmv2Response(ctx, ch, &pb);
     1416#endif
    10251417    offset = qEncodeNtlmBuffer(pb.ntlmResponse, offset, pb.ntlmResponseBuf);
    10261418
  • trunk/src/network/kernel/qauthenticator.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    4444
    4545#include <QtCore/qstring.h>
     46#include <QtCore/qvariant.h>
    4647
    4748QT_BEGIN_HEADER
     
    7475    QString realm() const;
    7576
     77    QVariant option(const QString &opt) const;
     78    QVariantHash options() const;
     79    void setOption(const QString &opt, const QVariant &value);
     80
    7681    bool isNull() const;
    7782    void detach();
  • trunk/src/network/kernel/qauthenticator_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    5858#include <qstring.h>
    5959#include <qauthenticator.h>
     60#include <qvariant.h>
    6061
    6162QT_BEGIN_NAMESPACE
     
    6364class QHttpResponseHeader;
    6465
    65 class QAuthenticatorPrivate
     66class Q_AUTOTEST_EXPORT QAuthenticatorPrivate
    6667{
    6768public:
     
    7172    QAtomicInt ref;
    7273    QString user;
     74    QString extractedUser;
    7375    QString password;
    74     QHash<QByteArray, QByteArray> options;
     76    QVariantHash options;
    7577    Method method;
    7678    QString realm;
     
    9193    // ntlm specific
    9294    QString workstation;
     95    QString userDomain;
    9396
    9497    QByteArray calculateResponse(const QByteArray &method, const QByteArray &path);
     
    103106    void parseHttpResponse(const QHttpResponseHeader &, bool isProxy);
    104107#endif
     108    void parseHttpResponse(const QList<QPair<QByteArray, QByteArray> >&, bool isProxy);
    105109
    106110};
  • trunk/src/network/kernel/qhostaddress.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    429429    and QUdpSocket to connect to a host or to set up a server.
    430430
    431     A host address is set with setAddress(), checked for its type
    432     using isIPv4Address() or isIPv6Address(), and retrieved with
    433     toIPv4Address(), toIPv6Address(), or toString().
     431    A host address is set with setAddress(), and retrieved with
     432    toIPv4Address(), toIPv6Address(), or toString(). You can check the
     433    type with protocol().
    434434
    435435    \note Please note that QHostAddress does not do DNS lookups.
     
    680680    2130706433 (i.e. 0x7f000001).
    681681
    682     This value is only valid if isIp4Addr() returns true.
     682    This value is only valid if the Protocol() is
     683    \l{QAbstractSocket::}{IPv4Protocol}.
    683684
    684685    \sa toString()
     
    705706    \snippet doc/src/snippets/code/src_network_kernel_qhostaddress.cpp 0
    706707
    707     This value is only valid if isIPv6Address() returns true.
     708    This value is only valid if the protocol() is
     709    \l{QAbstractSocket::}{IPv6Protocol}.
    708710
    709711    \sa toString()
     
    10981100    to the stream.
    10991101
    1100     \sa {Format of the QDataStream operators}
     1102    \sa {Serializing Qt Data Types}
    11011103*/
    11021104QDataStream &operator<<(QDataStream &out, const QHostAddress &address)
     
    11281130    reference to the stream.
    11291131
    1130     \sa {Format of the QDataStream operators}
     1132    \sa {Serializing Qt Data Types}
    11311133*/
    11321134QDataStream &operator>>(QDataStream &in, QHostAddress &address)
  • trunk/src/network/kernel/qhostaddress.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qhostaddress_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qhostinfo.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    169169        QHostInfo hostInfo(id);
    170170        hostInfo.setError(QHostInfo::HostNotFound);
    171         hostInfo.setErrorString(QObject::tr("No host name given"));
     171        hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given"));
    172172        QScopedPointer<QHostInfoResult> result(new QHostInfoResult);
    173173        QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)),
     
    244244#endif
    245245
    246     return QHostInfoAgent::fromName(name);
     246    QHostInfo hostInfo = QHostInfoAgent::fromName(name);
     247    QHostInfoLookupManager *manager = theHostInfoLookupManager();
     248    manager->cache.put(name, hostInfo);
     249    return hostInfo;
    247250}
    248251
     
    468471    resultEmitter.emitResultsReady(hostInfo);
    469472
     473    // now also iterate through the postponed ones
     474    {
     475        QMutexLocker locker(&manager->mutex);
     476        QMutableListIterator<QHostInfoRunnable*> iterator(manager->postponedLookups);
     477        while (iterator.hasNext()) {
     478            QHostInfoRunnable* postponed = iterator.next();
     479            if (toBeLookedUp == postponed->toBeLookedUp) {
     480                // we can now emit
     481                iterator.remove();
     482                hostInfo.setLookupId(postponed->id);
     483                postponed->resultEmitter.emitResultsReady(hostInfo);
     484            }
     485        }
     486    }
     487
    470488    manager->lookupFinished(this);
    471489
     
    485503
    486504    // don't qDeleteAll currentLookups, the QThreadPool has ownership
    487     qDeleteAll(postponedLookups);
    488     qDeleteAll(scheduledLookups);
    489     qDeleteAll(finishedLookups);
     505    clear();
     506}
     507
     508void QHostInfoLookupManager::clear()
     509{
     510    {
     511        QMutexLocker locker(&mutex);
     512        qDeleteAll(postponedLookups);
     513        qDeleteAll(scheduledLookups);
     514        qDeleteAll(finishedLookups);
     515        postponedLookups.clear();
     516        scheduledLookups.clear();
     517        finishedLookups.clear();
     518    }
     519
     520    threadPool.waitForDone();
     521    cache.clear();
    490522}
    491523
     
    579611
    580612    QMutexLocker locker(&this->mutex);
     613
     614    // is postponed? delete and return
     615    for (int i = 0; i < postponedLookups.length(); i++) {
     616        if (postponedLookups.at(i)->id == id) {
     617            delete postponedLookups.takeAt(i);
     618            return;
     619        }
     620    }
     621
     622    // is scheduled? delete and return
     623    for (int i = 0; i < scheduledLookups.length(); i++) {
     624        if (scheduledLookups.at(i)->id == id) {
     625            delete scheduledLookups.takeAt(i);
     626            return;
     627        }
     628    }
     629
    581630    if (!abortedLookups.contains(id))
    582631        abortedLookups.append(id);
     
    605654}
    606655
    607 // This function returns immediatly when we had a result in the cache, else it will later emit a signal
     656// This function returns immediately when we had a result in the cache, else it will later emit a signal
    608657QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id)
    609658{
     
    631680    QHostInfoLookupManager* manager = theHostInfoLookupManager();
    632681    if (manager) {
    633         manager->cache.clear();
     682        manager->clear();
    634683    }
    635684}
  • trunk/src/network/kernel/qhostinfo.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qhostinfo_p.h

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    8585
    8686Q_SIGNALS:
    87     void resultsReady(const QHostInfo info);
     87    void resultsReady(const QHostInfo &info);
    8888};
    8989
     
    117117// Do NOT use them outside of QAbstractSocket.
    118118QHostInfo Q_NETWORK_EXPORT qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id);
    119 void Q_NETWORK_EXPORT qt_qhostinfo_clear_cache();
     119void Q_AUTOTEST_EXPORT qt_qhostinfo_clear_cache();
    120120void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e);
    121121
     
    162162    ~QHostInfoLookupManager();
    163163
     164    void clear();
    164165    void work();
    165166
     
    173174
    174175    QHostInfoCache cache;
     176
     177    friend class QHostInfoRunnable;
    175178protected:
    176179    QList<QHostInfoRunnable*> currentLookups; // in progress
  • trunk/src/network/kernel/qhostinfo_unix.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    195195    if (aceHostname.isEmpty()) {
    196196        results.setError(QHostInfo::HostNotFound);
    197         results.setErrorString(hostName.isEmpty() ? QObject::tr("No host name given") : QObject::tr("Invalid hostname"));
     197        results.setErrorString(hostName.isEmpty() ?
     198                               QCoreApplication::translate("QHostInfoAgent", "No host name given") :
     199                               QCoreApplication::translate("QHostInfoAgent", "Invalid hostname"));
    198200        return results;
    199201    }
     
    209211    hints.ai_flags = Q_ADDRCONFIG;
    210212#endif
     213#ifdef Q_OS_SYMBIAN
     214#   ifdef QHOSTINFO_DEBUG
     215        qDebug() << "Setting flags: 'hints.ai_flags &= AI_V4MAPPED | AI_ALL'";
     216#   endif
     217#endif
    211218
    212219    int result = getaddrinfo(aceHostname.constData(), 0, &hints, &res);
     
    215222        // if the lookup failed with AI_ADDRCONFIG set, try again without it
    216223        hints.ai_flags = 0;
     224#ifdef Q_OS_SYMBIAN
     225#   ifdef QHOSTINFO_DEBUG
     226        qDebug() << "Setting flags: 'hints.ai_flags &= AI_V4MAPPED | AI_ALL'";
     227#   endif
     228        hints.ai_flags &= AI_V4MAPPED | AI_ALL;
     229#endif
    217230        result = getaddrinfo(aceHostname.constData(), 0, &hints, &res);
    218231    }
     
    223236        QList<QHostAddress> addresses;
    224237        while (node) {
     238#ifdef QHOSTINFO_DEBUG
     239                qDebug() << "getaddrinfo node: flags:" << node->ai_flags << "family:" << node->ai_family << "ai_socktype:" << node->ai_socktype << "ai_protocol:" << node->ai_protocol << "ai_addrlen:" << node->ai_addrlen;
     240#endif
    225241            if (node->ai_family == AF_INET) {
    226242                QHostAddress addr;
     
    232248            else if (node->ai_family == AF_INET6) {
    233249                QHostAddress addr;
    234                 addr.setAddress(((sockaddr_in6 *) node->ai_addr)->sin6_addr.s6_addr);
     250                sockaddr_in6 *sa6 = (sockaddr_in6 *) node->ai_addr;
     251                addr.setAddress(sa6->sin6_addr.s6_addr);
     252                if (sa6->sin6_scope_id)
     253                    addr.setScopeId(QString::number(sa6->sin6_scope_id));
    235254                if (!addresses.contains(addr))
    236255                    addresses.append(addr);
  • trunk/src/network/kernel/qhostinfo_win.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    5050#include "private/qnativesocketengine_p.h"
    5151#include <ws2tcpip.h>
    52 #include <qlibrary.h>
     52#include <private/qsystemlibrary_p.h>
    5353#include <qmutex.h>
    5454#include <qurl.h>
     
    9191    // back to gethostbyname(), which has no IPv6 support.
    9292#if !defined(Q_OS_WINCE)
    93     local_getaddrinfo = (getaddrinfoProto) QLibrary::resolve(QLatin1String("ws2_32.dll"), "getaddrinfo");
    94     local_freeaddrinfo = (freeaddrinfoProto) QLibrary::resolve(QLatin1String("ws2_32.dll"), "freeaddrinfo");
    95     local_getnameinfo = (getnameinfoProto) QLibrary::resolve(QLatin1String("ws2_32.dll"), "getnameinfo");
     93    local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getaddrinfo");
     94    local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo");
     95    local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo");
    9696#else
    97     local_getaddrinfo = (getaddrinfoProto) QLibrary::resolve(QLatin1String("ws2.dll"), "getaddrinfo");
    98     local_freeaddrinfo = (freeaddrinfoProto) QLibrary::resolve(QLatin1String("ws2.dll"), "freeaddrinfo");
    99     local_getnameinfo = (getnameinfoProto) QLibrary::resolve(QLatin1String("ws2.dll"), "getnameinfo");
     97    local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "getaddrinfo");
     98    local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "freeaddrinfo");
     99    local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "getnameinfo");
    100100#endif
    101101}
  • trunk/src/network/kernel/qnetworkinterface.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qnetworkinterface.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qnetworkinterface_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qnetworkinterface_symbian.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qnetworkinterface_unix.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qnetworkinterface_win.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    4949#include <qhash.h>
    5050#include <qurl.h>
     51#include <private/qsystemlibrary_p.h>
    5152
    5253QT_BEGIN_NAMESPACE
     
    6768        done = true;
    6869
    69         HINSTANCE iphlpapiHnd = LoadLibrary(L"iphlpapi");
     70        HINSTANCE iphlpapiHnd = QSystemLibrary::load(L"iphlpapi");
    7071        if (iphlpapiHnd == NULL)
    7172            return;
  • trunk/src/network/kernel/qnetworkinterface_win_p.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qnetworkproxy.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    427427    : d(0)
    428428{
    429     globalNetworkProxy()->init();
     429    if (QGlobalNetworkProxy *globalProxy = globalNetworkProxy())
     430        globalProxy->init();
    430431}
    431432
     
    442443    : d(new QNetworkProxyPrivate(type, hostName, port, user, password))
    443444{
    444     globalNetworkProxy()->init();
     445    if (QGlobalNetworkProxy *globalProxy = globalNetworkProxy())
     446        globalProxy->init();
    445447}
    446448
     
    11391141    such object, the factory will be queried for sockets created by
    11401142    that framework only.
     1143
     1144    \section1 System Proxies
     1145
     1146    You can configure a factory to use the system proxy's settings.
     1147    Call the setUseSystemConfiguration() function with true to enable
     1148    this behavior, or false to disable it.
     1149
     1150    Similarly, you can use a factory to make queries directly to the
     1151    system proxy by calling its systemProxyForQuery() function.
     1152
     1153    \warning Depending on the configuration of the user's system, the
     1154    use of system proxy features on certain platforms may be subject
     1155    to limitations. The systemProxyForQuery() documentation contains a
     1156    list of these limitations for those platforms that are affected.
    11411157*/
    11421158
     
    11601176
    11611177/*!
     1178    \since 4.6
     1179
    11621180    Enables the use of the platform-specific proxy settings, and only those.
    11631181    See systemProxyForQuery() for more information.
     
    11651183    Internally, this method (when called with \a enable set to true)
    11661184    sets an application-wide proxy factory. For this reason, this method
    1167     is mutually exclusive with setApplicationProxyFactory: calling
    1168     setApplicationProxyFactory overrides the use of the system-wide proxy,
    1169     and calling setUseSystemConfiguration overrides any
     1185    is mutually exclusive with setApplicationProxyFactory(): calling
     1186    setApplicationProxyFactory() overrides the use of the system-wide proxy,
     1187    and calling setUseSystemConfiguration() overrides any
    11701188    application proxy or proxy factory that was previously set.
    11711189
    1172     \since 4.6
     1190    \note See the systemProxyForQuery() documentation for a list of
     1191    limitations related to the use of system proxies.
    11731192*/
    11741193void QNetworkProxyFactory::setUseSystemConfiguration(bool enable)
     
    12651284    listed here.
    12661285
    1267     On MacOS X, this function will ignore the Proxy Auto Configuration
     1286    \list
     1287    \o On MacOS X, this function will ignore the Proxy Auto Configuration
    12681288    settings, since it cannot execute the associated ECMAScript code.
     1289
     1290    \o On Windows platforms, this function may take several seconds to
     1291    execute depending on the configuration of the user's system.
     1292    \endlist
    12691293*/
    12701294
  • trunk/src/network/kernel/qnetworkproxy.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qnetworkproxy_generic.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qnetworkproxy_mac.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    158158    }
    159159
    160     if (isHostExcluded(dict, query.peerHostName()))
     160    if (isHostExcluded(dict, query.peerHostName())) {
     161        CFRelease(dict);
    161162        return result;          // no proxy for this host
     163    }
    162164
    163165    // is there a PAC enabled? If so, use it first.
     
    223225    }
    224226
     227    CFRelease(dict);
    225228    return result;
    226229}
  • trunk/src/network/kernel/qnetworkproxy_win.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    5252#include <qt_windows.h>
    5353#include <wininet.h>
     54#include <private/qsystemlibrary_p.h>
    5455
    5556/*
     
    100101#define WINHTTP_NO_PROXY_NAME     NULL
    101102#define WINHTTP_NO_PROXY_BYPASS   NULL
     103
     104#define WINHTTP_ERROR_BASE                      12000
     105#define ERROR_WINHTTP_LOGIN_FAILURE             (WINHTTP_ERROR_BASE + 15)
     106#define ERROR_WINHTTP_AUTODETECTION_FAILED      (WINHTTP_ERROR_BASE + 180)
    102107
    103108QT_BEGIN_NAMESPACE
     
    274279#else
    275280    // load the winhttp.dll library
    276     HINSTANCE winhttpHnd = LoadLibrary(L"winhttp");
    277     if (!winhttpHnd)
     281    QSystemLibrary lib(L"winhttp");
     282    if (!lib.load())
    278283        return;                 // failed to load
    279284
    280     ptrWinHttpOpen = (PtrWinHttpOpen)GetProcAddress(winhttpHnd, "WinHttpOpen");
    281     ptrWinHttpCloseHandle = (PtrWinHttpCloseHandle)GetProcAddress(winhttpHnd, "WinHttpCloseHandle");
    282     ptrWinHttpGetProxyForUrl = (PtrWinHttpGetProxyForUrl)GetProcAddress(winhttpHnd, "WinHttpGetProxyForUrl");
    283     ptrWinHttpGetDefaultProxyConfiguration = (PtrWinHttpGetDefaultProxyConfiguration)GetProcAddress(winhttpHnd, "WinHttpGetDefaultProxyConfiguration");
    284     ptrWinHttpGetIEProxyConfigForCurrentUser = (PtrWinHttpGetIEProxyConfigForCurrentUser)GetProcAddress(winhttpHnd, "WinHttpGetIEProxyConfigForCurrentUser");
     285    ptrWinHttpOpen = (PtrWinHttpOpen)lib.resolve("WinHttpOpen");
     286    ptrWinHttpCloseHandle = (PtrWinHttpCloseHandle)lib.resolve("WinHttpCloseHandle");
     287    ptrWinHttpGetProxyForUrl = (PtrWinHttpGetProxyForUrl)lib.resolve("WinHttpGetProxyForUrl");
     288    ptrWinHttpGetDefaultProxyConfiguration = (PtrWinHttpGetDefaultProxyConfiguration)lib.resolve("WinHttpGetDefaultProxyConfiguration");
     289    ptrWinHttpGetIEProxyConfigForCurrentUser = (PtrWinHttpGetIEProxyConfigForCurrentUser)lib.resolve("WinHttpGetIEProxyConfigForCurrentUser");
    285290
    286291    // Try to obtain the Internet Explorer configuration.
     
    321326        isAutoConfig = true;
    322327        memset(&autoProxyOptions, 0, sizeof autoProxyOptions);
    323         autoProxyOptions.fAutoLogonIfChallenged = true;
     328        autoProxyOptions.fAutoLogonIfChallenged = false;
    324329        if (ieProxyConfig.fAutoDetect) {
    325330            autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
     
    378383            url.setScheme(QLatin1String("https"));
    379384        }
    380         if (ptrWinHttpGetProxyForUrl(sp->hHttpSession,
    381                                      (LPCWSTR)url.toString().utf16(),
    382                                      &sp->autoProxyOptions,
    383                                      &proxyInfo)) {
     385
     386        bool getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession,
     387                                                (LPCWSTR)url.toString().utf16(),
     388                                                &sp->autoProxyOptions,
     389                                                &proxyInfo);
     390        DWORD getProxyError = GetLastError();
     391
     392        if (!getProxySucceeded
     393            && (ERROR_WINHTTP_LOGIN_FAILURE == getProxyError)) {
     394            // We first tried without AutoLogon, because this might prevent caching the result.
     395            // But now we've to enable it (http://msdn.microsoft.com/en-us/library/aa383153%28v=VS.85%29.aspx)
     396            sp->autoProxyOptions.fAutoLogonIfChallenged = TRUE;
     397            getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession,
     398                                               (LPCWSTR)url.toString().utf16(),
     399                                                &sp->autoProxyOptions,
     400                                                &proxyInfo);
     401            getProxyError = GetLastError();
     402        }
     403
     404        if (getProxySucceeded) {
    384405            // yes, we got a config for this URL
    385406            QString proxyBypass = QString::fromWCharArray(proxyInfo.lpszProxyBypass);
     
    396417
    397418        // GetProxyForUrl failed
     419
     420        if (ERROR_WINHTTP_AUTODETECTION_FAILED == getProxyError) {
     421            //No config file could be retrieved on the network.
     422            //Don't search for it next time again.
     423            sp->isAutoConfig = false;
     424        }
     425
    398426        return sp->defaultResult;
    399427    }
  • trunk/src/network/kernel/qurlinfo.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
  • trunk/src/network/kernel/qurlinfo.h

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
Note: See TracChangeset for help on using the changeset viewer.