@@ -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 | ./src/Data/DataSeriesUtils.cpp |
|
66 | ./src/Data/DataSeriesUtils.cpp | |
67 | ./src/Data/VectorSeries.cpp |
|
67 | ./src/Data/VectorSeries.cpp | |
68 | ./src/Network/NetworkController.cpp |
|
68 | ./src/Network/NetworkController.cpp | |
|
69 | ./src/Network/Downloader.cpp | |||
69 | ./src/Catalogue/CatalogueController.cpp |
|
70 | ./src/Catalogue/CatalogueController.cpp | |
70 | ./src/Visualization/VisualizationController.cpp |
|
71 | ./src/Visualization/VisualizationController.cpp | |
71 | ./src/PluginManager/PluginManager.cpp |
|
72 | ./src/PluginManager/PluginManager.cpp |
@@ -31,3 +31,4 declare_test(TestVariableCacheController TestVariableCacheController Variable/Te | |||||
31 | declare_test(TestVariableController TestVariableController Variable/TestVariableController.cpp "sciqlopcore;Qt5::Test") |
|
31 | declare_test(TestVariableController TestVariableController Variable/TestVariableController.cpp "sciqlopcore;Qt5::Test") | |
32 | declare_test(TestVariableSync TestVariableSync Variable/TestVariableSync.cpp "sciqlopcore;Qt5::Test") |
|
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