/*! Returns a new QNetworkReply object to handle the operation \a op and request \a req. The device \a outgoingData is always 0 for Get and Head requests, but is the value passed to post() and put() in those operations (the QByteArray variants will pass a QBuffer object). The default implementation calls QNetworkCookieJar::cookiesForUrl() on the cookie jar set with setCookieJar() to obtain the cookies to be sent to the remote server. The returned object must be in an open state. */ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData) { Q_D(QNetworkAccessManager); bool isLocalFile = req.url().isLocalFile(); QString scheme = req.url().scheme().toLower(); // fast path for GET on file:// URLs // The QNetworkAccessFileBackend will right now only be used for PUT if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) && (isLocalFile || scheme == QLatin1String("qrc"))) { return new QNetworkReplyFileImpl(this, req, op); } if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) && scheme == QLatin1String("data")) { return new QNetworkReplyDataImpl(this, req, op); } // A request with QNetworkRequest::AlwaysCache does not need any bearer management QNetworkRequest::CacheLoadControl mode = static_cast<QNetworkRequest::CacheLoadControl>( req.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt()); if (mode == QNetworkRequest::AlwaysCache && (op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation)) { // FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106 QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); QNetworkReplyImplPrivate *priv = reply->d_func(); priv->manager = this; priv->backend = new QNetworkAccessCacheBackend(); priv->backend->manager = this->d_func(); priv->backend->setParent(reply); priv->backend->reply = priv; priv->setup(op, req, outgoingData); return reply; } #ifndef QT_NO_BEARERMANAGEMENT // Return a disabled network reply if network access is disabled. // Except if the scheme is empty or file://. if (!d->networkAccessible && !isLocalFile) { return new QDisabledNetworkReply(this, req, op); } if (!d->networkSession && (d->initializeSession || !d->networkConfiguration.isEmpty())) { QNetworkConfigurationManager manager; if (!d->networkConfiguration.isEmpty()) { d->createSession(manager.configurationFromIdentifier(d->networkConfiguration)); } else { if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) d->createSession(manager.defaultConfiguration()); else d->initializeSession = false; } } if (d->networkSession) d->networkSession->setSessionProperty(QLatin1String("AutoCloseSessionTimeout"), -1); #endif QNetworkRequest request = req; if (!request.header(QNetworkRequest::ContentLengthHeader).isValid() && outgoingData && !outgoingData->isSequential()) { // request has no Content-Length // but the data that is outgoing is random-access request.setHeader(QNetworkRequest::ContentLengthHeader, outgoingData->size()); } if (static_cast<QNetworkRequest::LoadControl> (request.attribute(QNetworkRequest::CookieLoadControlAttribute, QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Automatic) { if (d->cookieJar) { QList<QNetworkCookie> cookies = d->cookieJar->cookiesForUrl(request.url()); if (!cookies.isEmpty()) request.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(cookies)); } } // first step: create the reply QUrl url = request.url(); QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); #ifndef QT_NO_BEARERMANAGEMENT if (!isLocalFile) { connect(this, SIGNAL(networkSessionConnected()), reply, SLOT(_q_networkSessionConnected())); } #endif QNetworkReplyImplPrivate *priv = reply->d_func(); priv->manager = this; // second step: fetch cached credentials // This is not done for the time being, we should use signal emissions to request // the credentials from cache. // third step: find a backend priv->backend = d->findBackend(op, request); if (priv->backend) { priv->backend->setParent(reply); priv->backend->reply = priv; } #ifndef QT_NO_OPENSSL reply->setSslConfiguration(request.sslConfiguration()); #endif // fourth step: setup the reply priv->setup(op, request, outgoingData); return reply; }
/*! Returns a new QNetworkReply object to handle the operation \a op and request \a req. The device \a outgoingData is always 0 for Get and Head requests, but is the value passed to post() and put() in those operations (the QByteArray variants will pass a QBuffer object). The default implementation calls QNetworkCookieJar::cookiesForUrl() on the cookie jar set with setCookieJar() to obtain the cookies to be sent to the remote server. The returned object must be in an open state. */ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData) { Q_D(QNetworkAccessManager); // fast path for GET on file:// URLs // Also if the scheme is empty we consider it a file. // The QNetworkAccessFileBackend will right now only be used // for PUT or qrc:// if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) && (req.url().scheme() == QLatin1String("file") || req.url().scheme().isEmpty())) { return new QFileNetworkReply(this, req, op); } #ifndef QT_NO_BEARERMANAGEMENT // Return a disabled network reply if network access is disabled. // Except if the scheme is empty or file://. if (!d->networkAccessible && !(req.url().scheme() == QLatin1String("file") || req.url().scheme().isEmpty())) { return new QDisabledNetworkReply(this, req, op); } if (!d->networkSession && (d->initializeSession || !d->networkConfiguration.isEmpty())) { QNetworkConfigurationManager manager; if (!d->networkConfiguration.isEmpty()) { d->createSession(manager.configurationFromIdentifier(d->networkConfiguration)); } else { if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) d->createSession(manager.defaultConfiguration()); else d->initializeSession = false; } } if (d->networkSession) d->networkSession->setSessionProperty(QLatin1String("AutoCloseSessionTimeout"), -1); #endif QNetworkRequest request = req; if (!request.header(QNetworkRequest::ContentLengthHeader).isValid() && outgoingData && !outgoingData->isSequential()) { // request has no Content-Length // but the data that is outgoing is random-access request.setHeader(QNetworkRequest::ContentLengthHeader, outgoingData->size()); } if (d->cookieJar) { QList<QNetworkCookie> cookies = d->cookieJar->cookiesForUrl(request.url()); if (!cookies.isEmpty()) request.setHeader(QNetworkRequest::CookieHeader, qVariantFromValue(cookies)); } // first step: create the reply QUrl url = request.url(); QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); #ifndef QT_NO_BEARERMANAGEMENT if (req.url().scheme() != QLatin1String("file") && !req.url().scheme().isEmpty()) { connect(this, SIGNAL(networkSessionConnected()), reply, SLOT(_q_networkSessionConnected())); } #endif QNetworkReplyImplPrivate *priv = reply->d_func(); priv->manager = this; // second step: fetch cached credentials QNetworkAuthenticationCredential *cred = d->fetchCachedCredentials(url); if (cred) { url.setUserName(cred->user); url.setPassword(cred->password); priv->urlForLastAuthentication = url; } // third step: find a backend priv->backend = d->findBackend(op, request); #ifndef QT_NO_NETWORKPROXY QList<QNetworkProxy> proxyList = d->queryProxy(QNetworkProxyQuery(request.url())); priv->proxyList = proxyList; #endif if (priv->backend) { priv->backend->setParent(reply); priv->backend->reply = priv; } // fourth step: setup the reply priv->setup(op, request, outgoingData); #ifndef QT_NO_OPENSSL reply->setSslConfiguration(request.sslConfiguration()); #endif return reply; }