1 | /* |
2 | This file is part of the KDE project |
3 | SPDX-FileCopyrightText: 2004 Kevin Ottens <ervin@ipsquad.net> |
4 | SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-or-later |
7 | */ |
8 | |
9 | #ifndef _FORWARDING_WORKER_BASE_H_ |
10 | #define _FORWARDING_WORKER_BASE_H_ |
11 | |
12 | #include "kiocore_export.h" |
13 | #include <kio/workerbase.h> |
14 | |
15 | #include <QObject> |
16 | |
17 | #include <memory> |
18 | |
19 | namespace KIO |
20 | { |
21 | class ForwardingWorkerBasePrivate; |
22 | |
23 | /** |
24 | * @class KIO::ForwardingWorkerBase forwardingworkerbase.h <KIO/ForwardingWorkerBase> |
25 | * |
26 | * This class should be used as a base for KIO workers acting as a |
27 | * forwarder to other KIO workers. It has been designed to support only |
28 | * local filesystem like KIO workers. |
29 | * |
30 | * If the resulting KIO worker should be a simple proxy, you only need |
31 | * to implement the ForwardingWorkerBase::rewriteUrl() method. |
32 | * |
33 | * For more advanced behavior, the classic KIO worker methods should |
34 | * be reimplemented, because their default behavior in this class |
35 | * is to forward using the ForwardingWorkerBase::rewriteUrl() method. |
36 | * |
37 | * A possible code snippet for an advanced stat() behavior would look |
38 | * like this in the child class: |
39 | * |
40 | * \code |
41 | * WorkerResult ChildProtocol::stat(const QUrl &url) |
42 | * { |
43 | * bool is_special = false; |
44 | * |
45 | * // Process the URL to see if it should have |
46 | * // a special treatment |
47 | * |
48 | * if (is_special) { |
49 | * // Handle the URL ourselves |
50 | * KIO::UDSEntry entry; |
51 | * // Fill entry with values |
52 | * statEntry(entry); |
53 | * return WorkerResult::pass(); |
54 | * } |
55 | * // Setup the KIO worker internal state if |
56 | * // required by ChildProtocol::rewriteUrl() |
57 | * return ForwardingWorkerBase::stat(url); |
58 | * } |
59 | * \endcode |
60 | * |
61 | * Of course in this case, you surely need to reimplement listDir() |
62 | * and get() accordingly. |
63 | * |
64 | * If you want view on directories to be correctly refreshed when |
65 | * something changes on a forwarded URL, you'll need a companion kded |
66 | * module to emit the KDirNotify Files*() D-Bus signals. |
67 | * |
68 | * @see ForwardingWorkerBase::rewriteUrl() |
69 | * @author Kevin Ottens <ervin@ipsquad.net> |
70 | * @since 5.101 |
71 | */ |
72 | class KIOCORE_EXPORT ForwardingWorkerBase : public QObject, public WorkerBase |
73 | { |
74 | Q_OBJECT |
75 | public: |
76 | ForwardingWorkerBase(const QByteArray &protocol, const QByteArray &poolSocket, const QByteArray &appSocket); |
77 | ~ForwardingWorkerBase() override; |
78 | Q_DISABLE_COPY_MOVE(ForwardingWorkerBase) |
79 | |
80 | WorkerResult get(const QUrl &url) override; |
81 | WorkerResult put(const QUrl &url, int permissions, JobFlags flags) override; |
82 | WorkerResult stat(const QUrl &url) override; |
83 | WorkerResult mimetype(const QUrl &url) override; |
84 | WorkerResult listDir(const QUrl &url) override; |
85 | WorkerResult mkdir(const QUrl &url, int permissions) override; |
86 | WorkerResult rename(const QUrl &src, const QUrl &dest, JobFlags flags) override; |
87 | WorkerResult symlink(const QString &target, const QUrl &dest, JobFlags flags) override; |
88 | WorkerResult chmod(const QUrl &url, int permissions) override; |
89 | WorkerResult setModificationTime(const QUrl &url, const QDateTime &mtime) override; |
90 | WorkerResult copy(const QUrl &src, const QUrl &dest, int permissions, JobFlags flags) override; |
91 | WorkerResult del(const QUrl &url, bool isfile) override; |
92 | |
93 | protected: |
94 | /** |
95 | * Rewrite an url to its forwarded counterpart. It should return |
96 | * true if everything was ok, and false otherwise. |
97 | * |
98 | * If a problem is detected it's up to this method to trigger error() |
99 | * before returning. Returning false silently cancels the current |
100 | * KIO worker operation. |
101 | * |
102 | * @param url The URL as given during the KIO worker call |
103 | * @param newURL The new URL to forward the KIO worker call to |
104 | * @return true if the given url could be correctly rewritten |
105 | */ |
106 | virtual bool rewriteUrl(const QUrl &url, QUrl &newURL) = 0; |
107 | |
108 | enum UDSEntryCreationMode { |
109 | UDSEntryCreationInStat, ///< The entry is created during a stat operation. |
110 | UDSEntryCreationInListDir, ///< The entry is created during a listDir operation. |
111 | }; |
112 | |
113 | /** |
114 | * Adjusts a UDSEntry before it's sent in the reply to the KIO worker endpoint. |
115 | * This is the default implementation working in most cases, but sometimes |
116 | * you could make use of more forwarding black magic (for example |
117 | * dynamically transform any desktop file into a fake directory...) |
118 | * |
119 | * @param entry the UDSEntry to adjust |
120 | * @param creationMode the operation for which this entry is created |
121 | */ |
122 | virtual void adjustUDSEntry(KIO::UDSEntry &entry, UDSEntryCreationMode creationMode) const; |
123 | |
124 | /** |
125 | * Return the URL being processed by the KIO worker |
126 | * Only access it inside adjustUDSEntry() |
127 | */ |
128 | QUrl processedUrl() const; |
129 | |
130 | /** |
131 | * Return the URL asked to the KIO worker |
132 | * Only access it inside adjustUDSEntry() |
133 | */ |
134 | QUrl requestedUrl() const; |
135 | |
136 | private: |
137 | Q_PRIVATE_SLOT(d, void _k_slotRedirection(KIO::Job *, QUrl)) |
138 | friend class ForwardingWorkerBasePrivate; |
139 | std::unique_ptr<ForwardingWorkerBasePrivate> const d; |
140 | }; |
141 | |
142 | } // namespace KIO |
143 | |
144 | #endif |
145 | |