28#include <QNetworkReply>
32#include "moc_qgsnetworkcontentfetcher.cpp"
34using namespace Qt::StringLiterals;
38 if ( mReply && mReply->isRunning() )
47 QNetworkRequest req( url );
58 QNetworkRequest request( r );
59 request.setAttribute( QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy );
62 if ( !mAuthCfg.isEmpty() )
67 mContentLoaded =
false;
74 mReply.release()->deleteLater();
79 if ( !mAuthCfg.isEmpty() )
83 mReply->setParent(
nullptr );
84 connect( mReply.get(), &QNetworkReply::finished,
this, [
this] { contentLoaded(); } );
87 auto onError = [
this]( QNetworkReply::NetworkError code ) {
93 connect( mReply.get(), &QNetworkReply::errorOccurred,
this, onError );
98 if ( !mContentLoaded )
113 if ( !mContentLoaded || !mReply )
118 QByteArray array = mReply->readAll();
121 QTextCodec *codec = codecForHtml( array );
122 return codec->toUnicode( array );
133 mReply.release()->deleteLater();
143QTextCodec *QgsNetworkContentFetcher::codecForHtml( QByteArray &array )
const
150 QTextCodec *codec = QTextCodec::codecForUtfText( array,
nullptr );
157 const QByteArray header = array.left( 1024 ).toLower();
158 int pos = header.indexOf(
"meta charset=" );
161 pos += int( strlen(
"meta charset=" ) ) + 1;
162 const int pos2 = header.indexOf(
'\"', pos );
163 const QByteArray cs = header.mid( pos, pos2 - pos );
164 codec = QTextCodec::codecForName( cs );
172 codec = QTextCodec::codecForHtml( array, codec );
179 return QTextCodec::codecForName(
"UTF-8" );
182void QgsNetworkContentFetcher::contentLoaded(
bool ok )
192 if ( mReply->error() != QNetworkReply::NoError )
194 QgsMessageLog::logMessage( tr(
"HTTP fetch %1 failed with error %2" ).arg( mReply->url().toString(), mReply->errorString() ) );
195 mContentLoaded =
true;
200 const QVariant redirect = mReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
204 const QVariant status = mReply->attribute( QNetworkRequest::HttpStatusCodeAttribute );
207 QgsMessageLog::logMessage( tr(
"HTTP fetch %1 failed with error %2" ).arg( mReply->url().toString(), status.toString() ) );
209 mContentLoaded =
true;
215 mReply.release()->deleteLater();
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
bool updateNetworkRequest(QNetworkRequest &request, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkRequest with an authentication config.
bool updateNetworkReply(QNetworkReply *reply, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkReply with an authentication config (used to skip known SSL errors,...
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
QString contentDispositionFilename() const
Returns the associated filename from the reply's content disposition header, if present.
void fetchContent(const QUrl &url, const QString &authcfg=QString(), const QgsHttpHeaders &headers=QgsHttpHeaders())
Fetches content from a remote URL and handles redirects.
void finished()
Emitted when content has loaded.
bool wasCanceled() const
Returns true if the fetching was canceled.
~QgsNetworkContentFetcher() override
void errorOccurred(QNetworkReply::NetworkError code, const QString &errorMsg)
Emitted when an error with code error occurred while processing the request errorMsg is a textual des...
void cancel()
Cancels any ongoing request.
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
Emitted when data is received.
QNetworkReply * reply()
Returns a reference to the network reply.
QString contentAsString() const
Returns the fetched content as a string.
static QString extractFilenameFromContentDispositionHeader(QNetworkReply *reply)
Extracts the filename component of the content disposition header from a network reply.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
#define QgsSetRequestInitiatorClass(request, _class)