@@ -0,0 +1,36 | |||
|
1 | #ifndef DOWNLOADER_H | |
|
2 | #define DOWNLOADER_H | |
|
3 | ||
|
4 | #include "CoreGlobal.h" | |
|
5 | #include "Response.h" | |
|
6 | ||
|
7 | #include <Common/MetaTypes.h> | |
|
8 | #include <Common/spimpl.h> | |
|
9 | #include <functional> | |
|
10 | ||
|
11 | #include <QString> | |
|
12 | #include <QByteArray> | |
|
13 | ||
|
14 | /** | |
|
15 | * @brief The Downloader handles all data donwloads in SciQLOP. | |
|
16 | */ | |
|
17 | class SCIQLOP_CORE_EXPORT Downloader{ | |
|
18 | public: | |
|
19 | static Response get(const QString& url); | |
|
20 | static Response get(const QString& url, const QString& user, const QString& passwd); | |
|
21 | ||
|
22 | static Downloader& instance() | |
|
23 | { | |
|
24 | static Downloader inst; | |
|
25 | return inst; | |
|
26 | } | |
|
27 | ||
|
28 | private: | |
|
29 | class p_Downloader; | |
|
30 | ||
|
31 | explicit Downloader(); | |
|
32 | ||
|
33 | spimpl::unique_impl_ptr<Downloader::p_Downloader> impl; | |
|
34 | }; | |
|
35 | ||
|
36 | #endif // DOWNLOADER_H |
@@ -0,0 +1,25 | |||
|
1 | #ifndef RESPONSE_H | |
|
2 | #define RESPONSE_H | |
|
3 | ||
|
4 | #include <QByteArray> | |
|
5 | #include <QString> | |
|
6 | ||
|
7 | /** | |
|
8 | * @brief The Response class holds a Network request response | |
|
9 | * | |
|
10 | */ | |
|
11 | class Response | |
|
12 | { | |
|
13 | int _status_code; | |
|
14 | QByteArray _data; | |
|
15 | public: | |
|
16 | Response(){} | |
|
17 | Response(QByteArray data, int status_code) | |
|
18 | :_status_code(status_code),_data(data) | |
|
19 | { | |
|
20 | ||
|
21 | } | |
|
22 | int status_code(){return _status_code;} | |
|
23 | QByteArray& data(){return _data;} | |
|
24 | }; | |
|
25 | #endif // RESPONSE_H |
@@ -0,0 +1,69 | |||
|
1 | #include <Network/Downloader.h> | |
|
2 | #include <memory> | |
|
3 | ||
|
4 | #include <QNetworkRequest> | |
|
5 | #include <QNetworkReply> | |
|
6 | #include <QNetworkAccessManager> | |
|
7 | #include <QAuthenticator> | |
|
8 | #include <QVariant> | |
|
9 | #include <QHash> | |
|
10 | #include <QPair> | |
|
11 | #include <QCoreApplication> | |
|
12 | ||
|
13 | class Downloader::p_Downloader | |
|
14 | { | |
|
15 | using login_pair=QPair<QString,QString>; | |
|
16 | QNetworkAccessManager manager; | |
|
17 | QHash<QString,login_pair> auth; | |
|
18 | ||
|
19 | public: | |
|
20 | explicit p_Downloader() | |
|
21 | { | |
|
22 | ||
|
23 | auto login_bambda = [this](QNetworkReply * reply, QAuthenticator * authenticator) | |
|
24 | { | |
|
25 | if(auth.contains(reply->url().toString())) | |
|
26 | { | |
|
27 | auto login = auth[reply->url().toString()]; | |
|
28 | authenticator->setUser(login.first); | |
|
29 | authenticator->setPassword(login.second); | |
|
30 | } | |
|
31 | }; | |
|
32 | QObject::connect(&manager, &QNetworkAccessManager::authenticationRequired, login_bambda); | |
|
33 | } | |
|
34 | ||
|
35 | Response get(const QString& url, const QString &user="", const QString &passwd="") | |
|
36 | { | |
|
37 | QNetworkRequest request; | |
|
38 | request.setUrl(QUrl(url)); | |
|
39 | request.setRawHeader("User-Agent", "SciQLop 1.0"); | |
|
40 | if(user!="" and passwd!="") | |
|
41 | { | |
|
42 | //might grow quickly since we can have tons of URLs for the same host | |
|
43 | auth[url]=login_pair(user,passwd); | |
|
44 | QString login = "Basic "+user+":"+passwd; | |
|
45 | request.setRawHeader("Authorization",login.toLocal8Bit()); | |
|
46 | } | |
|
47 | QNetworkReply *reply = manager.get(request); | |
|
48 | while (!reply->isFinished()) | |
|
49 | QCoreApplication::processEvents(); | |
|
50 | QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); | |
|
51 | return Response(reply->readAll(), status_code.toInt()); | |
|
52 | } | |
|
53 | }; | |
|
54 | ||
|
55 | Response Downloader::get(const QString &url) | |
|
56 | { | |
|
57 | return Downloader::instance().impl->get(url); | |
|
58 | } | |
|
59 | ||
|
60 | Response Downloader::get(const QString &url, const QString &user, const QString &passwd) | |
|
61 | { | |
|
62 | return Downloader::instance().impl->get(url, user, passwd); | |
|
63 | } | |
|
64 | ||
|
65 | Downloader::Downloader() | |
|
66 | :impl(spimpl::make_unique_impl<p_Downloader>()) | |
|
67 | { | |
|
68 | } | |
|
69 |
@@ -0,0 +1,59 | |||
|
1 | #include <Network/Downloader.h> | |
|
2 | #include <QtTest> | |
|
3 | #include <QObject> | |
|
4 | ||
|
5 | ||
|
6 | class TestDownloader : public QObject | |
|
7 | ||
|
8 | { | |
|
9 | Q_OBJECT | |
|
10 | public: | |
|
11 | explicit TestDownloader(QObject *parent = nullptr) : QObject(parent){} | |
|
12 | signals: | |
|
13 | ||
|
14 | private slots: | |
|
15 | void initTestCase(){} | |
|
16 | void cleanupTestCase(){} | |
|
17 | ||
|
18 | void simpleGet() | |
|
19 | { | |
|
20 | auto resp = Downloader::get("https://httpbin.org/user-agent"); | |
|
21 | QCOMPARE(resp.status_code(), 200); | |
|
22 | QCOMPARE(resp.data(), QString("{\n \"user-agent\": \"SciQLop 1.0\"\n}\n")); | |
|
23 | } | |
|
24 | ||
|
25 | void wrongUrl() | |
|
26 | { | |
|
27 | auto resp = Downloader::get("https://lpp.polytechniqe2.fr"); | |
|
28 | QCOMPARE(resp.status_code(), 0); | |
|
29 | resp = Downloader::get("https://hephaistos.lpp.polytechnique.fr/will_never_exist"); | |
|
30 | QCOMPARE(resp.status_code(), 404); | |
|
31 | ||
|
32 | } | |
|
33 | ||
|
34 | void authGet_data() | |
|
35 | { | |
|
36 | QTest::addColumn<QString>("url"); | |
|
37 | QTest::addColumn<int>("code"); | |
|
38 | ||
|
39 | QTest::newRow("basic-auth") << "https://httpbin.org/basic-auth/user/passwd" << 200; | |
|
40 | QTest::newRow("digest-auth") << "https://httpbin.org/digest-auth/auth/user/passwd" << 200; | |
|
41 | QTest::newRow("hidden-basic-auth") << "https://httpbin.org/hidden-basic-auth/user/passwd" << 404; | |
|
42 | } | |
|
43 | ||
|
44 | void authGet() | |
|
45 | { | |
|
46 | QFETCH(QString, url); | |
|
47 | QFETCH(int, code); | |
|
48 | auto resp = Downloader::get(url, "user", "passwd"); | |
|
49 | QCOMPARE(resp.status_code(), code); | |
|
50 | } | |
|
51 | ||
|
52 | private: | |
|
53 | ||
|
54 | }; | |
|
55 | ||
|
56 | ||
|
57 | QTEST_MAIN(TestDownloader) | |
|
58 | ||
|
59 | #include "TestDownloader.moc" |
@@ -66,6 +66,7 FILE (GLOB_RECURSE core_SRCS | |||
|
66 | 66 | ./src/Data/DataSeriesUtils.cpp |
|
67 | 67 | ./src/Data/VectorSeries.cpp |
|
68 | 68 | ./src/Network/NetworkController.cpp |
|
69 | ./src/Network/Downloader.cpp | |
|
69 | 70 | ./src/Catalogue/CatalogueController.cpp |
|
70 | 71 | ./src/Visualization/VisualizationController.cpp |
|
71 | 72 | ./src/PluginManager/PluginManager.cpp |
@@ -31,3 +31,4 declare_test(TestVariableCacheController TestVariableCacheController Variable/Te | |||
|
31 | 31 | declare_test(TestVariableController TestVariableController Variable/TestVariableController.cpp "sciqlopcore;Qt5::Test") |
|
32 | 32 | declare_test(TestVariableSync TestVariableSync Variable/TestVariableSync.cpp "sciqlopcore;Qt5::Test") |
|
33 | 33 | |
|
34 | declare_test(TestDownloader TestDownloader Network/TestDownloader.cpp "sciqlopcore;Qt5::Test") |
General Comments 0
You need to be logged in to leave comments.
Login now