summaryrefslogtreecommitdiff
path: root/kde-plasma/plasma-workspace/files/plasma-workspace-5.25.5-geolocation-deadlock.patch
blob: 70bd28419472670a82364529918bc4dee54d25f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
https://invent.kde.org/plasma/plasma-workspace/-/commit/d693026676cc6bf2b7c23e9ff4b620679cf15d10

From d693026676cc6bf2b7c23e9ff4b620679cf15d10 Mon Sep 17 00:00:00 2001
From: Nicolas Fella <nicolas.fella@gmx.de>
Date: Mon, 15 Aug 2022 18:36:56 +0200
Subject: [PATCH] [dataengines/geolocation] Port from KIO::http_post to
 QNetworkAccessManager

Not only does this slightly simplify the code, it also avoids a deadlock in kded when automatic proxy detection is enabled

BUG: 449984

BUG: 457341
(cherry picked from commit 98cadd48c21c89b81fdeb3499a557a6551a09d8a)
---
 dataengines/geolocation/CMakeLists.txt  |  2 +-
 dataengines/geolocation/location_ip.cpp | 84 ++++++++++---------------
 2 files changed, 35 insertions(+), 51 deletions(-)

diff --git a/dataengines/geolocation/CMakeLists.txt b/dataengines/geolocation/CMakeLists.txt
index 175687bd4d..6ae707643c 100644
--- a/dataengines/geolocation/CMakeLists.txt
+++ b/dataengines/geolocation/CMakeLists.txt
@@ -36,7 +36,7 @@ target_link_libraries(plasma_engine_geolocation
 kcoreaddons_add_plugin(plasma-geolocation-ip SOURCES location_ip.cpp INSTALL_NAMESPACE plasma/geolocationprovider)
 ecm_qt_declare_logging_category(plasma-geolocation-ip HEADER geolocdebug.h IDENTIFIER DATAENGINE_GEOLOCATION CATEGORY_NAME org.kde.plasma.dataengine.geolocation)
 target_compile_definitions(plasma-geolocation-ip PRIVATE -DQT_NO_KEYWORDS)
-target_link_libraries(plasma-geolocation-ip plasma-geolocation-interface KF5::KIOCore KF5::NetworkManagerQt)
+target_link_libraries(plasma-geolocation-ip plasma-geolocation-interface KF5::NetworkManagerQt)
 
 pkg_check_modules(LIBGPS libgps IMPORTED_TARGET)
 
diff --git a/dataengines/geolocation/location_ip.cpp b/dataengines/geolocation/location_ip.cpp
index 27b530810c..3c5a202b89 100644
--- a/dataengines/geolocation/location_ip.cpp
+++ b/dataengines/geolocation/location_ip.cpp
@@ -12,15 +12,14 @@
 
 #include "location_ip.h"
 #include "geolocdebug.h"
-#include <KIO/Job>
-#include <KIO/TransferJob>
-#include <KJob>
 #include <KSharedConfig>
 #include <NetworkManagerQt/Manager>
 #include <NetworkManagerQt/WirelessDevice>
 #include <QJsonArray>
 #include <QJsonDocument>
 #include <QJsonObject>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
 #include <QUrl>
 
 class Ip::Private : public QObject
@@ -30,19 +29,21 @@ public:
     Private(Ip *q)
         : q(q)
     {
+        m_nam.setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
+        m_nam.setStrictTransportSecurityEnabled(true);
+        m_nam.enableStrictTransportSecurityStore(true,
+                                                 QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1String("/plasmashell/hsts/"));
     }
 
-    void readGeoLocation(KJob *job)
+    void readGeoLocation(QNetworkReply *reply)
     {
         m_geoLocationResolved = true;
-        if (job && job->error()) {
-            qCCritical(DATAENGINE_GEOLOCATION) << "error: " << job->errorString();
-            m_geoLocationPayload.clear();
+        if (reply->error()) {
+            qCCritical(DATAENGINE_GEOLOCATION) << "error: " << reply->errorString();
             checkUpdateData();
             return;
         }
-        const QJsonObject json = QJsonDocument::fromJson(m_geoLocationPayload).object();
-        m_geoLocationPayload.clear();
+        const QJsonObject json = QJsonDocument::fromJson(reply->readAll()).object();
 
         auto accuracyIt = json.find(QStringLiteral("accuracy"));
         if (accuracyIt != json.end()) {
@@ -62,52 +63,28 @@ public:
 
     void clear()
     {
-        m_geoLocationPayload.clear();
-        m_countryPayload.clear();
         m_countryResolved = false;
         m_geoLocationResolved = false;
         m_data.clear();
     }
 
-    void geoLocationData(KIO::Job *job, const QByteArray &data)
-    {
-        Q_UNUSED(job)
-
-        if (data.isEmpty()) {
-            return;
-        }
-        m_geoLocationPayload.append(data);
-    }
-
-    void countryData(KIO::Job *job, const QByteArray &data)
-    {
-        Q_UNUSED(job)
-
-        if (data.isEmpty()) {
-            return;
-        }
-        m_countryPayload.append(data);
-    }
-
-    void readCountry(KJob *job)
+    void readCountry(QNetworkReply *reply)
     {
         m_countryResolved = true;
-        if (job && job->error()) {
-            qCCritical(DATAENGINE_GEOLOCATION) << "error: " << job->errorString();
-            m_countryPayload.clear();
+        if (reply->error()) {
+            qCCritical(DATAENGINE_GEOLOCATION) << "error: " << reply->errorString();
             checkUpdateData();
             return;
         }
 
-        const QJsonObject json = QJsonDocument::fromJson(m_countryPayload).object();
-        m_countryPayload.clear();
+        const QJsonObject json = QJsonDocument::fromJson(reply->readAll()).object();
 
         m_data[QStringLiteral("country")] = json.value(QStringLiteral("country_name")).toString();
         m_data[QStringLiteral("country code")] = json.value(QStringLiteral("country_code")).toString();
+
         checkUpdateData();
     }
 
-private:
     void checkUpdateData()
     {
         if (!m_countryResolved || !m_geoLocationResolved) {
@@ -117,11 +94,10 @@ private:
     }
 
     Ip *q;
-    QByteArray m_geoLocationPayload;
-    QByteArray m_countryPayload;
     bool m_countryResolved = false;
     bool m_geoLocationResolved = false;
     Plasma::DataEngine::Data m_data;
+    QNetworkAccessManager m_nam;
 };
 
 Ip::Ip(QObject *parent, const QVariantList &args)
@@ -176,18 +152,26 @@ void Ip::update()
     }
     const QByteArray postData = QJsonDocument(request).toJson(QJsonDocument::Compact);
     const QString apiKey = QStringLiteral("60e8eae6-3988-4ada-ad48-2cfddddf216b");
-    KIO::TransferJob *datajob =
-        KIO::http_post(QUrl(QStringLiteral("https://location.services.mozilla.com/v1/geolocate?key=%1").arg(apiKey)), postData, KIO::HideProgressInfo);
-    datajob->addMetaData(QStringLiteral("content-type"), QStringLiteral("application/json"));
 
     qCDebug(DATAENGINE_GEOLOCATION) << "Fetching https://location.services.mozilla.com/v1/geolocate";
-    connect(datajob, &KIO::TransferJob::data, d, &Ip::Private::geoLocationData);
-    connect(datajob, &KIO::TransferJob::result, d, &Ip::Private::readGeoLocation);
-
-    datajob = KIO::http_post(QUrl(QStringLiteral("https://location.services.mozilla.com/v1/country?key=%1").arg(apiKey)), postData, KIO::HideProgressInfo);
-    datajob->addMetaData(QStringLiteral("content-type"), QStringLiteral("application/json"));
-    connect(datajob, &KIO::TransferJob::data, d, &Ip::Private::countryData);
-    connect(datajob, &KIO::TransferJob::result, d, &Ip::Private::readCountry);
+    QNetworkRequest locationRequest(QUrl(QStringLiteral("https://location.services.mozilla.com/v1/geolocate?key=%1").arg(apiKey)));
+    locationRequest.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
+    QNetworkReply *locationReply = d->m_nam.post(locationRequest, postData);
+
+    connect(locationReply, &QNetworkReply::finished, this, [this, locationReply] {
+        locationReply->deleteLater();
+        d->readGeoLocation(locationReply);
+    });
+
+    qCDebug(DATAENGINE_GEOLOCATION) << "Fetching https://location.services.mozilla.com/v1/country";
+    QNetworkRequest countryRequest(QUrl(QStringLiteral("https://location.services.mozilla.com/v1/country?key=%1").arg(apiKey)));
+    countryRequest.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
+    QNetworkReply *countryReply = d->m_nam.post(countryRequest, postData);
+
+    connect(countryReply, &QNetworkReply::finished, this, [this, countryReply] {
+        countryReply->deleteLater();
+        d->readCountry(countryReply);
+    });
 }
 
 K_PLUGIN_CLASS_WITH_JSON(Ip, "plasma-geolocation-ip.json")
-- 
GitLab