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

source code of kio/src/core/forwardingworkerbase.h