QByteArray QgsSvgCache::getImageData( const QString &path ) const { // is it a path to local file? QFile svgFile( path ); if ( svgFile.exists() ) { if ( svgFile.open( QIODevice::ReadOnly ) ) { return svgFile.readAll(); } else { return mMissingSvg; } } // maybe it's a url... if ( !path.contains( "://" ) ) // otherwise short, relative SVG paths might be considered URLs { return mMissingSvg; } QUrl svgUrl( path ); if ( !svgUrl.isValid() ) { return mMissingSvg; } // check whether it's a url pointing to a local file if ( svgUrl.scheme().compare( "file", Qt::CaseInsensitive ) == 0 ) { svgFile.setFileName( svgUrl.toLocalFile() ); if ( svgFile.exists() ) { if ( svgFile.open( QIODevice::ReadOnly ) ) { return svgFile.readAll(); } } // not found... return mMissingSvg; } // the url points to a remote resource, download it! QNetworkReply *reply = nullptr; // The following code blocks until the file is downloaded... // TODO: use signals to get reply finished notification, in this moment // it's executed while rendering. while ( 1 ) { QgsDebugMsg( QString( "get svg: %1" ).arg( svgUrl.toString() ) ); QNetworkRequest request( svgUrl ); request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache ); request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true ); reply = QgsNetworkAccessManager::instance()->get( request ); connect( reply, SIGNAL( downloadProgress( qint64, qint64 ) ), this, SLOT( downloadProgress( qint64, qint64 ) ) ); //emit statusChanged( tr( "Downloading svg." ) ); // wait until the image download finished // TODO: connect to the reply->finished() signal while ( !reply->isFinished() ) { QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents, 500 ); } if ( reply->error() != QNetworkReply::NoError ) { QgsMessageLog::logMessage( tr( "SVG request failed [error: %1 - url: %2]" ).arg( reply->errorString(), reply->url().toString() ), tr( "SVG" ) ); reply->deleteLater(); return QByteArray(); } QVariant redirect = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ); if ( redirect.isNull() ) { // neither network error nor redirection // TODO: cache the image break; } // do a new request to the redirect url svgUrl = redirect.toUrl(); reply->deleteLater(); } QVariant status = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ); if ( !status.isNull() && status.toInt() >= 400 ) { QVariant phrase = reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute ); QgsMessageLog::logMessage( tr( "SVG request error [status: %1 - reason phrase: %2]" ).arg( status.toInt() ).arg( phrase.toString() ), tr( "SVG" ) ); reply->deleteLater(); return mMissingSvg; } QString contentType = reply->header( QNetworkRequest::ContentTypeHeader ).toString(); QgsDebugMsg( "contentType: " + contentType ); if ( !contentType.startsWith( "image/svg+xml", Qt::CaseInsensitive ) ) { reply->deleteLater(); return mMissingSvg; } // read the image data QByteArray ba = reply->readAll(); reply->deleteLater(); return ba; }
// // There have been problems with the finish-signal coming from the networkmanager. // To avoid that, the reply-signals were connected and the data is taken from the // sender() method. // void ownCloudInfo::slotReplyFinished() { QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender()); QSslConfiguration sslConfig = reply->sslConfiguration(); if (!sslConfig.isNull()) { QMutexLocker lock(&_certChainMutex); _certificateChain = sslConfig.peerCertificateChain(); } if( ! reply ) { qDebug() << "ownCloudInfo: Reply empty!"; return; } // Detect redirect url QVariant possibleRedirUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); /* We'll deduct if the redirection is valid in the redirectUrl function */ _urlRedirectedTo = redirectUrl( possibleRedirUrl.toUrl(), _urlRedirectedTo ); if(!_urlRedirectedTo.isEmpty()) { QString configHandle; qDebug() << "Redirected to " << possibleRedirUrl; // We'll do another request to the redirection url. // an empty config handle is ok for the default config. if( _configHandleMap.contains(reply) ) { configHandle = _configHandleMap[reply]; qDebug() << "Redirect: Have a custom config handle: " << configHandle; } QString path = _directories[reply]; qDebug() << "This path was redirected: " << path; MirallConfigFile cfgFile( configHandle ); QString newUrl = _urlRedirectedTo.toString(); if( newUrl.endsWith( path )) { // cut off the trailing path newUrl.chop( path.length() ); cfgFile.setOwnCloudUrl( _connection, newUrl ); qDebug() << "Update the config file url to " << newUrl; getRequest( path, false ); // FIXME: Redirect for webdav! reply->deleteLater(); return; } else { qDebug() << "WRN: Path is not part of the redirect URL. NO redirect."; } } _urlRedirectedTo.clear(); // TODO: check if this is always the correct encoding const QString version = QString::fromUtf8( reply->readAll() ); const QString url = reply->url().toString(); QString plainUrl(url); plainUrl.remove( QLatin1String("/status.php")); QString info( version ); if( url.endsWith( QLatin1String("status.php")) ) { // it was a call to status.php if( reply->error() == QNetworkReply::NoError && info.isEmpty() ) { // This seems to be a bit strange behaviour of QNetworkAccessManager. // It calls the finised slot multiple times but only the first read wins. // That happend when the code connected the finished signal of the manager. // It did not happen when the code connected to the reply finish signal. qDebug() << "WRN: NetworkReply with not content but also no error! " << reply; reply->deleteLater(); return; } qDebug() << "status.php returns: " << info << " " << reply->error() << " Reply: " << reply; if( info.contains(QLatin1String("installed")) && info.contains(QLatin1String("version")) && info.contains(QLatin1String("versionstring")) ) { info.remove(0,1); // remove first char which is a "{" info.remove(-1,1); // remove the last char which is a "}" QStringList li = info.split( QLatin1Char(',') ); QString versionStr; QString version; QString edition; foreach ( const QString& infoString, li ) { QStringList touple = infoString.split( QLatin1Char(':')); QString key = touple[0]; key.remove(QLatin1Char('"')); QString val = touple[1]; val.remove(QLatin1Char('"')); if( key == QLatin1String("versionstring") ) { // get the versionstring out. versionStr = val; } else if( key == QLatin1String( "version") ) { // get version out version = val; } else if( key == QLatin1String( "edition") ) { // get version out edition = val; } else if(key == QLatin1String("installed")) { // Silently ignoring "installed = true" information } else { qDebug() << "Unknown info from ownCloud status.php: "<< key << "=" << val; } } emit ownCloudInfoFound( plainUrl, versionStr, version, edition ); } else {
void OnlineSearchBioRxiv::bibTeXDownloadDone() { emit progress(++curStep, numSteps); QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); if (handleErrors(reply)) { /// ensure proper treatment of UTF-8 characters const QString bibTeXcode = QString::fromUtf8(reply->readAll().constData()); if (!bibTeXcode.isEmpty()) { FileImporterBibTeX importer; File *bibtexFile = importer.fromString(bibTeXcode); if (bibtexFile != NULL) { for (File::ConstIterator it = bibtexFile->constBegin(); it != bibtexFile->constEnd(); ++it) { QSharedPointer<Entry> entry = (*it).dynamicCast<Entry>(); publishEntry(entry); } delete bibtexFile; } else { qCWarning(LOG_KBIBTEX_NETWORKING) << "No valid BibTeX file results returned on request on" << reply->url().toDisplayString(); } } } if (d->resultPageUrls.isEmpty()) stopSearch(resultNoError); else { const QUrl firstUrl = *d->resultPageUrls.constBegin(); d->resultPageUrls.remove(firstUrl); QNetworkRequest request(firstUrl); QNetworkReply *reply = InternalNetworkAccessManager::self()->get(request); InternalNetworkAccessManager::self()->setNetworkReplyTimeout(reply); connect(reply, &QNetworkReply::finished, this, &OnlineSearchBioRxiv::resultPageDone); } }
void NetworkAccessManager::HandleSslErrors(const QList<QSslError> &errors){ QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); if(!reply){ return; } Application::AskSslErrorPolicyIfNeed(); switch(Application::GetSslErrorPolicy()){ case Application::BlockAccess: break; case Application::IgnoreSslErrors: reply->ignoreSslErrors(); break; case Application::AskForEachAccess:{ ModalDialog *dialog = new ModalDialog(); dialog->SetTitle(tr("Ssl errors.")); dialog->SetCaption(tr("Ssl errors.")); dialog->SetInformativeText(tr("Ignore errors in this access?")); QString detail; foreach(QSslError error, errors){ if(!detail.isEmpty()) detail += QStringLiteral("\n"); detail += QStringLiteral("Ssl error : ") + error.errorString(); } dialog->SetDetailedText(detail); dialog->SetButtons(QStringList() << tr("Allow") << tr("Block")); if(dialog->Execute() && dialog->ClickedButton() == tr("Allow")) reply->ignoreSslErrors(); break; } case Application::AskForEachHost: case Application::AskForEachCertificate:{ QString host = reply->url().host(); if(Application::GetBlockedHosts().contains(host)){ break; } else if(Application::GetAllowedHosts().contains(host)){ reply->ignoreSslErrors(); break; } else { ModalDialog *dialog = new ModalDialog(); dialog->SetTitle(tr("Ssl errors on host:%1").arg(host)); dialog->SetCaption(tr("Ssl errors on host:%1").arg(host)); dialog->SetInformativeText(tr("Allow or Block this host?")); QString detail; foreach(QSslError error, errors){ if(!detail.isEmpty()) detail += QStringLiteral("\n"); detail += QStringLiteral("Ssl error : ") + error.errorString(); } dialog->SetDetailedText(detail); dialog->SetButtons(QStringList() << tr("Allow") << tr("Block") << tr("Cancel")); dialog->Execute(); QString text = dialog->ClickedButton(); if(text == tr("Allow")){ Application::AppendToAllowedHosts(host); reply->ignoreSslErrors(); } else if(text == tr("Block")){ Application::AppendToBlockedHosts(host); } break; } } default: break; } }