1 /*
2     This file is part of the KDE libraries
3     SPDX-FileCopyrightText: 2000 Stephan Kulow <coolo@kde.org>
4     SPDX-FileCopyrightText: 2000-2013 David Faure <faure@kde.org>
5 
6     SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 
9 #ifndef KIO_TRANSFERJOB_H
10 #define KIO_TRANSFERJOB_H
11 
12 #include "simplejob.h"
13 
14 namespace KIO
15 {
16 class TransferJobPrivate;
17 /**
18  * @class KIO::TransferJob transferjob.h <KIO/TransferJob>
19  *
20  * The transfer job pumps data into and/or out of a Slave.
21  * Data is sent to the slave on request of the slave ( dataReq).
22  * If data coming from the slave can not be handled, the
23  * reading of data from the slave should be suspended.
24  */
25 class KIOCORE_EXPORT TransferJob : public SimpleJob
26 {
27     Q_OBJECT
28 
29 public:
30     ~TransferJob() override;
31 
32     /**
33      * Sets the modification time of the file to be created (by KIO::put)
34      * Note that some kioslaves might ignore this.
35      */
36     void setModificationTime(const QDateTime &mtime);
37 
38     /**
39      * Checks whether we got an error page. This currently only happens
40      * with HTTP urls. Call this from your slot connected to result().
41      *
42      * @return true if we got an (HTML) error page from the server
43      * instead of what we asked for.
44      */
45     bool isErrorPage() const;
46 
47     /**
48      * Enable the async data mode.
49      * When async data is enabled, data should be provided to the job by
50      * calling sendAsyncData() instead of returning data in the
51      * dataReq() signal.
52      */
53     void setAsyncDataEnabled(bool enabled);
54 
55     /**
56      * Provide data to the job when async data is enabled.
57      * Should be called exactly once after receiving a dataReq signal
58      * Sending an empty block indicates end of data.
59      */
60     void sendAsyncData(const QByteArray &data);
61 
62 #if KIOCORE_ENABLE_DEPRECATED_SINCE(4, 3)
63     /**
64      * When enabled, the job reports the amount of data that has been sent,
65      * instead of the amount of data that has been received.
66      * @see slotProcessedSize
67      * @see slotSpeed
68      * @deprecated since 4.2.1, this is unnecessary (it is always false for
69      *             KIO::get and true for KIO::put)
70      */
71     KIOCORE_DEPRECATED_VERSION(4, 3, "No longer needed")
72     void setReportDataSent(bool enabled);
73 #endif
74 
75 #if KIOCORE_ENABLE_DEPRECATED_SINCE(4, 3)
76     /**
77      *  Returns whether the job reports the amount of data that has been
78      *  sent (true), or whether the job reports the amount of data that
79      * has been received (false)
80      * @deprecated since 4.2.1, this is unnecessary (it is always false for
81      *             KIO::get and true for KIO::put)
82      */
83     KIOCORE_DEPRECATED_VERSION(4, 3, "No longer needed")
84     bool reportDataSent() const;
85 #endif
86 
87     /**
88      * Call this in the slot connected to result,
89      * and only after making sure no error happened.
90      * @return the MIME type of the URL
91      */
92     QString mimetype() const;
93 
94     /**
95      * After the job has finished, it will return the final url in case a redirection
96      * has happened.
97      * @return the final url that can be empty in case no redirection has happened.
98      * @since 5.0
99      */
100     QUrl redirectUrl() const;
101 
102     /**
103      * Set the total size of data that we are going to send
104      * in a put job. Helps getting proper progress information.
105      * @since 4.2.1
106      */
107     void setTotalSize(KIO::filesize_t bytes);
108 
109 protected:
110     /**
111      * Called when m_subJob finishes.
112      * @param job the job that finished
113      */
114     void slotResult(KJob *job) override;
115 
116     /**
117      * Reimplemented for internal reasons
118      */
119     bool doResume() override;
120 
121 Q_SIGNALS:
122     /**
123      * Data from the slave has arrived.
124      * @param job the job that emitted this signal
125      * @param data data received from the slave.
126      *
127      * End of data (EOD) has been reached if data.size() == 0, however, you
128      * should not be certain of data.size() == 0 ever happening (e.g. in case
129      * of an error), so you should rely on result() instead.
130      */
131     void data(KIO::Job *job, const QByteArray &data);
132 
133     /**
134      * Request for data.
135      * Please note, that you shouldn't put too large chunks
136      * of data in it as this requires copies within the frame
137      * work, so you should rather split the data you want
138      * to pass here in reasonable chunks (about 1MB maximum)
139      *
140      * @param job the job that emitted this signal
141      * @param data buffer to fill with data to send to the
142      * slave. An empty buffer indicates end of data. (EOD)
143      */
144     void dataReq(KIO::Job *job, QByteArray &data);
145 
146     /**
147      * Signals a redirection.
148      * Use to update the URL shown to the user.
149      * The redirection itself is handled internally.
150      * @param job the job that emitted this signal
151      * @param url the new URL
152      */
153     void redirection(KIO::Job *job, const QUrl &url);
154 
155     /**
156      * Signals a permanent redirection.
157      * The redirection itself is handled internally.
158      * @param job the job that emitted this signal
159      * @param fromUrl the original URL
160      * @param toUrl the new URL
161      */
162     void permanentRedirection(KIO::Job *job, const QUrl &fromUrl, const QUrl &toUrl);
163 
164 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 78)
165     /**
166      * MIME type determined.
167      * @param job the job that emitted this signal
168      * @param mimeType the MIME type
169      * @deprecated Since 5.78, use mimeTypeFound(KIO::Job *, const QString &)
170      */
171     KIOCORE_DEPRECATED_VERSION(5, 78, "Use KIO::TransferJob::mimeTypeFound(KIO::Job *, const QString &)")
172     void mimetype(KIO::Job *job, const QString &mimeType); // clazy:exclude=overloaded-signal
173 #endif
174 
175     /**
176      * MIME type determined.
177      * @param job the job that emitted this signal
178      * @param mimeType the MIME type
179      * @since 5.78
180      */
181     void mimeTypeFound(KIO::Job *job, const QString &mimeType);
182 
183     /**
184      * @internal
185      * Emitted if the "put" job found an existing partial file
186      * (in which case offset is the size of that file)
187      * and emitted by the "get" job if it supports resuming to
188      * the given offset - in this case @p offset is unused)
189      */
190     void canResume(KIO::Job *job, KIO::filesize_t offset);
191 
192 protected Q_SLOTS:
193     virtual void slotRedirection(const QUrl &url);
194     void slotFinished() override;
195     virtual void slotData(const QByteArray &data);
196     virtual void slotDataReq();
197     virtual void slotMimetype(const QString &mimetype);
198     void slotMetaData(const KIO::MetaData &_metaData) override;
199 
200 protected:
201     TransferJob(TransferJobPrivate &dd);
202 
203 private:
204     Q_PRIVATE_SLOT(d_func(), void slotPostRedirection())
205     Q_PRIVATE_SLOT(d_func(), void slotIODeviceClosed())
206     Q_PRIVATE_SLOT(d_func(), void slotIODeviceClosedBeforeStart())
207     Q_DECLARE_PRIVATE(TransferJob)
208 
209     // A FileCopyJob may control one or more TransferJobs
210     friend class FileCopyJob;
211     friend class FileCopyJobPrivate;
212 };
213 
214 /**
215  * Get (means: read).
216  * This is the job to use in order to "download" a file into memory.
217  * The slave emits the data through the data() signal.
218  *
219  * Special case: if you want to determine the MIME type of the file first,
220  * and then read it with the appropriate component, you can still use
221  * a KIO::get() directly. When that job emits the mimeType signal, (which is
222  * guaranteed to happen before it emits any data), put the job on hold:
223  *
224  * @code
225  *   job->putOnHold();
226  *   KIO::Scheduler::publishSlaveOnHold();
227  * @endcode
228  *
229  * and forget about the job. The next time someone does a KIO::get() on the
230  * same URL (even in another process) this job will be resumed. This saves KIO
231  * from doing two requests to the server.
232  *
233  * @param url the URL of the file
234  * @param reload Reload to reload the file, NoReload if it can be taken from the cache
235  * @param flags Can be HideProgressInfo here
236  * @return the job handling the operation.
237  */
238 KIOCORE_EXPORT TransferJob *get(const QUrl &url, LoadType reload = NoReload, JobFlags flags = DefaultFlags);
239 
240 /**
241  * Put (means: write)
242  *
243  * @param url Where to write data.
244  * @param permissions May be -1. In this case no special permission mode is set.
245  * @param flags Can be HideProgressInfo, Overwrite and Resume here. WARNING:
246  * Setting Resume means that the data will be appended to @p dest if @p dest exists.
247  * @return the job handling the operation.
248  * @see multi_get()
249  */
250 KIOCORE_EXPORT TransferJob *put(const QUrl &url, int permissions, JobFlags flags = DefaultFlags);
251 
252 /**
253  * HTTP POST (for form data).
254  *
255  * Example:
256  * \code
257  *    job = KIO::http_post( url, postData, KIO::HideProgressInfo );
258  *    job->addMetaData("content-type", contentType );
259  *    job->addMetaData("referrer", referrerURL);
260  * \endcode
261  *
262  * @p postData is the data that you want to send and
263  * @p contentType is the complete HTTP header line that
264  * specifies the content's MIME type, for example
265  * "Content-Type: text/xml".
266  *
267  * You MUST specify content-type!
268  *
269  * Often @p contentType is
270  * "Content-Type: application/x-www-form-urlencoded" and
271  * the @p postData is then an ASCII string (without null-termination!)
272  * with characters like space, linefeed and percent escaped like %20,
273  * %0A and %25.
274  *
275  * @param url Where to write the data.
276  * @param postData Encoded data to post.
277  * @param flags Can be HideProgressInfo here
278  * @return the job handling the operation.
279  */
280 KIOCORE_EXPORT TransferJob *http_post(const QUrl &url, const QByteArray &postData, JobFlags flags = DefaultFlags);
281 
282 /**
283  * HTTP POST.
284  *
285  * This function, unlike the one that accepts a QByteArray, accepts an IO device
286  * from which to read the encoded data to be posted to the server in order to
287  * to avoid holding the content of very large post requests, e.g. multimedia file
288  * uploads, in memory.
289  *
290  * @param url Where to write the data.
291  * @param device the device to read from
292  * @param size Size of the encoded post data.
293  * @param flags Can be HideProgressInfo here
294  * @return the job handling the operation.
295  *
296  * @since 4.7
297  */
298 KIOCORE_EXPORT TransferJob *http_post(const QUrl &url, QIODevice *device, qint64 size = -1, JobFlags flags = DefaultFlags);
299 
300 /**
301  * HTTP DELETE.
302  *
303  * Though this function servers the same purpose as KIO::file_delete, unlike
304  * file_delete it accommodates HTTP specific actions such as redirections.
305  *
306  * @param url url resource to delete.
307  * @param flags Can be HideProgressInfo here
308  * @return the job handling the operation.
309  *
310  * @since 4.7.3
311  */
312 KIOCORE_EXPORT TransferJob *http_delete(const QUrl &url, JobFlags flags = DefaultFlags);
313 
314 }
315 
316 #endif
317