2012-02-20 21:47:14 +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 */
|
|
|
|
|
|
|
|
#ifndef __ARTICLE_NETMGR_HH_INCLUDED__
|
|
|
|
#define __ARTICLE_NETMGR_HH_INCLUDED__
|
|
|
|
|
|
|
|
#include <QtNetwork>
|
2017-03-21 14:35:34 +00:00
|
|
|
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5,2,0)
|
|
|
|
#include <QWebSecurityOrigin>
|
|
|
|
#include <QSet>
|
|
|
|
#include <QMap>
|
|
|
|
#include <QPair>
|
|
|
|
#endif
|
|
|
|
|
2009-01-28 20:55:45 +00:00
|
|
|
#include "dictionary.hh"
|
|
|
|
#include "article_maker.hh"
|
|
|
|
|
|
|
|
using std::vector;
|
|
|
|
|
|
|
|
/// A custom QNetworkAccessManager version which fetches images from the
|
|
|
|
/// dictionaries when requested.
|
|
|
|
|
2017-03-21 14:35:34 +00:00
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5,2,0)
|
|
|
|
|
|
|
|
// White lists for QWebSecurityOrigin
|
|
|
|
struct SecurityWhiteList
|
|
|
|
{
|
|
|
|
QWebSecurityOrigin * origin;
|
|
|
|
QString originUri;
|
|
|
|
QSet< QPair< QString, QString > > hostsToAccess;
|
|
|
|
|
|
|
|
SecurityWhiteList() :
|
|
|
|
origin( 0 )
|
|
|
|
{}
|
|
|
|
|
|
|
|
~SecurityWhiteList()
|
|
|
|
{
|
|
|
|
swlDelete();
|
|
|
|
}
|
|
|
|
SecurityWhiteList( SecurityWhiteList const & swl ) :
|
|
|
|
origin( 0 )
|
|
|
|
{
|
|
|
|
swlCopy( swl );
|
|
|
|
}
|
|
|
|
|
|
|
|
SecurityWhiteList & operator=( SecurityWhiteList const & swl )
|
|
|
|
{
|
|
|
|
swlDelete();
|
|
|
|
swlCopy( swl );
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
QWebSecurityOrigin * setOrigin( QUrl const & url )
|
|
|
|
{
|
|
|
|
swlDelete();
|
|
|
|
originUri = url.toString( QUrl::FullyDecoded );
|
|
|
|
origin = new QWebSecurityOrigin( url );
|
|
|
|
return origin;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
void swlCopy( SecurityWhiteList const & swl )
|
|
|
|
{
|
|
|
|
if( swl.origin )
|
|
|
|
{
|
|
|
|
hostsToAccess = swl.hostsToAccess;
|
|
|
|
originUri = swl.originUri;
|
|
|
|
origin = new QWebSecurityOrigin( QUrl( originUri ) );
|
|
|
|
|
|
|
|
for( QSet< QPair< QString, QString > >::iterator it = hostsToAccess.begin();
|
|
|
|
it != hostsToAccess.end(); ++it )
|
|
|
|
origin->addAccessWhitelistEntry( it->first, it->second, QWebSecurityOrigin::AllowSubdomains );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void swlDelete()
|
|
|
|
{
|
|
|
|
if( origin )
|
|
|
|
{
|
|
|
|
for( QSet< QPair< QString, QString > >::iterator it = hostsToAccess.begin();
|
|
|
|
it != hostsToAccess.end(); ++it )
|
|
|
|
origin->removeAccessWhitelistEntry( it->first, it->second, QWebSecurityOrigin::AllowSubdomains );
|
|
|
|
|
|
|
|
delete origin;
|
|
|
|
origin = 0;
|
|
|
|
}
|
|
|
|
hostsToAccess.clear();
|
|
|
|
originUri.clear();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef QMap< QString, SecurityWhiteList > Origins;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-01-28 20:55:45 +00:00
|
|
|
class ArticleNetworkAccessManager: public QNetworkAccessManager
|
|
|
|
{
|
|
|
|
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;
|
2017-03-21 14:35:34 +00:00
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5,2,0)
|
|
|
|
Origins allOrigins;
|
|
|
|
#endif
|
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
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
virtual QNetworkReply * createRequest( Operation op,
|
|
|
|
QNetworkRequest const & req,
|
|
|
|
QIODevice * outgoingData );
|
|
|
|
};
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
virtual qint64 bytesAvailable() const;
|
|
|
|
|
|
|
|
virtual void abort()
|
|
|
|
{}
|
|
|
|
virtual qint64 readData( char * data, qint64 maxSize );
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
|
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();
|
|
|
|
};
|
|
|
|
|
2009-01-28 20:55:45 +00:00
|
|
|
#endif
|