QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetworkRequest &request) { Q_Q(QHttpNetworkConnection); // The reply component of the pair is created initially. QHttpNetworkReply *reply = new QHttpNetworkReply(request.url()); reply->setRequest(request); reply->d_func()->connection = q; reply->d_func()->connectionChannel = &channels[0]; // will have the correct one set later HttpMessagePair pair = qMakePair(request, reply); switch (request.priority()) { case QHttpNetworkRequest::HighPriority: highPriorityQueue.prepend(pair); break; case QHttpNetworkRequest::NormalPriority: case QHttpNetworkRequest::LowPriority: lowPriorityQueue.prepend(pair); break; } // this used to be called via invokeMethod and a QueuedConnection // It is the only place _q_startNextRequest is called directly without going // through the event loop using a QueuedConnection. // This is dangerous because of recursion that might occur when emitting // signals as DirectConnection from this code path. Therefore all signal // emissions that can come out from this code path need to // be QueuedConnection. // We are currently trying to fine-tune this. _q_startNextRequest(); return reply; }
void QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair) { // this is only called for simple GET QHttpNetworkRequest &request = pair.first; QHttpNetworkReply *reply = pair.second; reply->d_func()->clear(); reply->d_func()->connection = connection; reply->d_func()->connectionChannel = this; reply->d_func()->autoDecompress = request.d->autoDecompress; reply->d_func()->pipeliningUsed = true; #ifndef QT_NO_NETWORKPROXY QByteArray header = QHttpNetworkRequestPrivate::header(request, (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy)); #else QByteArray header = QHttpNetworkRequestPrivate::header(request, false); #endif socket->write(header); alreadyPipelinedRequests.append(pair); }
void QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair) { // this is only called for simple GET QHttpNetworkRequest &request = pair.first; QHttpNetworkReply *reply = pair.second; reply->d_func()->clear(); reply->d_func()->connection = connection; reply->d_func()->connectionChannel = this; reply->d_func()->autoDecompress = request.d->autoDecompress; reply->d_func()->pipeliningUsed = true; #ifndef QT_NO_NETWORKPROXY pipeline.append(QHttpNetworkRequestPrivate::header(request, (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy))); #else pipeline.append(QHttpNetworkRequestPrivate::header(request, false)); #endif alreadyPipelinedRequests.append(pair); // pipelineFlush() needs to be called at some point afterwards }
void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair) { QHttpNetworkRequest &request = messagePair.first; QHttpNetworkReply *reply = messagePair.second; // add missing fields for the request QByteArray value; // check if Content-Length is provided QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice(); if (uploadByteDevice) { if (request.contentLength() != -1 && uploadByteDevice->size() != -1) { // both values known, take the smaller one. request.setContentLength(qMin(uploadByteDevice->size(), request.contentLength())); } else if (request.contentLength() == -1 && uploadByteDevice->size() != -1) { // content length not supplied by user, but the upload device knows it request.setContentLength(uploadByteDevice->size()); } else if (request.contentLength() != -1 && uploadByteDevice->size() == -1) { // everything OK, the user supplied us the contentLength } else if (request.contentLength() == -1 && uploadByteDevice->size() == -1) { qFatal("QHttpNetworkConnectionPrivate: Neither content-length nor upload device size were given"); } } // set the Connection/Proxy-Connection: Keep-Alive headers #ifndef QT_NO_NETWORKPROXY if (networkProxy.type() == QNetworkProxy::HttpCachingProxy) { value = request.headerField("proxy-connection"); if (value.isEmpty()) request.setHeaderField("Proxy-Connection", "Keep-Alive"); } else { #endif value = request.headerField("connection"); if (value.isEmpty()) request.setHeaderField("Connection", "Keep-Alive"); #ifndef QT_NO_NETWORKPROXY } #endif // If the request had a accept-encoding set, we better not mess // with it. If it was not set, we announce that we understand gzip // and remember this fact in request.d->autoDecompress so that // we can later decompress the HTTP reply if it has such an // encoding. value = request.headerField("accept-encoding"); if (value.isEmpty()) { #ifndef QT_NO_COMPRESS request.setHeaderField("Accept-Encoding", "gzip"); request.d->autoDecompress = true; #else // if zlib is not available set this to false always request.d->autoDecompress = false; #endif } // some websites mandate an accept-language header and fail // if it is not sent. This is a problem with the website and // not with us, but we work around this by setting // one always. value = request.headerField("accept-language"); if (value.isEmpty()) { QString systemLocale = QLocale::system().name().replace(QChar::fromAscii('_'),QChar::fromAscii('-')); QString acceptLanguage; if (systemLocale == QLatin1String("C")) acceptLanguage = QString::fromAscii("en,*"); else if (systemLocale.startsWith(QLatin1String("en-"))) acceptLanguage = QString::fromAscii("%1,*").arg(systemLocale); else acceptLanguage = QString::fromAscii("%1,en,*").arg(systemLocale); request.setHeaderField("Accept-Language", acceptLanguage.toAscii()); } // set the User Agent value = request.headerField("user-agent"); if (value.isEmpty()) request.setHeaderField("User-Agent", "Mozilla/5.0"); // set the host value = request.headerField("host"); if (value.isEmpty()) { QHostAddress add; QByteArray host; if(add.setAddress(hostName)) { if(add.protocol() == QAbstractSocket::IPv6Protocol) { host = "[" + hostName.toAscii() + "]";//format the ipv6 in the standard way } else { host = QUrl::toAce(hostName); } } else { host = QUrl::toAce(hostName); } int port = request.url().port(); if (port != -1) { host += ':'; host += QByteArray::number(port); } request.setHeaderField("Host", host); } reply->d_func()->requestIsPrepared = true; }
qint64 QHttpNetworkConnectionPrivate::uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const { return reply.d_func()->responseData.sizeNextBlock(); }
qint64 QHttpNetworkConnectionPrivate::uncompressedBytesAvailable(const QHttpNetworkReply &reply) const { return reply.d_func()->responseData.byteAmount(); }