File indexing completed on 2024-12-01 03:40:37

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2004 Kevin Ottens <ervin@ipsquad.net>
0004     SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef _FORWARDING_WORKER_BASE_H_
0010 #define _FORWARDING_WORKER_BASE_H_
0011 
0012 #include "kiocore_export.h"
0013 #include <kio/workerbase.h>
0014 
0015 #include <QObject>
0016 
0017 #include <memory>
0018 
0019 namespace KIO
0020 {
0021 class ForwardingWorkerBasePrivate;
0022 
0023 /**
0024  * @class KIO::ForwardingWorkerBase forwardingworkerbase.h <KIO/ForwardingWorkerBase>
0025  *
0026  * This class should be used as a base for KIO workers acting as a
0027  * forwarder to other KIO workers. It has been designed to support only
0028  * local filesystem like KIO workers.
0029  *
0030  * If the resulting KIO worker should be a simple proxy, you only need
0031  * to implement the ForwardingWorkerBase::rewriteUrl() method.
0032  *
0033  * For more advanced behavior, the classic KIO worker methods should
0034  * be reimplemented, because their default behavior in this class
0035  * is to forward using the ForwardingWorkerBase::rewriteUrl() method.
0036  *
0037  * A possible code snippet for an advanced stat() behavior would look
0038  * like this in the child class:
0039  *
0040  * \code
0041  *     WorkerResult ChildProtocol::stat(const QUrl &url)
0042  *     {
0043  *         bool is_special = false;
0044  *
0045  *         // Process the URL to see if it should have
0046  *         // a special treatment
0047  *
0048  *         if (is_special) {
0049  *             // Handle the URL ourselves
0050  *             KIO::UDSEntry entry;
0051  *             // Fill entry with values
0052  *             statEntry(entry);
0053  *             return WorkerResult::pass();
0054  *         }
0055  *         // Setup the KIO worker internal state if
0056  *         // required by ChildProtocol::rewriteUrl()
0057  *         return ForwardingWorkerBase::stat(url);
0058  *     }
0059  * \endcode
0060  *
0061  * Of course in this case, you surely need to reimplement listDir()
0062  * and get() accordingly.
0063  *
0064  * If you want view on directories to be correctly refreshed when
0065  * something changes on a forwarded URL, you'll need a companion kded
0066  * module to emit the KDirNotify Files*() D-Bus signals.
0067  *
0068  * @see ForwardingWorkerBase::rewriteUrl()
0069  * @author Kevin Ottens <ervin@ipsquad.net>
0070  * @since 5.101
0071  */
0072 class KIOCORE_EXPORT ForwardingWorkerBase : public QObject, public WorkerBase
0073 {
0074     Q_OBJECT
0075 public:
0076     ForwardingWorkerBase(const QByteArray &protocol, const QByteArray &poolSocket, const QByteArray &appSocket);
0077     ~ForwardingWorkerBase() override;
0078     Q_DISABLE_COPY_MOVE(ForwardingWorkerBase)
0079 
0080     WorkerResult get(const QUrl &url) override;
0081     WorkerResult put(const QUrl &url, int permissions, JobFlags flags) override;
0082     WorkerResult stat(const QUrl &url) override;
0083     WorkerResult mimetype(const QUrl &url) override;
0084     WorkerResult listDir(const QUrl &url) override;
0085     WorkerResult mkdir(const QUrl &url, int permissions) override;
0086     WorkerResult rename(const QUrl &src, const QUrl &dest, JobFlags flags) override;
0087     WorkerResult symlink(const QString &target, const QUrl &dest, JobFlags flags) override;
0088     WorkerResult chmod(const QUrl &url, int permissions) override;
0089     WorkerResult setModificationTime(const QUrl &url, const QDateTime &mtime) override;
0090     WorkerResult copy(const QUrl &src, const QUrl &dest, int permissions, JobFlags flags) override;
0091     WorkerResult del(const QUrl &url, bool isfile) override;
0092 
0093 protected:
0094     /**
0095      * Rewrite an url to its forwarded counterpart. It should return
0096      * true if everything was ok, and false otherwise.
0097      *
0098      * If a problem is detected it's up to this method to trigger error()
0099      * before returning. Returning false silently cancels the current
0100      * KIO worker operation.
0101      *
0102      * @param url The URL as given during the KIO worker call
0103      * @param newURL The new URL to forward the KIO worker call to
0104      * @return true if the given url could be correctly rewritten
0105      */
0106     virtual bool rewriteUrl(const QUrl &url, QUrl &newURL) = 0;
0107 
0108     enum UDSEntryCreationMode {
0109         UDSEntryCreationInStat, ///< The entry is created during a stat operation.
0110         UDSEntryCreationInListDir, ///<  The entry is created during a listDir operation.
0111     };
0112 
0113     /**
0114      * Adjusts a UDSEntry before it's sent in the reply to the KIO worker endpoint.
0115      * This is the default implementation working in most cases, but sometimes
0116      * you could make use of more forwarding black magic (for example
0117      * dynamically transform any desktop file into a fake directory...)
0118      *
0119      * @param entry the UDSEntry to adjust
0120      * @param creationMode the operation for which this entry is created
0121      */
0122     virtual void adjustUDSEntry(KIO::UDSEntry &entry, UDSEntryCreationMode creationMode) const;
0123 
0124     /**
0125      * Return the URL being processed by the KIO worker
0126      * Only access it inside adjustUDSEntry()
0127      */
0128     QUrl processedUrl() const;
0129 
0130     /**
0131      * Return the URL asked to the KIO worker
0132      * Only access it inside adjustUDSEntry()
0133      */
0134     QUrl requestedUrl() const;
0135 
0136 private:
0137     Q_PRIVATE_SLOT(d, void _k_slotRedirection(KIO::Job *, QUrl))
0138     friend class ForwardingWorkerBasePrivate;
0139     std::unique_ptr<ForwardingWorkerBasePrivate> const d;
0140 };
0141 
0142 } // namespace KIO
0143 
0144 #endif