1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 1999 Torben Weis <weis@kde.org>
4 SPDX-FileCopyrightText: 2000 Waldo Bastain <bastain@kde.org>
5 SPDX-FileCopyrightText: 2000 Dawit Alemayehu <adawit@kde.org>
6 SPDX-FileCopyrightText: 2008 Jarosław Staniek <staniek@kde.org>
7 SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
8
9 SPDX-License-Identifier: LGPL-2.0-only
10*/
11
12#include "kprotocolmanager.h"
13#include "kprotocolinfo_p.h"
14#include "kprotocolmanager_p.h"
15
16#include <config-kiocore.h>
17
18#include <QCoreApplication>
19#include <QUrl>
20
21#include <KConfigGroup>
22#include <KSharedConfig>
23
24#include <kprotocolinfofactory_p.h>
25
26#include "ioworker_defaults.h"
27#include "workerconfig.h"
28
29Q_GLOBAL_STATIC(KProtocolManagerPrivate, kProtocolManagerPrivate)
30
31static void syncOnExit()
32{
33 if (kProtocolManagerPrivate.exists()) {
34 kProtocolManagerPrivate()->sync();
35 }
36}
37
38KProtocolManagerPrivate::KProtocolManagerPrivate()
39{
40 // post routine since KConfig::sync() breaks if called too late
41 qAddPostRoutine(syncOnExit);
42}
43
44KProtocolManagerPrivate::~KProtocolManagerPrivate()
45{
46}
47
48void KProtocolManagerPrivate::sync()
49{
50 QMutexLocker lock(&mutex);
51 if (configPtr) {
52 configPtr->sync();
53 }
54}
55
56void KProtocolManager::reparseConfiguration()
57{
58 KProtocolManagerPrivate *d = kProtocolManagerPrivate();
59 QMutexLocker lock(&d->mutex);
60 if (d->configPtr) {
61 d->configPtr->reparseConfiguration();
62 }
63 lock.unlock();
64
65 // Force the slave config to re-read its config...
66 KIO::WorkerConfig::self()->reset();
67}
68
69static KSharedConfig::Ptr config()
70{
71 KProtocolManagerPrivate *d = kProtocolManagerPrivate();
72 Q_ASSERT(!d->mutex.tryLock()); // the caller must have locked the mutex
73 if (!d->configPtr) {
74 d->configPtr = KSharedConfig::openConfig(QStringLiteral("kioslaverc"), mode: KConfig::NoGlobals);
75 }
76 return d->configPtr;
77}
78
79QMap<QString, QString> KProtocolManager::entryMap(const QString &group)
80{
81 KProtocolManagerPrivate *d = kProtocolManagerPrivate();
82 QMutexLocker lock(&d->mutex);
83 return config()->entryMap(aGroup: group);
84}
85
86/*=============================== TIMEOUT SETTINGS ==========================*/
87
88#if KIOCORE_BUILD_DEPRECATED_SINCE(6, 11)
89int KProtocolManager::readTimeout()
90{
91 KProtocolManagerPrivate *d = kProtocolManagerPrivate();
92 QMutexLocker lock(&d->mutex);
93 KConfigGroup cg(config(), QString());
94 int val = cg.readEntry(key: "ReadTimeout", defaultValue: DEFAULT_READ_TIMEOUT);
95 return qMax(a: MIN_TIMEOUT_VALUE, b: val);
96}
97#endif
98
99#if KIOCORE_BUILD_DEPRECATED_SINCE(6, 11)
100int KProtocolManager::connectTimeout()
101{
102 KProtocolManagerPrivate *d = kProtocolManagerPrivate();
103 QMutexLocker lock(&d->mutex);
104 KConfigGroup cg(config(), QString());
105 int val = cg.readEntry(key: "ConnectTimeout", defaultValue: DEFAULT_CONNECT_TIMEOUT);
106 return qMax(a: MIN_TIMEOUT_VALUE, b: val);
107}
108#endif
109
110#if KIOCORE_BUILD_DEPRECATED_SINCE(6, 11)
111int KProtocolManager::proxyConnectTimeout()
112{
113 KProtocolManagerPrivate *d = kProtocolManagerPrivate();
114 QMutexLocker lock(&d->mutex);
115 KConfigGroup cg(config(), QString());
116 int val = cg.readEntry(key: "ProxyConnectTimeout", defaultValue: DEFAULT_PROXY_CONNECT_TIMEOUT);
117 return qMax(a: MIN_TIMEOUT_VALUE, b: val);
118}
119#endif
120
121#if KIOCORE_BUILD_DEPRECATED_SINCE(6, 11)
122int KProtocolManager::responseTimeout()
123{
124 KProtocolManagerPrivate *d = kProtocolManagerPrivate();
125 QMutexLocker lock(&d->mutex);
126 KConfigGroup cg(config(), QString());
127 int val = cg.readEntry(key: "ResponseTimeout", defaultValue: DEFAULT_RESPONSE_TIMEOUT);
128 return qMax(a: MIN_TIMEOUT_VALUE, b: val);
129}
130#endif
131
132/*==================================== OTHERS ===============================*/
133
134bool KProtocolManager::markPartial()
135{
136 KProtocolManagerPrivate *d = kProtocolManagerPrivate();
137 QMutexLocker lock(&d->mutex);
138 return config()->group(group: QString()).readEntry(key: "MarkPartial", defaultValue: true);
139}
140
141int KProtocolManager::minimumKeepSize()
142{
143 KProtocolManagerPrivate *d = kProtocolManagerPrivate();
144 QMutexLocker lock(&d->mutex);
145 return config()->group(group: QString()).readEntry(key: "MinimumKeepSize",
146 defaultValue: DEFAULT_MINIMUM_KEEP_SIZE); // 5000 byte
147}
148
149bool KProtocolManager::autoResume()
150{
151 KProtocolManagerPrivate *d = kProtocolManagerPrivate();
152 QMutexLocker lock(&d->mutex);
153 return config()->group(group: QString()).readEntry(key: "AutoResume", defaultValue: false);
154}
155
156/* =========================== PROTOCOL CAPABILITIES ============== */
157
158static KProtocolInfoPrivate *findProtocol(const QUrl &url)
159{
160 if (!url.isValid()) {
161 return nullptr;
162 }
163 QString protocol = url.scheme();
164 return KProtocolInfoFactory::self()->findProtocol(protocol);
165}
166
167KProtocolInfo::Type KProtocolManager::inputType(const QUrl &url)
168{
169 KProtocolInfoPrivate *prot = findProtocol(url);
170 if (!prot) {
171 return KProtocolInfo::T_NONE;
172 }
173
174 return prot->m_inputType;
175}
176
177KProtocolInfo::Type KProtocolManager::outputType(const QUrl &url)
178{
179 KProtocolInfoPrivate *prot = findProtocol(url);
180 if (!prot) {
181 return KProtocolInfo::T_NONE;
182 }
183
184 return prot->m_outputType;
185}
186
187bool KProtocolManager::isSourceProtocol(const QUrl &url)
188{
189 KProtocolInfoPrivate *prot = findProtocol(url);
190 if (!prot) {
191 return false;
192 }
193
194 return prot->m_isSourceProtocol;
195}
196
197bool KProtocolManager::supportsListing(const QUrl &url)
198{
199 KProtocolInfoPrivate *prot = findProtocol(url);
200 if (!prot) {
201 return false;
202 }
203
204 return prot->m_supportsListing;
205}
206
207QStringList KProtocolManager::listing(const QUrl &url)
208{
209 KProtocolInfoPrivate *prot = findProtocol(url);
210 if (!prot) {
211 return QStringList();
212 }
213
214 return prot->m_listing;
215}
216
217bool KProtocolManager::supportsReading(const QUrl &url)
218{
219 KProtocolInfoPrivate *prot = findProtocol(url);
220 if (!prot) {
221 return false;
222 }
223
224 return prot->m_supportsReading;
225}
226
227bool KProtocolManager::supportsWriting(const QUrl &url)
228{
229 KProtocolInfoPrivate *prot = findProtocol(url);
230 if (!prot) {
231 return false;
232 }
233
234 return prot->m_supportsWriting;
235}
236
237bool KProtocolManager::supportsMakeDir(const QUrl &url)
238{
239 KProtocolInfoPrivate *prot = findProtocol(url);
240 if (!prot) {
241 return false;
242 }
243
244 return prot->m_supportsMakeDir;
245}
246
247bool KProtocolManager::supportsDeleting(const QUrl &url)
248{
249 KProtocolInfoPrivate *prot = findProtocol(url);
250 if (!prot) {
251 return false;
252 }
253
254 return prot->m_supportsDeleting;
255}
256
257bool KProtocolManager::supportsLinking(const QUrl &url)
258{
259 KProtocolInfoPrivate *prot = findProtocol(url);
260 if (!prot) {
261 return false;
262 }
263
264 return prot->m_supportsLinking;
265}
266
267bool KProtocolManager::supportsMoving(const QUrl &url)
268{
269 KProtocolInfoPrivate *prot = findProtocol(url);
270 if (!prot) {
271 return false;
272 }
273
274 return prot->m_supportsMoving;
275}
276
277bool KProtocolManager::supportsOpening(const QUrl &url)
278{
279 KProtocolInfoPrivate *prot = findProtocol(url);
280 if (!prot) {
281 return false;
282 }
283
284 return prot->m_supportsOpening;
285}
286
287bool KProtocolManager::supportsTruncating(const QUrl &url)
288{
289 KProtocolInfoPrivate *prot = findProtocol(url);
290 if (!prot) {
291 return false;
292 }
293
294 return prot->m_supportsTruncating;
295}
296
297bool KProtocolManager::canCopyFromFile(const QUrl &url)
298{
299 KProtocolInfoPrivate *prot = findProtocol(url);
300 if (!prot) {
301 return false;
302 }
303
304 return prot->m_canCopyFromFile;
305}
306
307bool KProtocolManager::canCopyToFile(const QUrl &url)
308{
309 KProtocolInfoPrivate *prot = findProtocol(url);
310 if (!prot) {
311 return false;
312 }
313
314 return prot->m_canCopyToFile;
315}
316
317bool KProtocolManager::canRenameFromFile(const QUrl &url)
318{
319 KProtocolInfoPrivate *prot = findProtocol(url);
320 if (!prot) {
321 return false;
322 }
323
324 return prot->m_canRenameFromFile;
325}
326
327bool KProtocolManager::canRenameToFile(const QUrl &url)
328{
329 KProtocolInfoPrivate *prot = findProtocol(url);
330 if (!prot) {
331 return false;
332 }
333
334 return prot->m_canRenameToFile;
335}
336
337bool KProtocolManager::canDeleteRecursive(const QUrl &url)
338{
339 KProtocolInfoPrivate *prot = findProtocol(url);
340 if (!prot) {
341 return false;
342 }
343
344 return prot->m_canDeleteRecursive;
345}
346
347KProtocolInfo::FileNameUsedForCopying KProtocolManager::fileNameUsedForCopying(const QUrl &url)
348{
349 KProtocolInfoPrivate *prot = findProtocol(url);
350 if (!prot) {
351 return KProtocolInfo::FromUrl;
352 }
353
354 return prot->m_fileNameUsedForCopying;
355}
356
357QString KProtocolManager::defaultMimetype(const QUrl &url)
358{
359 KProtocolInfoPrivate *prot = findProtocol(url);
360 if (!prot) {
361 return QString();
362 }
363
364 return prot->m_defaultMimetype;
365}
366
367QString KProtocolManager::protocolForArchiveMimetype(const QString &mimeType)
368{
369 KProtocolManagerPrivate *d = kProtocolManagerPrivate();
370 QMutexLocker lock(&d->mutex);
371 if (d->protocolForArchiveMimetypes.isEmpty()) {
372 const QList<KProtocolInfoPrivate *> allProtocols = KProtocolInfoFactory::self()->allProtocols();
373 for (KProtocolInfoPrivate *allProtocol : allProtocols) {
374 const QStringList archiveMimetypes = allProtocol->m_archiveMimeTypes;
375 for (const QString &mime : archiveMimetypes) {
376 d->protocolForArchiveMimetypes.insert(key: mime, value: allProtocol->m_name);
377 }
378 }
379 }
380 return d->protocolForArchiveMimetypes.value(key: mimeType);
381}
382
383QString KProtocolManager::charsetFor(const QUrl &url)
384{
385 return KIO::WorkerConfig::self()->configData(protocol: url.scheme(), host: url.host(), QStringLiteral("Charset"));
386}
387
388bool KProtocolManager::supportsPermissions(const QUrl &url)
389{
390 KProtocolInfoPrivate *prot = findProtocol(url);
391 if (!prot) {
392 return true;
393 }
394
395 return prot->m_supportsPermissions;
396}
397
398#undef PRIVATE_DATA
399
400#include "moc_kprotocolmanager_p.cpp"
401

source code of kio/src/core/kprotocolmanager.cpp