Ignore:
Timestamp:
Aug 2, 2010, 9:27:30 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

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

Location:
trunk
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/network/access/qfilenetworkreply.cpp

    r651 r769  
    5050
    5151QFileNetworkReplyPrivate::QFileNetworkReplyPrivate()
    52     : QNetworkReplyPrivate(), realFileSize(0)
    53 {
     52    : QNetworkReplyPrivate(), fileEngine(0), fileSize(0), filePos(0)
     53{
     54}
     55
     56QFileNetworkReplyPrivate::~QFileNetworkReplyPrivate()
     57{
     58    delete fileEngine;
    5459}
    5560
     
    95100        fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);
    96101    }
    97     d->realFile.setFileName(fileName);
    98 
    99     QFileInfo fi(d->realFile);
     102
     103    QFileInfo fi(fileName);
    100104    if (fi.isDir()) {
    101105        QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString());
     
    107111    }
    108112
    109     bool opened = d->realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
     113    d->fileEngine = QAbstractFileEngine::create(fileName);
     114    bool opened = d->fileEngine->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
    110115
    111116    // could we open the file?
    112117    if (!opened) {
    113118        QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2")
    114                       .arg(d->realFile.fileName(), d->realFile.errorString());
    115 
    116         if (d->realFile.exists()) {
     119                      .arg(errorString());
     120
     121        if (.exists()) {
    117122            setError(QNetworkReply::ContentAccessDenied, msg);
    118123            QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
     
    127132    }
    128133
    129     d->realFileSize = fi.size();
     134    d->ileSize = fi.size();
    130135    setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified());
    131     setHeader(QNetworkRequest::ContentLengthHeader, d->realFileSize);
     136    setHeader(QNetworkRequest::ContentLengthHeader, d->ileSize);
    132137
    133138    QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
    134139    QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection,
    135         Q_ARG(qint64, d->realFileSize), Q_ARG(qint64, d->realFileSize));
     140        Q_ARG(qint64, d->ileSize));
    136141    QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
    137142    QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
     
    147152    Q_D(QFileNetworkReply);
    148153    QNetworkReply::close();
    149     d->realFile.close();
     154    if (d->fileEngine)
     155        d->fileEngine->close();
    150156}
    151157
     
    154160    Q_D(QFileNetworkReply);
    155161    QNetworkReply::close();
    156     d->realFile.close();
     162    if (d->fileEngine)
     163        d->fileEngine->close();
    157164}
    158165
     
    160167{
    161168    Q_D(const QFileNetworkReply);
    162     return QNetworkReply::bytesAvailable() + d->realFile.bytesAvailable();
     169    if (!d->fileEngine)
     170        return 0;
     171
     172    return QNetworkReply::bytesAvailable() + d->fileSize - d->filePos;
    163173}
    164174
     
    171181{
    172182    Q_D(const QFileNetworkReply);
    173     return d->realFileSize;
     183    return d->ileSize;
    174184}
    175185
     
    180190{
    181191    Q_D(QFileNetworkReply);
    182     qint64 ret = d->realFile.read(data, maxlen);
    183     if (ret == 0 && bytesAvailable() == 0)
     192    if (!d->fileEngine)
     193        return -1;
     194
     195    qint64 ret = d->fileEngine->read(data, maxlen);
     196    if (ret == 0 && bytesAvailable() == 0) {
    184197        return -1; // everything had been read
    185     else
    186         return ret;
     198    } else if (ret > 0) {
     199        d->filePos += ret;
     200    }
     201
     202    return ret;
    187203}
    188204
  • trunk/src/network/access/qfilenetworkreply_p.h

    r651 r769  
    5858#include "qnetworkaccessmanager.h"
    5959#include <QFile>
     60
    6061
    6162QT_BEGIN_NAMESPACE
     
    8687public:
    8788    QFileNetworkReplyPrivate();
     89
    8890
    89     QFile realFile;
    90     qint64 realFileSize;
     91    QAbstractFileEngine *fileEngine;
     92    qint64 fileSize;
     93    qint64 filePos;
    9194
    9295    virtual bool isFinished() const;
  • trunk/src/network/access/qftp.cpp

    r651 r769  
    23102310{
    23112311    Q_Q(QFtp);
     2312
     2313
     2314
     2315
     2316
     2317
    23122318    QFtpCommand *c = pending.first();
    23132319
  • trunk/src/network/access/qhttpnetworkconnection.cpp

    r651 r769  
    7272#endif
    7373
    74 // the maximum amount of requests that might be pipelined into a socket
    75 // from what was suggested, 3 seems to be OK
     74// The pipeline length. So there will be 4 requests in flight.
    7675const int QHttpNetworkConnectionPrivate::defaultPipelineLength = 3;
     76
     77
     78
    7779
    7880
     
    405407    reply->setRequest(request);
    406408    reply->d_func()->connection = q;
     409
    407410    HttpMessagePair pair = qMakePair(request, reply);
    408411
     
    416419        break;
    417420    }
     421
    418422    // this used to be called via invokeMethod and a QueuedConnection
     423
     424
     425
     426
     427
     428
     429
    419430    _q_startNextRequest();
     431
     432
    420433    return reply;
    421434}
     
    423436void QHttpNetworkConnectionPrivate::requeueRequest(const HttpMessagePair &pair)
    424437{
     438
     439
    425440    QHttpNetworkRequest request = pair.first;
    426441    switch (request.priority()) {
     
    433448        break;
    434449    }
    435     // this used to be called via invokeMethod and a QueuedConnection
    436     _q_startNextRequest();
     450
     451    );
    437452}
    438453
     
    475490    int i = indexOf(socket);
    476491
    477     bool highPriorityQueueProcessingDone = false;
    478     bool lowPriorityQueueProcessingDone = false;
    479 
    480     while (!highPriorityQueueProcessingDone && !lowPriorityQueueProcessingDone) {
    481         // this loop runs once per request we intend to pipeline in.
    482 
    483         if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported)
    484             return;
    485 
    486         // the current request that is in must already support pipelining
    487         if (!channels[i].request.isPipeliningAllowed())
    488             return;
    489 
    490         // the current request must be a idempotent (right now we only check GET)
    491         if (channels[i].request.operation() != QHttpNetworkRequest::Get)
    492             return;
    493 
    494         // check if socket is connected
    495         if (socket->state() != QAbstractSocket::ConnectedState)
    496             return;
    497 
    498         // check for resendCurrent
    499         if (channels[i].resendCurrent)
    500             return;
    501 
    502         // we do not like authentication stuff
    503         // ### make sure to be OK with this in later releases
    504         if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty())
    505             return;
    506         if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty())
    507             return;
    508 
    509         // check for pipeline length
     492    // return fast if there was no reply right now processed
     493    if (channels[i].reply == 0)
     494        return;
     495
     496    if (! (defaultPipelineLength - channels[i].alreadyPipelinedRequests.length() >= defaultRePipelineLength)) {
     497        return;
     498    }
     499
     500    if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported)
     501        return;
     502
     503    // the current request that is in must already support pipelining
     504    if (!channels[i].request.isPipeliningAllowed())
     505        return;
     506
     507    // the current request must be a idempotent (right now we only check GET)
     508    if (channels[i].request.operation() != QHttpNetworkRequest::Get)
     509        return;
     510
     511    // check if socket is connected
     512    if (socket->state() != QAbstractSocket::ConnectedState)
     513        return;
     514
     515    // check for resendCurrent
     516    if (channels[i].resendCurrent)
     517        return;
     518
     519    // we do not like authentication stuff
     520    // ### make sure to be OK with this in later releases
     521    if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty())
     522        return;
     523    if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty())
     524        return;
     525
     526    // must be in ReadingState or WaitingState
     527    if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState
     528           || channels[i].state == QHttpNetworkConnectionChannel::ReadingState))
     529        return;
     530
     531
     532    //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing highPriorityQueue, size=" << highPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length();
     533    int lengthBefore;
     534    while (!highPriorityQueue.isEmpty()) {
     535        lengthBefore = channels[i].alreadyPipelinedRequests.length();
     536        fillPipeline(highPriorityQueue, channels[i]);
     537
    510538        if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
    511539            return;
    512540
    513         // must be in ReadingState or WaitingState
    514         if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState
    515                || channels[i].state == QHttpNetworkConnectionChannel::ReadingState))
     541        if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
     542            break; // did not process anything, now do the low prio queue
     543    }
     544
     545    //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing lowPriorityQueue, size=" << lowPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length();
     546    while (!lowPriorityQueue.isEmpty()) {
     547        lengthBefore = channels[i].alreadyPipelinedRequests.length();
     548        fillPipeline(lowPriorityQueue, channels[i]);
     549
     550        if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
    516551            return;
    517552
    518         highPriorityQueueProcessingDone = fillPipeline(highPriorityQueue, channels[i]);
    519         // not finished with highPriorityQueue? then loop again
    520         if (!highPriorityQueueProcessingDone)
    521             continue;
    522         // highPriorityQueue was processed, now deal with the lowPriorityQueue
    523         lowPriorityQueueProcessingDone = fillPipeline(lowPriorityQueue, channels[i]);
    524     }
     553        if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
     554            break; // did not process anything
     555    }
     556
     557
    525558}
    526559
     
    682715
    683716
     717
     718
     719
    684720void QHttpNetworkConnectionPrivate::_q_startNextRequest()
    685721{
     
    689725            channels[i].resendCurrent = false;
    690726            channels[i].state = QHttpNetworkConnectionChannel::IdleState;
    691             if (channels[i].reply)
    692                 channels[i].sendRequest();
     727
     728            // if this is not possible, error will be emitted and connection terminated
     729            if (!channels[i].resetUploadData())
     730                continue;
     731            channels[i].sendRequest();
    693732        }
    694733    }
     
    696735    // dequeue new ones
    697736
    698     QAbstractSocket *socket = 0;
     737    // return fast if there is nothing to do
     738    if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
     739        return;
     740    // try to get a free AND connected socket
    699741    for (int i = 0; i < channelCount; ++i) {
    700         QAbstractSocket *chSocket = channels[i].socket;
    701         // try to get a free AND connected socket
    702742        if (!channels[i].isSocketBusy() && channels[i].socket->state() == QAbstractSocket::ConnectedState) {
    703             socket = chSocket;
    704             dequeueAndSendRequest(socket);
    705             break;
    706         }
    707     }
    708 
    709     if (!socket) {
    710         for (int i = 0; i < channelCount; ++i) {
    711             QAbstractSocket *chSocket = channels[i].socket;
    712             // try to get a free unconnected socket
    713             if (!channels[i].isSocketBusy()) {
    714                 socket = chSocket;
    715                 dequeueAndSendRequest(socket);
    716                 break;
    717             }
     743            dequeueAndSendRequest(channels[i].socket);
     744        }
     745    }
     746
     747    // return fast if there is nothing to do
     748    if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
     749        return;
     750    // try to get a free unconnected socket
     751    for (int i = 0; i < channelCount; ++i) {
     752        if (!channels[i].isSocketBusy()) {
     753            dequeueAndSendRequest(channels[i].socket);
    718754        }
    719755    }
     
    729765    if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
    730766        return;
    731     for (int j = 0; j < channelCount; j++)
    732         fillPipeline(channels[j].socket);
     767    for (int i = 0; i < channelCount; i++)
     768        if (channels[i].socket->state() == QAbstractSocket::ConnectedState)
     769            fillPipeline(channels[i].socket);
    733770}
    734771
     
    856893// SSL support below
    857894#ifndef QT_NO_OPENSSL
    858 QSslConfiguration QHttpNetworkConnectionPrivate::sslConfiguration(const QHttpNetworkReply &reply) const
    859 {
    860     if (!encrypt)
    861         return QSslConfiguration();
    862 
    863     for (int i = 0; i < channelCount; ++i)
    864         if (channels[i].reply == &reply)
    865             return static_cast<QSslSocket *>(channels[0].socket)->sslConfiguration();
    866     return QSslConfiguration(); // pending or done request
    867 }
    868 
    869895void QHttpNetworkConnection::setSslConfiguration(const QSslConfiguration &config)
    870896{
  • trunk/src/network/access/qhttpnetworkconnection_p.h

    r651 r769  
    157157    static const int defaultChannelCount;
    158158    static const int defaultPipelineLength;
     159
    159160
    160161    QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt);
     
    211212    bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend);
    212213
    213 
    214 #ifndef QT_NO_OPENSSL
    215     QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const;
    216 #endif
    217 
    218214#ifndef QT_NO_NETWORKPROXY
    219215    QNetworkProxy networkProxy;
  • trunk/src/network/access/qhttpnetworkconnectionchannel.cpp

    r651 r769  
    5959// TODO: Put channel specific stuff here so it does not polute qhttpnetworkconnection.cpp
    6060
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
    6183void QHttpNetworkConnectionChannel::init()
    6284{
     
    125147bool QHttpNetworkConnectionChannel::sendRequest()
    126148{
     149
     150
     151
     152
     153
     154
     155
    127156    switch (state) {
    128157    case QHttpNetworkConnectionChannel::IdleState: { // write the header
     
    135164        written = 0; // excluding the header
    136165        bytesTotal = 0;
    137         if (reply) {
    138             reply->d_func()->clear();
    139             reply->d_func()->connection = connection;
    140             reply->d_func()->autoDecompress = request.d->autoDecompress;
    141             reply->d_func()->pipeliningUsed = false;
    142         }
    143         state = QHttpNetworkConnectionChannel::WritingState;
     166
     167        reply->d_func()->clear();
     168        reply->d_func()->connection = connection;
     169        s;
     170        ;
     171       
     172
    144173        pendingEncrypt = false;
    145174        // if the url contains authentication parameters, use the new ones
     
    175204
    176205            bytesTotal = request.contentLength();
     206
     207
     208
    177209        } else {
    178             state = QHttpNetworkConnectionChannel::WaitingState;
    179             sendRequest();
    180             break;
    181         }
    182         // write the initial chunk together with the headers
    183         // fall through
     210            state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
     211            sendRequest(); //recurse
     212        }
     213
     214        break;
    184215    }
    185216    case QHttpNetworkConnectionChannel::WritingState:
     
    191222                emit reply->dataSendProgress(written, bytesTotal);
    192223            state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
    193             sendRequest();
     224            sendRequest();
    194225            break;
    195226        }
     
    255286
    256287        // HTTP pipelining
    257         connection->d_func()->fillPipeline(socket);
    258         socket->flush();
     288        connection->d_func()->fillPipeline(socket);
     289        socket->flush();
    259290
    260291        // ensure we try to receive a reply in all cases, even if _q_readyRead_ hat not been called
    261292        // this is needed if the sends an reply before we have finished sending the request. In that
    262293        // case receiveReply had been called before but ignored the server reply
    263         QMetaObject::invokeMethod(this, "_q_receiveReply", Qt::QueuedConnection);
     294        if (socket->bytesAvailable())
     295            QMetaObject::invokeMethod(this, "_q_receiveReply", Qt::QueuedConnection);
    264296        break;
    265297    }
     
    279311    Q_ASSERT(socket);
    280312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
    281328    qint64 bytes = 0;
    282329    QAbstractSocket::SocketState socketState = socket->state();
     
    284331    // connection might be closed to signal the end of data
    285332    if (socketState == QAbstractSocket::UnconnectedState) {
    286         if (!socket->bytesAvailable()) {
    287             if (reply && reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) {
     333        if (socket->bytesAvailable() <= 0) {
     334            if (reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) {
     335                // finish this reply. this case happens when the server did not send a content length
    288336                reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;
    289                 this->state = QHttpNetworkConnectionChannel::IdleState;
    290337                allDone();
     338
    291339            } else {
    292                 // try to reconnect/resend before sending an error.
    293                 if (reconnectAttempts-- > 0) {
    294                     closeAndResendCurrentRequest();
    295                 } else if (reply) {
    296                     reply->d_func()->errorString = connection->d_func()->errorDetail(QNetworkReply::RemoteHostClosedError, socket);
    297                     emit reply->finishedWithError(QNetworkReply::RemoteHostClosedError, reply->d_func()->errorString);
    298                     QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
    299                 }
    300             }
     340                handleUnexpectedEOF();
     341                return;
     342            }
     343        } else {
     344            // socket not connected but still bytes for reading.. just continue in this function
    301345        }
    302346    }
     
    304348    // read loop for the response
    305349    while (socket->bytesAvailable()) {
    306         QHttpNetworkReplyPrivate::ReplyState state = reply ? reply->d_func()->state : QHttpNetworkReplyPrivate::AllDoneState;
     350        QHttpNetworkReplyPrivate::ReplyState state = replytate;
    307351        switch (state) {
    308         case QHttpNetworkReplyPrivate::NothingDoneState:
     352        case QHttpNetworkReplyPrivate::NothingDoneState: {
     353            // only eat whitespace on the first call
     354            eatWhitespace();
     355            state = reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;
     356            // fallthrough
     357        }
    309358        case QHttpNetworkReplyPrivate::ReadingStatusState: {
    310             eatWhitespace();
    311359            qint64 statusBytes = reply->d_func()->readStatus(socket);
    312             if (statusBytes == -1 && reconnectAttempts <= 0) {
    313                 // too many errors reading/receiving/parsing the status, close the socket and emit error
    314                 close();
    315                 reply->d_func()->errorString = connection->d_func()->errorDetail(QNetworkReply::ProtocolFailure, socket);
    316                 emit reply->finishedWithError(QNetworkReply::ProtocolFailure, reply->d_func()->errorString);
    317                 QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
    318                 break;
    319             } else if (statusBytes == -1) {
    320                 reconnectAttempts--;
    321                 reply->d_func()->clear();
    322                 closeAndResendCurrentRequest();
    323                 break;
     360            if (statusBytes == -1) {
     361                // connection broke while reading status. also handled if later _q_disconnected is called
     362                handleUnexpectedEOF();
     363                return;
    324364            }
    325365            bytes += statusBytes;
     
    329369        case QHttpNetworkReplyPrivate::ReadingHeaderState: {
    330370            QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
    331             bytes += replyPrivate->readHeader(socket);
     371            qint64 headerBytes = replyPrivate->readHeader(socket);
     372            if (headerBytes == -1) {
     373                // connection broke while reading headers. also handled if later _q_disconnected is called
     374                handleUnexpectedEOF();
     375                return;
     376            }
     377            bytes += headerBytes;
    332378            if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) {
    333379                if (replyPrivate->isGzipped() && replyPrivate->autoDecompress) {
     
    338384                }
    339385                if (replyPrivate->statusCode == 100) {
     386
    340387                    replyPrivate->state = QHttpNetworkReplyPrivate::ReadingStatusState;
    341388                    break; // ignore
     
    345392                if (!replyPrivate->expectContent()) {
    346393                    replyPrivate->state = QHttpNetworkReplyPrivate::AllDoneState;
    347                     this->state = QHttpNetworkConnectionChannel::IdleState;
    348394                    allDone();
    349                     return;
     395                    ;
    350396                }
    351397            }
     
    417463                }
    418464            }
     465
    419466            if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState)
    420467                break;
     468
    421469            // everything done, fall through
    422470            }
    423471      case QHttpNetworkReplyPrivate::AllDoneState:
    424             this->state = QHttpNetworkConnectionChannel::IdleState;
    425472            allDone();
    426473            break;
     
    428475            break;
    429476        }
     477
     478
     479
     480
     481
     482
     483
     484
     485
     486
     487
     488
     489
     490
     491
     492
     493
     494
     495
    430496    }
    431497}
     
    557623    // ### at this point there should be no more data on the socket
    558624    // close if server requested
    559     if (reply->d_func()->isConnectionCloseEnabled())
     625    bool connectionCloseEnabled = reply->d_func()->isConnectionCloseEnabled();
     626    if (connectionCloseEnabled)
    560627        close();
    561628    // queue the finished signal, this is required since we might send new requests from
     
    570637    detectPipeliningSupport();
    571638
     639
     640
     641
     642
     643
     644
     645
     646
     647
     648
     649
    572650    // move next from pipeline to current request
    573651    if (!alreadyPipelinedRequests.isEmpty()) {
    574         if (resendCurrent || reply->d_func()->isConnectionCloseEnabled() || socket->state() != QAbstractSocket::ConnectedState) {
     652        if (resendCurrent || || socket->state() != QAbstractSocket::ConnectedState) {
    575653            // move the pipelined ones back to the main queue
    576654            requeueCurrentlyPipelinedRequests();
     
    592670
    593671            // continue reading
    594             _q_receiveReply();
     672            //_q_receiveReply();
     673            // this was wrong, allDone gets called from that function anyway.
    595674        }
    596675    } else if (alreadyPipelinedRequests.isEmpty() && socket->bytesAvailable() > 0) {
     
    608687{
    609688    // detect HTTP Pipelining support
    610     QByteArray serverHeaderField = reply->headerField("Server");
     689    QByteArray serverHeaderField;
    611690    if (
    612             // check for broken servers in server reply header
    613             // this is adapted from http://mxr.mozilla.org/firefox/ident?i=SupportsPipelining
    614             (!serverHeaderField.contains("Microsoft-IIS/4."))
    615             && (!serverHeaderField.contains("Microsoft-IIS/5."))
    616             && (!serverHeaderField.contains("Netscape-Enterprise/3."))
    617691            // check for HTTP/1.1
    618             && (reply->d_func()->majorVersion == 1 && reply->d_func()->minorVersion == 1)
     692            (reply->d_func()->majorVersion == 1 && reply->d_func()->minorVersion == 1)
    619693            // check for not having connection close
    620694            && (!reply->d_func()->isConnectionCloseEnabled())
    621695            // check if it is still connected
    622696            && (socket->state() == QAbstractSocket::ConnectedState)
     697
     698
     699
     700
     701
     702
     703
    623704            ) {
    624705        pipeliningSupported = QHttpNetworkConnectionChannel::PipeliningProbablySupported;
     
    635716    alreadyPipelinedRequests.clear();
    636717
    637     QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
     718    // only run when the QHttpNetworkConnection is not currently being destructed, e.g.
     719    // this function is called from _q_disconnected which is called because
     720    // of ~QHttpNetworkConnectionPrivate
     721    if (qobject_cast<QHttpNetworkConnection*>(connection))
     722        QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
    638723}
    639724
     
    675760        if (connection->d_func()->handleAuthenticateChallenge(socket, reply, (statusCode == 407), resend)) {
    676761            if (resend) {
    677                 QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
    678                 if (uploadByteDevice) {
    679                     if (uploadByteDevice->reset()) {
    680                         written = 0;
    681                     } else {
    682                         connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ContentReSendError);
    683                         break;
    684                     }
    685                 }
     762                if (!resetUploadData())
     763                    break;
    686764
    687765                reply->d_func()->eraseData();
     
    713791}
    714792
     793
     794
     795
     796
     797
     798
     799
     800
     801
     802
     803
     804
     805
     806
     807
     808
    715809void  QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair)
    716810{
     
    719813    QHttpNetworkRequest &request = pair.first;
    720814    QHttpNetworkReply *reply = pair.second;
    721     if (reply) {
    722         reply->d_func()->clear();
    723         reply->d_func()->connection = connection;
    724         reply->d_func()->autoDecompress = request.d->autoDecompress;
    725         reply->d_func()->pipeliningUsed = true;
    726     }
     815    reply->d_func()->clear();
     816    reply->d_func()->connection = connection;
     817    reply->d_func()->connectionChannel = this;
     818    reply->d_func()->autoDecompress = request.d->autoDecompress;
     819    reply->d_func()->pipeliningUsed = true;
    727820
    728821#ifndef QT_NO_NETWORKPROXY
     
    788881    // read the available data before closing
    789882    if (isSocketWaiting() || isSocketReading()) {
    790         state = QHttpNetworkConnectionChannel::ReadingState;
    791         if (reply)
     883       
     884       
    792885            _q_receiveReply();
     886
    793887    } else if (state == QHttpNetworkConnectionChannel::IdleState && resendCurrent) {
    794888        // re-sending request because the socket was in ClosingState
     
    805899{
    806900    // improve performance since we get the request sent by the kernel ASAP
    807     socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
     901    //socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
     902    // We have this commented out now. It did not have the effect we wanted. If we want to
     903    // do this properly, Qt has to combine multiple HTTP requests into one buffer
     904    // and send this to the kernel in one syscall and then the kernel immediately sends
     905    // it as one TCP packet because of TCP_NODELAY.
     906    // However, this code is currently not in Qt, so we rely on the kernel combining
     907    // the requests into one TCP packet.
     908
    808909    // not sure yet if it helps, but it makes sense
    809910    socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
     
    872973        break;
    873974    }
    874     QPointer<QObject> that = connection;
     975    QPointer<Q> that = connection;
    875976    QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString());
    876977    if (send2Reply) {
     
    9271028    // otherwise we do nothing
    9281029}
    929 #endif
     1030
     1031#endif
     1032
     1033void QHttpNetworkConnectionChannel::setConnection(QHttpNetworkConnection *c)
     1034{
     1035    // Inlining this function in the header leads to compiler error on
     1036    // release-armv5, on at least timebox 9.2 and 10.1.
     1037    connection = c;
     1038}
    9301039
    9311040QT_END_NAMESPACE
  • trunk/src/network/access/qhttpnetworkconnectionchannel_p.h

    r651 r769  
    6666#include <private/qhttpnetworkreply_p.h>
    6767
     68
    6869
    6970#ifndef QT_NO_HTTP
     
    8182class QHttpNetworkReply;
    8283class QByteArray;
    83 class QHttpNetworkConnection;
    8484
    8585#ifndef HttpMessagePair
     
    128128
    129129
    130     QHttpNetworkConnectionChannel() : socket(0), state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false),
    131     lastStatus(0), pendingEncrypt(false), reconnectAttempts(2),
    132     authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None)
    133 #ifndef QT_NO_OPENSSL
    134     , ignoreAllSslErrors(false)
    135 #endif
    136     , pipeliningSupported(PipeliningSupportUnknown)
    137     , connection(0)
    138     {}
    139 
    140     void setConnection(QHttpNetworkConnection *c) {connection = c;}
    141     QHttpNetworkConnection *connection;
     130    QHttpNetworkConnectionChannel();
     131   
     132    void setConnection(QHttpNetworkConnection *c);
     133    QPointer<QHttpNetworkConnection> connection;
    142134
    143135    void init();
     
    152144    void handleStatus(); // called from allDone()
    153145
     146
     147
    154148    void pipelineInto(HttpMessagePair &pair);
    155149    void requeueCurrentlyPipelinedRequests();
    156150    void detectPipeliningSupport();
    157151
     152
    158153    void closeAndResendCurrentRequest();
    159154
     
    185180};
    186181
    187 
    188 
    189182QT_END_NAMESPACE
    190183
  • trunk/src/network/access/qhttpnetworkheader.cpp

    r651 r769  
    8181    QByteArray result;
    8282    bool first = true;
    83     foreach (QByteArray value, allValues) {
     83    foreach (value, allValues) {
    8484        if (!first)
    8585            result += ", ";
  • trunk/src/network/access/qhttpnetworkreply.cpp

    r651 r769  
    180180{
    181181    Q_D(QHttpNetworkReply);
     182
     183
     184
    182185    // we'll take the last buffer, so schedule another read from http
    183186    if (d->downstreamLimited && d->responseData.bufferCount() == 1)
     
    220223}
    221224
    222 void QHttpNetworkReplyPrivate::clear()
     225void QHttpNetworkReplyPrivate::clear()
    223226{
    224227    state = NothingDoneState;
     
    230233    currentChunkRead = 0;
    231234    connectionCloseEnabled = true;
    232     connection = 0;
    233235#ifndef QT_NO_COMPRESS
    234236    if (initInflate)
     
    237239    initInflate = false;
    238240    streamEnd = false;
     241
     242
     243
     244
     245
     246
     247
     248
    239249    autoDecompress = false;
    240     fields.clear();
     250    ();
    241251}
    242252
     
    424434qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket)
    425435{
     436
     437
     438
     439
     440
    426441    qint64 bytes = 0;
    427442    char c;
    428 
    429     while (socket->bytesAvailable()) {
     443    qint64 haveRead = 0;
     444
     445    do {
     446        haveRead = socket->read(&c, 1);
     447        if (haveRead == -1)
     448            return -1; // unexpected EOF
     449        else if (haveRead == 0)
     450            break; // read more later
     451
     452        bytes++;
     453
    430454        // allow both CRLF & LF (only) line endings
    431         if (socket->peek(&c, 1) == 1 && c == '\n') {
    432             bytes += socket->read(&c, 1); // read the "n"
     455        if (c == '\n') {
    433456            // remove the CR at the end
    434457            if (fragment.endsWith('\r')) {
     
    443466            break;
    444467        } else {
    445             c = 0;
    446             int haveRead = socket->read(&c, 1);
    447             if (haveRead == -1)
    448                 return -1;
    449             bytes += haveRead;
    450468            fragment.append(c);
    451469        }
     
    457475            return -1;
    458476        }
    459 
    460     }
     477    } while (haveRead == 1);
    461478
    462479    return bytes;
     
    501518qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket)
    502519{
     520
     521
     522
     523
     524
     525
     526
    503527    qint64 bytes = 0;
    504528    char c = 0;
    505529    bool allHeaders = false;
    506     while (!allHeaders && socket->bytesAvailable()) {
    507         if (socket->peek(&c, 1) == 1 && c == '\n') {
    508             // check for possible header endings. As per HTTP rfc,
    509             // the header endings will be marked by CRLFCRLF. But
    510             // we will allow CRLFLF, LFLF & CRLFCRLF
    511             if (fragment.endsWith("\n\r") || fragment.endsWith('\n'))
    512                 allHeaders = true;
    513         }
    514         bytes += socket->read(&c, 1);
    515         fragment.append(c);
    516     }
     530    qint64 haveRead = 0;
     531    do {
     532        haveRead = socket->read(&c, 1);
     533        if (haveRead == 0) {
     534            // read more later
     535            break;
     536        } else if (haveRead == -1) {
     537            // connection broke down
     538            return -1;
     539        } else {
     540            fragment.append(c);
     541            bytes++;
     542
     543            if (c == '\n') {
     544                // check for possible header endings. As per HTTP rfc,
     545                // the header endings will be marked by CRLFCRLF. But
     546                // we will allow CRLFCRLF, CRLFLF, LFLF
     547                if (fragment.endsWith("\r\n\r\n")
     548                    || fragment.endsWith("\r\n\n")
     549                    || fragment.endsWith("\n\n"))
     550                    allHeaders = true;
     551
     552                // there is another case: We have no headers. Then the fragment equals just the line ending
     553                if ((fragment.length() == 2 && fragment.endsWith("\r\n"))
     554                    || (fragment.length() == 1 && fragment.endsWith("\n")))
     555                    allHeaders = true;
     556            }
     557        }
     558    } while (!allHeaders && haveRead > 0);
     559
    517560    // we received all headers now parse them
    518561    if (allHeaders) {
     
    776819{
    777820    Q_D(const QHttpNetworkReply);
    778     if (d->connection)
    779         return d->connection->d_func()->sslConfiguration(*this);
    780     return QSslConfiguration();
     821
     822    if (!d->connectionChannel)
     823        return QSslConfiguration();
     824
     825    QSslSocket *sslSocket = qobject_cast<QSslSocket*>(d->connectionChannel->socket);
     826    if (!sslSocket)
     827        return QSslConfiguration();
     828
     829    return sslSocket->sslConfiguration();
    781830}
    782831
  • trunk/src/network/access/qhttpnetworkreply_p.h

    r651 r769  
    8787
    8888class QHttpNetworkConnection;
     89
    8990class QHttpNetworkRequest;
    9091class QHttpNetworkConnectionPrivate;
     
    172173    QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const;
    173174    void clear();
     175
    174176
    175177    qint64 readReplyBodyRaw(QIODevice *in, QByteDataBuffer *out, qint64 size);
     
    219221    qint64 currentChunkRead;
    220222    QPointer<QHttpNetworkConnection> connection;
     223
    221224    bool initInflate;
    222225    bool streamEnd;
  • trunk/src/network/access/qnetworkaccessbackend.cpp

    r651 r769  
    7373{
    7474    QMutexLocker locker(&factoryData()->mutex);
    75     factoryData()->prepend(this);
     75    factoryData()->pend(this);
    7676}
    7777
  • trunk/src/network/access/qnetworkaccesshttpbackend.cpp

    r651 r769  
    681681
    682682    while (httpReply->bytesAvailable() != 0 && nextDownstreamBlockSize() != 0 && nextDownstreamBlockSize() > list.byteAmount()) {
    683         QByteArray data = httpReply->readAny();
    684         list.append(data);
     683        list.append(httpReply->readAny());
    685684    }
    686685
     
    754753        if (!value.isEmpty()) {
    755754            if (qstricmp(it->first.constData(), "set-cookie") == 0)
    756                 value += "\n";
     755                value += ;
    757756            else
    758757                value += ", ";
     
    977976        // write to disk when only the date changes).
    978977        // However, without the date we cannot calculate the age of the page
    979         // anymore. Consider a proper fix of that problem for 4.6.1.
     978        // anymore.
    980979        //if (header == "date")
    981980            //continue;
  • trunk/src/network/access/qnetworkaccesshttpbackend_p.h

    r651 r769  
    9595    QNetworkCacheMetaData fetchCacheMetaData(const QNetworkCacheMetaData &metaData) const;
    9696
    97     qint64 deviceReadData(char *buffer, qint64 maxlen);
    98 
    9997    // we return true since HTTP needs to send PUT/POST data again after having authenticated
    10098    bool needsResetableUploadData() { return true; }
  • trunk/src/network/access/qnetworkaccessmanager.cpp

    r651 r769  
    108108    it sends. It contains the proxy and cache configuration, as well as the
    109109    signals related to such issues, and reply signals that can be used to
    110     monitor the progress of a network operation.
     110    monitor the progress of a network operation. One QNetworkAccessManager
     111    should be enough for the whole Qt application.
    111112
    112113    Once a QNetworkAccessManager object has been created, the application can
     
    119120    \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 0
    120121
     122
    121123    When the \tt replyFinished slot above is called, the parameter it
    122124    takes is the QNetworkReply object containing the downloaded data
     
    128130    deleteLater() function.
    129131
     132
     133
     134
     135
     136
    130137    A more involved example, assuming the manager is already existent,
    131138    can be:
    132139    \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 1
     140
     141
     142
     143
     144
     145
     146
     147
     148
     149
    133150
    134151    \sa QNetworkRequest, QNetworkReply, QNetworkProxy
     
    550567/*!
    551568    Posts a request to obtain the network headers for \a request
    552     and returns a new QNetworkReply object which will contain such headers
     569    and returns a new QNetworkReply object which will contain such headers
    553570
    554571    The function is named after the HTTP request associated (HEAD).
  • trunk/src/network/access/qnetworkcookie.h

    r651 r769  
    115115
    116116// ### Qt5 remove this include
    117 #include "qnetworkcookiejar.h"
     117#include
    118118
    119119Q_DECLARE_METATYPE(QNetworkCookie)
  • trunk/src/network/access/qnetworkcookiejar.h

    r651 r769  
    4747
    4848// ### Qt5 remove this include
    49 #include "qnetworkcookie.h"
     49#include
    5050
    5151QT_BEGIN_HEADER
  • trunk/src/network/access/qnetworkdiskcache.cpp

    r651 r769  
    4242//#define QNETWORKDISKCACHE_DEBUG
    4343
    44 #ifndef QT_NO_NETWORKDISKCACHE
    4544
    4645#include "qnetworkdiskcache.h"
     
    6059#define CACHE_POSTFIX QLatin1String(".cache")
    6160#define MAX_COMPRESSION_SIZE (1024 * 1024 * 3)
     61
     62
    6263
    6364QT_BEGIN_NAMESPACE
  • trunk/src/network/access/qnetworkdiskcache_p.h

    r651 r769  
    6060#include <qtemporaryfile.h>
    6161
     62
     63
    6264QT_BEGIN_NAMESPACE
    6365
     
    120122QT_END_NAMESPACE
    121123
     124
     125
    122126#endif // QNETWORKDISKCACHE_P_H
  • trunk/src/network/access/qnetworkreplyimpl.cpp

    r651 r769  
    404404}
    405405
     406
     407
     408
     409
     410
     411
     412
     413
     414
     415
     416
     417
     418
     419
     420
     421
     422
     423
     424
     425
     426
     427
     428
     429
     430
     431
     432
     433
     434
     435
     436
    406437// we received downstream data and send this to the cache
    407438// and to our readBuffer (which in turn gets read by the user of QNetworkReply)
     
    413444
    414445    if (cacheEnabled && !cacheSaveDevice) {
    415         // save the meta data
    416         QNetworkCacheMetaData metaData;
    417         metaData.setUrl(url);
    418         metaData = backend->fetchCacheMetaData(metaData);
    419 
    420         // save the redirect request also in the cache
    421         QVariant redirectionTarget = q->attribute(QNetworkRequest::RedirectionTargetAttribute);
    422         if (redirectionTarget.isValid()) {
    423             QNetworkCacheMetaData::AttributesMap attributes = metaData.attributes();
    424             attributes.insert(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget);
    425             metaData.setAttributes(attributes);
    426         }
    427 
    428         cacheSaveDevice = networkCache()->prepare(metaData);
    429 
    430         if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) {
    431             if (cacheSaveDevice && !cacheSaveDevice->isOpen())
    432                 qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- "
    433                       "class %s probably needs to be fixed",
    434                       networkCache()->metaObject()->className());
    435 
    436             networkCache()->remove(url);
    437             cacheSaveDevice = 0;
    438             cacheEnabled = false;
    439         }
     446        initCacheSaveDevice();
    440447    }
    441448
    442449    qint64 bytesWritten = 0;
    443450    for (int i = 0; i < data.bufferCount(); i++) {
    444         QByteArray item = data[i];
     451        QByteArray item = data[i];
    445452
    446453        if (cacheSaveDevice)
     
    454461    bytesDownloaded += bytesWritten;
    455462    lastBytesDownloaded = bytesDownloaded;
     463
     464
     465
     466
     467
     468
     469
    456470
    457471    QPointer<QNetworkReplyImpl> qq = q;
     
    496510}
    497511
     512
     513
     514
     515
     516
     517
     518
     519
     520
    498521void QNetworkReplyImplPrivate::finished()
    499522{
     
    581604{
    582605    Q_D(QNetworkReplyImpl);
     606
     607
     608
     609
    583610    if (d->isCachingEnabled())
    584611        d->networkCache()->remove(url());
     612
    585613    if (d->outgoingDataBuffer)
    586614        delete d->outgoingDataBuffer;
  • trunk/src/network/access/qnetworkreplyimpl_p.h

    r651 r769  
    146146    void emitUploadProgress(qint64 bytesSent, qint64 bytesTotal);
    147147    qint64 nextDownstreamBlockSize() const;
     148
     149
     150
    148151    void appendDownstreamData(QByteDataBuffer &data);
    149152    void appendDownstreamData(QIODevice *data);
     153
     154
    150155    void finished();
    151156    void error(QNetworkReply::NetworkError code, const QString &errorString);
  • trunk/src/network/access/qnetworkrequest.cpp

    r651 r769  
    139139        determine if the requested redirection should be allowed,
    140140        according to its security policies.
     141
     142
    141143
    142144    \value ConnectionEncryptedAttribute
     
    650652    QList<QNetworkCookie> result;
    651653    QList<QByteArray> cookieList = raw.split(';');
    652     foreach (QByteArray cookie, cookieList) {
     654    foreach (cookie, cookieList) {
    653655        QList<QNetworkCookie> parsed = QNetworkCookie::parseCookies(cookie.trimmed());
    654656        if (parsed.count() != 1)
Note: See TracChangeset for help on using the changeset viewer.