void QmlRemoteImage::setUrl(QUrl url) { if (m_url != url) { m_url = url; m_loading = 0; abortRequest(); if (url.isEmpty()) { resetImageSource(); } else { QNetworkRequest request = QNetworkRequest(url); request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); m_reply = Helper::networkManager()->get(request); if (m_reply->error() == QNetworkReply::NoError) { connect(m_reply, SIGNAL(finished()), this, SLOT(downloadFinished())); connect(m_reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgressChanged(qint64,qint64))); } else { m_reply->deleteLater(); m_reply = 0; } } emit urlChanged(); } }
/*! \qmlmethod QtLocation::RouteModel::cancel() Cancels any outstanding requests and clears errors. Model status will be set to either RouteModel.Null or RouteModel.Ready. */ void QDeclarativeGeoRouteModel::cancel() { abortRequest(); setErrorString(QString()); setError(NoError); setStatus(routes_.isEmpty() ? Null : Ready); }
void HttpConnection::on(BufferedSocketListener::ModeChange) noexcept { if(connState != CONN_CHUNKED) { abortRequest(true); fire(HttpConnectionListener::Complete(), this); } }
void XMLHttpRequestClass::requestTimeout() { if (_onTimeout.isFunction()) { _onTimeout.call(QScriptValue::NullValue); } abortRequest(); _errorCode = QNetworkReply::TimeoutError; setReadyState(DONE); emit requestComplete(); }
void XMLHttpRequestClass::requestMetaDataChanged() { QVariant redirect = _reply->attribute(QNetworkRequest::RedirectionTargetAttribute); // If this is a redirect, abort the current request and start a new one if (redirect.isValid() && _numRedirects < MAXIMUM_REDIRECTS) { _numRedirects++; abortRequest(); QUrl newUrl = _url.resolved(redirect.toUrl().toString()); _request.setUrl(newUrl); doSend(); } }
void HttpConnection::on(BufferedSocketListener::Data, uint8_t* aBuf, size_t aLen) noexcept { if(size != -1 && static_cast<size_t>(size - done) < aLen) { abortRequest(true); connState = CONN_FAILED; fire(HttpConnectionListener::Failed(), this, str(F_("Too much data in response body (%1%)") % url)); return; } done += aLen; updateSpeed(); fire(HttpConnectionListener::Data(), this, aBuf, aLen); }
void QDeclarativeGeoRouteModel::reset() { if (!routes_.isEmpty()) { beginResetModel(); qDeleteAll(routes_); routes_.clear(); emit countChanged(); emit routesChanged(); endResetModel(); } abortRequest(); setError(NoError, QString()); setStatus(QDeclarativeGeoRouteModel::Null); }
// This is invoked as BlockingQueuedConnection from QNetworkAccessHttpBackend in the user thread void QHttpThreadDelegate::startRequestSynchronously() { #ifdef QHTTPTHREADDELEGATE_DEBUG qDebug() << "QHttpThreadDelegate::startRequestSynchronously() thread=" << QThread::currentThreadId(); #endif synchronous = true; QEventLoop synchronousRequestLoop; this->synchronousRequestLoop = &synchronousRequestLoop; // Worst case timeout QTimer::singleShot(30*1000, this, SLOT(abortRequest())); QMetaObject::invokeMethod(this, "startRequest", Qt::QueuedConnection); synchronousRequestLoop.exec(); connections.localData()->releaseEntry(cacheKey); connections.setLocalData(0); #ifdef QHTTPTHREADDELEGATE_DEBUG qDebug() << "QHttpThreadDelegate::startRequestSynchronously() thread=" << QThread::currentThreadId() << "finished"; #endif }
void XMLHttpRequestClass::abort() { abortRequest(); }
void HttpConnection::abort() { if(socket) { abortRequest(true); } }
void HttpConnection::on(BufferedSocketListener::Failed, const string& aLine) noexcept { abortRequest(false); connState = CONN_FAILED; fire(HttpConnectionListener::Failed(), this, str(F_("%1% (%2%)") % boost::trim_copy(aLine) % url)); }
void HttpConnection::on(BufferedSocketListener::Line, const string& aLine) noexcept { if(connState == CONN_CHUNKED && aLine.size() > 1) { string::size_type i; string chunkSizeStr; if((i = aLine.find(";")) == string::npos) { chunkSizeStr = aLine.substr(0, aLine.length() - 1); } else chunkSizeStr = aLine.substr(0, i); unsigned long chunkSize = strtoul(chunkSizeStr.c_str(), NULL, 16); if(chunkSize == 0 || chunkSize == ULONG_MAX) { abortRequest(true); if(chunkSize == 0) { connState = CONN_OK; fire(HttpConnectionListener::Complete(), this); } else { connState = CONN_FAILED; fire(HttpConnectionListener::Failed(), this, str(F_("Transfer-encoding error (%1%)") % url)); } } else socket->setDataMode(chunkSize); } else if(connState == CONN_UNKNOWN) { if(aLine.find("200") != string::npos) { connState = CONN_OK; } else if(aLine.find("301") != string::npos || aLine.find("302") != string::npos) { connState = CONN_MOVED; } else { abortRequest(true); connState = CONN_FAILED; fire(HttpConnectionListener::Failed(), this, str(F_("%1% (%2%)") % boost::trim_copy(aLine) % url)); } } else if(connState == CONN_MOVED && Util::findSubString(aLine, "Location") != string::npos) { abortRequest(true); string location = aLine.substr(10, aLine.length() - 10); Util::sanitizeUrl(location); // make sure we can also handle redirects with relative paths if(location.find("://") == string::npos) { if(location[0] == '/') { string proto, query, fragment; Util::decodeUrl(url, proto, server, port, file, query, fragment); string tmp = proto + "://" + server; if(port != "80" || port != "443") tmp += ':' + port; location = tmp + location; } else { auto i = url.rfind('/'); dcassert(i != string::npos); location = url.substr(0, i + 1) + location; } } if(location == url) { connState = CONN_FAILED; fire(HttpConnectionListener::Failed(), this, str(F_("Endless redirection loop (%1%)") % url)); return; } fire(HttpConnectionListener::Redirected(), this, location); url = location; download(); } else if(aLine[0] == 0x0d) { if(size != -1) { socket->setDataMode(size); } else connState = CONN_CHUNKED; } else if(Util::findSubString(aLine, "Content-Length") != string::npos) { size = Util::toInt(aLine.substr(16, aLine.length() - 17)); } else if(mimeType.empty()) { if(Util::findSubString(aLine, "Content-Encoding") != string::npos) { if(aLine.substr(18, aLine.length() - 19) == "x-bzip2") mimeType = "application/x-bzip2"; } else if(Util::findSubString(aLine, "Content-Type") != string::npos) { mimeType = aLine.substr(14, aLine.length() - 15); } } }
QmlRemoteImage::~QmlRemoteImage() { abortRequest(); }
void QNetworkAccessHttpBackend::postRequest() { QThread *thread = 0; if (isSynchronous()) { // A synchronous HTTP request uses its own thread thread = new QThread(); QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start(); } else if (!manager->httpThread) { // We use the manager-global thread. // At some point we could switch to having multiple threads if it makes sense. manager->httpThread = new QThread(); QObject::connect(manager->httpThread, SIGNAL(finished()), manager->httpThread, SLOT(deleteLater())); manager->httpThread->start(); #ifndef QT_NO_NETWORKPROXY qRegisterMetaType<QNetworkProxy>("QNetworkProxy"); #endif #ifndef QT_NO_OPENSSL qRegisterMetaType<QList<QSslError> >("QList<QSslError>"); qRegisterMetaType<QSslConfiguration>("QSslConfiguration"); #endif qRegisterMetaType<QList<QPair<QByteArray,QByteArray> > >("QList<QPair<QByteArray,QByteArray> >"); qRegisterMetaType<QHttpNetworkRequest>("QHttpNetworkRequest"); qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError"); qRegisterMetaType<QSharedPointer<char> >("QSharedPointer<char>"); thread = manager->httpThread; } else { // Asynchronous request, thread already exists thread = manager->httpThread; } QUrl url = request().url(); httpRequest.setUrl(url); bool ssl = url.scheme().toLower() == QLatin1String("https"); setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, ssl); httpRequest.setSsl(ssl); #ifndef QT_NO_NETWORKPROXY QNetworkProxy transparentProxy, cacheProxy; foreach (const QNetworkProxy &p, proxyList()) { // use the first proxy that works // for non-encrypted connections, any transparent or HTTP proxy // for encrypted, only transparent proxies if (!ssl && (p.capabilities() & QNetworkProxy::CachingCapability) && (p.type() == QNetworkProxy::HttpProxy || p.type() == QNetworkProxy::HttpCachingProxy)) { cacheProxy = p; transparentProxy = QNetworkProxy::NoProxy; break; } if (p.isTransparentProxy()) { transparentProxy = p; cacheProxy = QNetworkProxy::NoProxy; break; } } // check if at least one of the proxies if (transparentProxy.type() == QNetworkProxy::DefaultProxy && cacheProxy.type() == QNetworkProxy::DefaultProxy) { // unsuitable proxies QMetaObject::invokeMethod(this, "error", isSynchronous() ? Qt::DirectConnection : Qt::QueuedConnection, Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError), Q_ARG(QString, tr("No suitable proxy found"))); QMetaObject::invokeMethod(this, "finished", isSynchronous() ? Qt::DirectConnection : Qt::QueuedConnection); return; } #endif bool loadedFromCache = false; httpRequest.setPriority(convert(request().priority())); switch (operation()) { case QNetworkAccessManager::GetOperation: httpRequest.setOperation(QHttpNetworkRequest::Get); loadedFromCache = loadFromCacheIfAllowed(httpRequest); break; case QNetworkAccessManager::HeadOperation: httpRequest.setOperation(QHttpNetworkRequest::Head); loadedFromCache = loadFromCacheIfAllowed(httpRequest); break; case QNetworkAccessManager::PostOperation: invalidateCache(); httpRequest.setOperation(QHttpNetworkRequest::Post); createUploadByteDevice(); break; case QNetworkAccessManager::PutOperation: invalidateCache(); httpRequest.setOperation(QHttpNetworkRequest::Put); createUploadByteDevice(); break; case QNetworkAccessManager::DeleteOperation: invalidateCache(); httpRequest.setOperation(QHttpNetworkRequest::Delete); break; case QNetworkAccessManager::CustomOperation: invalidateCache(); // for safety reasons, we don't know what the operation does httpRequest.setOperation(QHttpNetworkRequest::Custom); createUploadByteDevice(); httpRequest.setCustomVerb(request().attribute( QNetworkRequest::CustomVerbAttribute).toByteArray()); break; default: break; // can't happen } if (loadedFromCache) { // commented this out since it will be called later anyway // by copyFinished() //QNetworkAccessBackend::finished(); return; // no need to send the request! :) } QList<QByteArray> headers = request().rawHeaderList(); if (resumeOffset != 0) { if (headers.contains("Range")) { // Need to adjust resume offset for user specified range headers.removeOne("Range"); // We've already verified that requestRange starts with "bytes=", see canResume. QByteArray requestRange = request().rawHeader("Range").mid(6); int index = requestRange.indexOf('-'); quint64 requestStartOffset = requestRange.left(index).toULongLong(); quint64 requestEndOffset = requestRange.mid(index + 1).toULongLong(); requestRange = "bytes=" + QByteArray::number(resumeOffset + requestStartOffset) + '-' + QByteArray::number(requestEndOffset); httpRequest.setHeaderField("Range", requestRange); } else { httpRequest.setHeaderField("Range", "bytes=" + QByteArray::number(resumeOffset) + '-'); } } foreach (const QByteArray &header, headers) httpRequest.setHeaderField(header, request().rawHeader(header)); if (request().attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool() == true) httpRequest.setPipeliningAllowed(true); if (static_cast<QNetworkRequest::LoadControl> (request().attribute(QNetworkRequest::AuthenticationReuseAttribute, QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Manual) httpRequest.setWithCredentials(false); // Create the HTTP thread delegate QHttpThreadDelegate *delegate = new QHttpThreadDelegate; #ifndef QT_NO_BEARERMANAGEMENT QVariant v(property("_q_networksession")); if (v.isValid()) delegate->networkSession = qvariant_cast<QSharedPointer<QNetworkSession> >(v); #endif // For the synchronous HTTP, this is the normal way the delegate gets deleted // For the asynchronous HTTP this is a safety measure, the delegate deletes itself when HTTP is finished connect(thread, SIGNAL(finished()), delegate, SLOT(deleteLater())); // Set the properties it needs delegate->httpRequest = httpRequest; #ifndef QT_NO_NETWORKPROXY delegate->cacheProxy = cacheProxy; delegate->transparentProxy = transparentProxy; #endif delegate->ssl = ssl; #ifndef QT_NO_OPENSSL if (ssl) delegate->incomingSslConfiguration = request().sslConfiguration(); #endif // Do we use synchronous HTTP? delegate->synchronous = isSynchronous(); // The authentication manager is used to avoid the BlockingQueuedConnection communication // from HTTP thread to user thread in some cases. delegate->authenticationManager = manager->authenticationManager; if (!isSynchronous()) { // Tell our zerocopy policy to the delegate delegate->downloadBufferMaximumSize = request().attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute).toLongLong(); // These atomic integers are used for signal compression delegate->pendingDownloadData = pendingDownloadDataEmissions; delegate->pendingDownloadProgress = pendingDownloadProgressEmissions; // Connect the signals of the delegate to us connect(delegate, SIGNAL(downloadData(QByteArray)), this, SLOT(replyDownloadData(QByteArray)), Qt::QueuedConnection); connect(delegate, SIGNAL(downloadFinished()), this, SLOT(replyFinished()), Qt::QueuedConnection); connect(delegate, SIGNAL(downloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64)), this, SLOT(replyDownloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64)), Qt::QueuedConnection); connect(delegate, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(replyDownloadProgressSlot(qint64,qint64)), Qt::QueuedConnection); connect(delegate, SIGNAL(error(QNetworkReply::NetworkError,QString)), this, SLOT(httpError(QNetworkReply::NetworkError, const QString)), Qt::QueuedConnection); #ifndef QT_NO_OPENSSL connect(delegate, SIGNAL(sslConfigurationChanged(QSslConfiguration)), this, SLOT(replySslConfigurationChanged(QSslConfiguration)), Qt::QueuedConnection); #endif // Those need to report back, therefire BlockingQueuedConnection connect(delegate, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)), this, SLOT(httpAuthenticationRequired(QHttpNetworkRequest,QAuthenticator*)), Qt::BlockingQueuedConnection); #ifndef QT_NO_NETWORKPROXY connect (delegate, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), Qt::BlockingQueuedConnection); #endif #ifndef QT_NO_OPENSSL connect(delegate, SIGNAL(sslErrors(QList<QSslError>,bool*,QList<QSslError>*)), this, SLOT(replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *)), Qt::BlockingQueuedConnection); #endif // This signal we will use to start the request. connect(this, SIGNAL(startHttpRequest()), delegate, SLOT(startRequest())); connect(this, SIGNAL(abortHttpRequest()), delegate, SLOT(abortRequest())); // To throttle the connection. QObject::connect(this, SIGNAL(readBufferSizeChanged(qint64)), delegate, SLOT(readBufferSizeChanged(qint64))); QObject::connect(this, SIGNAL(readBufferFreed(qint64)), delegate, SLOT(readBufferFreed(qint64))); if (uploadByteDevice) { QNonContiguousByteDeviceThreadForwardImpl *forwardUploadDevice = new QNonContiguousByteDeviceThreadForwardImpl(uploadByteDevice->atEnd(), uploadByteDevice->size()); if (uploadByteDevice->isResetDisabled()) forwardUploadDevice->disableReset(); forwardUploadDevice->setParent(delegate); // needed to make sure it is moved on moveToThread() delegate->httpRequest.setUploadByteDevice(forwardUploadDevice); // From main thread to user thread: QObject::connect(this, SIGNAL(haveUploadData(QByteArray, bool, qint64)), forwardUploadDevice, SLOT(haveDataSlot(QByteArray, bool, qint64)), Qt::QueuedConnection); QObject::connect(uploadByteDevice.data(), SIGNAL(readyRead()), forwardUploadDevice, SIGNAL(readyRead()), Qt::QueuedConnection); // From http thread to user thread: QObject::connect(forwardUploadDevice, SIGNAL(wantData(qint64)), this, SLOT(wantUploadDataSlot(qint64))); QObject::connect(forwardUploadDevice, SIGNAL(processedData(qint64)), this, SLOT(sentUploadDataSlot(qint64))); connect(forwardUploadDevice, SIGNAL(resetData(bool*)), this, SLOT(resetUploadDataSlot(bool*)), Qt::BlockingQueuedConnection); // this is the only one with BlockingQueued! } } else if (isSynchronous()) {