2021-08-14 07:25:10 +00:00
|
|
|
/* This file is (c) 2008-2012 Konstantin Isakov <ikm@goldendict.org>
|
2009-01-28 20:55:45 +00:00
|
|
|
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
|
|
|
|
2024-11-07 03:53:04 +00:00
|
|
|
#pragma once
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
#include <QtNetwork>
|
2017-03-21 14:35:34 +00:00
|
|
|
#include <QSet>
|
|
|
|
#include <QMap>
|
2021-08-05 06:57:22 +00:00
|
|
|
#include <QWebEngineUrlSchemeHandler>
|
|
|
|
#include <QWebEngineUrlRequestJob>
|
|
|
|
#include <QNetworkAccessManager>
|
2017-03-21 14:35:34 +00:00
|
|
|
|
2021-08-05 06:57:22 +00:00
|
|
|
#include <utility>
|
2024-09-02 00:07:17 +00:00
|
|
|
|
2023-04-17 20:55:34 +00:00
|
|
|
#include "dict/dictionary.hh"
|
2009-01-28 20:55:45 +00:00
|
|
|
#include "article_maker.hh"
|
|
|
|
|
|
|
|
using std::vector;
|
|
|
|
|
|
|
|
/// A custom QNetworkAccessManager version which fetches images from the
|
|
|
|
/// dictionaries when requested.
|
|
|
|
|
2017-03-23 15:03:17 +00:00
|
|
|
// Proxy class for QNetworkReply to remove X-Frame-Options header
|
|
|
|
// It allow to show websites in <iframe> tag like Qt 4.x
|
|
|
|
|
|
|
|
class AllowFrameReply: public QNetworkReply
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
2023-07-20 08:02:22 +00:00
|
|
|
|
2017-03-23 15:03:17 +00:00
|
|
|
private:
|
|
|
|
QNetworkReply * baseReply;
|
2017-03-24 14:05:22 +00:00
|
|
|
QByteArray buffer;
|
2017-03-23 15:03:17 +00:00
|
|
|
|
|
|
|
AllowFrameReply();
|
|
|
|
AllowFrameReply( AllowFrameReply const & );
|
2017-03-21 14:35:34 +00:00
|
|
|
|
2017-03-23 15:03:17 +00:00
|
|
|
public:
|
|
|
|
explicit AllowFrameReply( QNetworkReply * _reply );
|
|
|
|
~AllowFrameReply()
|
|
|
|
{
|
|
|
|
delete baseReply;
|
|
|
|
}
|
|
|
|
|
2024-11-05 22:17:54 +00:00
|
|
|
void close() override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
baseReply->close();
|
|
|
|
}
|
|
|
|
|
|
|
|
// QIODevice virtual functions
|
2024-11-05 22:17:54 +00:00
|
|
|
qint64 bytesAvailable() const override;
|
2024-10-26 11:35:27 +00:00
|
|
|
bool atEnd() const override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
return baseReply->atEnd();
|
|
|
|
}
|
2024-11-05 22:17:54 +00:00
|
|
|
qint64 bytesToWrite() const override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
return baseReply->bytesToWrite();
|
|
|
|
}
|
2024-11-05 22:17:54 +00:00
|
|
|
bool canReadLine() const override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
return baseReply->canReadLine();
|
|
|
|
}
|
2024-11-05 22:17:54 +00:00
|
|
|
bool isSequential() const override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
return baseReply->isSequential();
|
|
|
|
}
|
2024-11-05 22:17:54 +00:00
|
|
|
bool waitForReadyRead( int msecs ) override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
return baseReply->waitForReadyRead( msecs );
|
|
|
|
}
|
2024-11-05 22:17:54 +00:00
|
|
|
bool waitForBytesWritten( int msecs ) override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
return baseReply->waitForBytesWritten( msecs );
|
|
|
|
}
|
2024-11-05 22:17:54 +00:00
|
|
|
bool reset() override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
return baseReply->reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
void applyError( QNetworkReply::NetworkError code );
|
|
|
|
|
|
|
|
// Redirect QNetworkReply slots
|
2024-11-05 22:17:54 +00:00
|
|
|
void abort() override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
baseReply->abort();
|
|
|
|
}
|
2024-11-05 22:17:54 +00:00
|
|
|
void ignoreSslErrors() override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
baseReply->ignoreSslErrors();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// QNetworkReply virtual functions
|
2024-11-05 22:17:54 +00:00
|
|
|
void ignoreSslErrorsImplementation( const QList< QSslError > & errors ) override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
baseReply->ignoreSslErrors( errors );
|
|
|
|
}
|
2024-11-05 22:17:54 +00:00
|
|
|
void setSslConfigurationImplementation( const QSslConfiguration & configuration ) override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
baseReply->setSslConfiguration( configuration );
|
|
|
|
}
|
2024-11-05 22:17:54 +00:00
|
|
|
void sslConfigurationImplementation( QSslConfiguration & configuration ) const override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
configuration = baseReply->sslConfiguration();
|
|
|
|
}
|
|
|
|
|
|
|
|
// QIODevice virtual functions
|
2024-11-05 22:17:54 +00:00
|
|
|
qint64 readData( char * data, qint64 maxSize ) override;
|
|
|
|
qint64 readLineData( char * data, qint64 maxSize ) override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
return baseReply->readLine( data, maxSize );
|
|
|
|
}
|
2024-11-05 22:17:54 +00:00
|
|
|
qint64 writeData( const char * data, qint64 maxSize ) override
|
2017-03-23 15:03:17 +00:00
|
|
|
{
|
|
|
|
return baseReply->write( data, maxSize );
|
|
|
|
}
|
|
|
|
};
|
2021-07-24 07:18:46 +00:00
|
|
|
|
2023-10-07 12:49:38 +00:00
|
|
|
enum class ResourceType {
|
|
|
|
UNTITLE,
|
2023-10-10 13:17:34 +00:00
|
|
|
WELCOME,
|
|
|
|
BLANK
|
2023-10-07 12:49:38 +00:00
|
|
|
};
|
2017-03-21 14:35:34 +00:00
|
|
|
|
2009-01-28 20:55:45 +00:00
|
|
|
class ArticleNetworkAccessManager: public QNetworkAccessManager
|
|
|
|
{
|
2021-08-05 06:57:22 +00:00
|
|
|
Q_OBJECT
|
2009-01-28 20:55:45 +00:00
|
|
|
vector< sptr< Dictionary::Class > > const & dictionaries;
|
|
|
|
ArticleMaker const & articleMaker;
|
2009-08-31 12:18:08 +00:00
|
|
|
bool const & disallowContentFromOtherSites;
|
2013-04-08 12:20:12 +00:00
|
|
|
bool const & hideGoldenDictHeader;
|
2021-12-27 13:15:13 +00:00
|
|
|
QMimeDatabase db;
|
2021-09-25 02:23:03 +00:00
|
|
|
|
2009-01-28 20:55:45 +00:00
|
|
|
public:
|
|
|
|
|
|
|
|
ArticleNetworkAccessManager( QObject * parent,
|
|
|
|
vector< sptr< Dictionary::Class > > const & dictionaries_,
|
2009-08-31 12:18:08 +00:00
|
|
|
ArticleMaker const & articleMaker_,
|
2013-04-08 12:20:12 +00:00
|
|
|
bool const & disallowContentFromOtherSites_,
|
|
|
|
bool const & hideGoldenDictHeader_ ):
|
2009-01-28 20:55:45 +00:00
|
|
|
QNetworkAccessManager( parent ),
|
|
|
|
dictionaries( dictionaries_ ),
|
2009-08-31 12:18:08 +00:00
|
|
|
articleMaker( articleMaker_ ),
|
2013-04-08 12:20:12 +00:00
|
|
|
disallowContentFromOtherSites( disallowContentFromOtherSites_ ),
|
|
|
|
hideGoldenDictHeader( hideGoldenDictHeader_ )
|
2009-01-28 20:55:45 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-03-26 19:00:08 +00:00
|
|
|
/// Tries handling any kind of internal resources referenced by dictionaries.
|
|
|
|
/// If it succeeds, the result is a dictionary request object. Otherwise, an
|
|
|
|
/// empty pointer is returned.
|
|
|
|
/// The function can optionally set the Content-Type header correspondingly.
|
|
|
|
sptr< Dictionary::DataRequest > getResource( QUrl const & url, QString & contentType );
|
2009-01-28 20:55:45 +00:00
|
|
|
|
2022-05-18 23:14:36 +00:00
|
|
|
virtual QNetworkReply * getArticleReply( QNetworkRequest const & req );
|
2023-10-07 12:49:38 +00:00
|
|
|
string getHtml( ResourceType resourceType );
|
2009-01-28 20:55:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class ArticleResourceReply: public QNetworkReply
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
2009-03-26 19:00:08 +00:00
|
|
|
sptr< Dictionary::DataRequest > req;
|
2014-05-12 13:43:02 +00:00
|
|
|
qint64 alreadyRead;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
2022-01-09 06:30:06 +00:00
|
|
|
QAtomicInt finishSignalSent;
|
|
|
|
|
2009-01-28 20:55:45 +00:00
|
|
|
public:
|
|
|
|
|
|
|
|
ArticleResourceReply( QObject * parent,
|
|
|
|
QNetworkRequest const &,
|
2009-03-26 19:00:08 +00:00
|
|
|
sptr< Dictionary::DataRequest > const &,
|
2009-01-28 20:55:45 +00:00
|
|
|
QString const & contentType );
|
|
|
|
|
2009-03-28 15:59:39 +00:00
|
|
|
~ArticleResourceReply();
|
|
|
|
|
2009-01-28 20:55:45 +00:00
|
|
|
protected:
|
|
|
|
|
2024-11-05 22:17:54 +00:00
|
|
|
virtual qint64 bytesAvailable() const override;
|
2024-10-26 11:35:27 +00:00
|
|
|
bool atEnd() const override;
|
2024-11-05 22:17:54 +00:00
|
|
|
virtual void abort() override {}
|
|
|
|
virtual qint64 readData( char * data, qint64 maxSize ) override;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
// We use the hackery below to work around the fact that we need to emit
|
|
|
|
// ready/finish signals after we've been constructed.
|
|
|
|
signals:
|
|
|
|
|
|
|
|
void readyReadSignal();
|
|
|
|
void finishedSignal();
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
|
2009-03-26 19:00:08 +00:00
|
|
|
void reqUpdated();
|
|
|
|
void reqFinished();
|
2023-07-20 08:02:22 +00:00
|
|
|
|
2009-01-28 20:55:45 +00:00
|
|
|
void readyReadSlot();
|
|
|
|
void finishedSlot();
|
|
|
|
};
|
|
|
|
|
2009-08-31 12:18:08 +00:00
|
|
|
class BlockedNetworkReply: public QNetworkReply
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
BlockedNetworkReply( QObject * parent );
|
|
|
|
|
|
|
|
virtual qint64 readData( char *, qint64 )
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void abort() {}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
// We use the hackery below to work around the fact that we need to emit
|
|
|
|
// ready/finish signals after we've been constructed.
|
|
|
|
|
|
|
|
signals:
|
|
|
|
|
|
|
|
void finishedSignal();
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
|
|
|
|
void finishedSlot();
|
|
|
|
};
|
|
|
|
|
2021-10-02 12:48:49 +00:00
|
|
|
class LocalSchemeHandler: public QWebEngineUrlSchemeHandler
|
2021-08-05 06:57:22 +00:00
|
|
|
{
|
2022-05-18 23:14:36 +00:00
|
|
|
Q_OBJECT
|
2023-07-20 08:02:22 +00:00
|
|
|
|
2021-08-05 06:57:22 +00:00
|
|
|
public:
|
2022-12-22 01:08:41 +00:00
|
|
|
LocalSchemeHandler( ArticleNetworkAccessManager & articleNetMgr, QObject * parent = nullptr );
|
2022-05-18 23:14:36 +00:00
|
|
|
void requestStarted( QWebEngineUrlRequestJob * requestJob );
|
2021-08-21 01:41:40 +00:00
|
|
|
|
2021-08-05 06:57:22 +00:00
|
|
|
protected:
|
2023-07-20 08:02:22 +00:00
|
|
|
|
2021-09-24 12:29:13 +00:00
|
|
|
private:
|
2022-05-18 23:14:36 +00:00
|
|
|
ArticleNetworkAccessManager & mManager;
|
2022-05-13 16:00:23 +00:00
|
|
|
QNetworkAccessManager mgr;
|
2021-08-05 06:57:22 +00:00
|
|
|
};
|