~mandel/ubuntu-download-manager/properties

« back to all changes in this revision

Viewing changes to src/uploads/priv/ubuntu/uploads/file_upload.cpp

  • Committer: CI bot
  • Author(s): Manuel de la Peña
  • Date: 2014-07-21 09:39:39 UTC
  • mfrom: (304.2.8 write-upload-response)
  • Revision ID: ps-jenkins@lists.canonical.com-20140721093939-grgfcboq0ppb1dmz
On a succesful upload write the response to a secure local path for the client to read. 
Approved by: Sergio Schvezov, PS Jenkins bot

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 * Boston, MA 02110-1301, USA.
17
17
 */
18
18
 
 
19
#include <QDir>
19
20
#include <QFileInfo>
20
21
#include <ubuntu/transfers/system/logger.h>
 
22
#include <ubuntu/transfers/system/filename_mutex.h>
 
23
 
21
24
#include "file_upload.h"
22
25
 
23
 
#define UP_LOG(LEVEL) LOG(LEVEL) << "Upload ID{" << objectName() << "}"
 
26
#define UP_LOG(LEVEL) LOG(LEVEL) << "Upload ID{" << objectName() << " } "
24
27
 
25
28
namespace {
26
29
    const QString CONTENT_TYPE_HEADER = "multipart/form-data;";
29
32
    const QString AUTH_ERROR = "AUTHENTICATION ERROR";
30
33
    const QString PROXY_AUTH_ERROR = "PROXY_AUTHENTICATION ERROR";
31
34
    const QString UNEXPECTED_ERROR = "UNEXPECTED_ERROR";
 
35
    const QString RESPONSE_EXTENSION = ".response";
32
36
}
33
37
 
34
38
namespace Ubuntu {
43
47
               const QString& appId,
44
48
               const QString& path,
45
49
               bool isConfined,
 
50
               const QString& rootPath,
46
51
               const QUrl& url,
47
52
               const QString& filePath,
48
53
               const QVariantMap& metadata,
49
54
               const QMap<QString, QString>& headers,
50
55
               QObject* parent)
51
 
    : Transfer(id, appId, path, isConfined, parent),
 
56
    : Transfer(id, appId, path, isConfined, rootPath, parent),
52
57
      _url(url),
53
58
      _filePath(filePath),
54
59
      _metadata(metadata),
62
67
        setLastError(QString("Path is not absolute: '%1'").arg(filePath));
63
68
    }
64
69
 
65
 
    if (!info.exists()) {
 
70
    if (isValid() && !info.exists()) {
66
71
        UP_LOG(INFO) << "Path does not exist: " << filePath;
67
72
        setIsValid(false);
68
73
        setLastError(QString("Path does not exist: '%1'").arg(filePath));
69
 
    } else {
 
74
    }
 
75
 
 
76
    if (isValid()) {
70
77
        _currentData = FileManager::instance()->createFile(filePath);
71
78
    }
 
79
 
72
80
    _requestFactory = RequestFactory::instance();
73
81
}
74
82
 
109
117
    }
110
118
 
111
119
    // remove current data and metadata
112
 
    cleanUpCurrentData();
113
120
    emit canceled(true);
114
121
}
115
122
 
139
146
 
140
147
    if (!canRead) {
141
148
        emit started(false);
 
149
        return;
142
150
    }
143
151
 
144
152
    _reply = _requestFactory->post(buildRequest(), _currentData);
196
204
}
197
205
 
198
206
void
199
 
FileUpload::cleanUpCurrentData() {
200
 
    bool success = true;
201
 
    QFile::FileError error = QFile::NoError;
202
 
    if (_currentData != nullptr) {
203
 
        success = _currentData->remove();
204
 
 
205
 
        if (!success)
206
 
            error = _currentData->error();
207
 
 
208
 
        _currentData->deleteLater();
209
 
        _currentData = nullptr;
210
 
    }
211
 
 
212
 
    if (!success)
213
 
        UP_LOG(WARNING) << "Error " << error <<
214
 
            "removing file with path" << _filePath;
215
 
}
216
 
 
217
 
void
218
207
FileUpload::connectToReplySignals() {
219
208
    if (_reply != nullptr) {
220
209
        connect(_reply, &NetworkReply::uploadProgress,
248
237
    disconnectFromReplySignals();
249
238
    _reply->deleteLater();
250
239
    _reply = nullptr;
251
 
    cleanUpCurrentData();
252
240
    setState(Transfer::ERROR);
253
241
    emit error(errorStr);
254
242
}
255
243
 
256
244
void
257
 
FileUpload::onUploadProgress(qint64 currentProgress, qint64) {
 
245
FileUpload::onUploadProgress(qint64 currentProgress, qint64 total) {
258
246
    _progress = currentProgress;
259
 
    emit progress(_progress, _currentData->size());
 
247
    emit progress(_progress, total);
260
248
}
261
249
 
262
250
void
263
251
FileUpload::onError(QNetworkReply::NetworkError code) {
264
 
    UP_LOG(ERROR) << _url << " ERROR:" << ":" << code << " " << 
 
252
    UP_LOG(ERROR) << _url << " ERROR:" << ":" << code << " " <<
265
253
        QString(_reply->readAll());
266
254
 
267
255
    QString msg;
301
289
    emitError(errStr);
302
290
}
303
291
 
 
292
QString
 
293
FileUpload::writeResponseToDisk() {
 
294
    QFileInfo fi(_filePath);
 
295
    auto desiredPath = rootPath() + QDir::separator() +
 
296
        fi.fileName() + RESPONSE_EXTENSION;
 
297
    auto responsePath = FileNameMutex::instance()->lockFileName(desiredPath);
 
298
    QScopedPointer<File> f(FileManager::instance()->createFile(responsePath));
 
299
 
 
300
    bool canWrite = f->open(QIODevice::ReadWrite | QFile::Append);
 
301
    if (!canWrite) {
 
302
        emit error("Could not write to response in disk.");
 
303
    }
 
304
 
 
305
    f->write(_reply->readAll());
 
306
    f->close();
 
307
    FileNameMutex::instance()->unlockFileName(desiredPath);
 
308
    return responsePath;
 
309
}
 
310
 
304
311
void
305
312
FileUpload::onFinished() {
306
313
    setState(Transfer::FINISH);
 
314
    // it is important to write the response of the upload to a file for the
 
315
    // client to process it
 
316
    auto path = writeResponseToDisk();
 
317
 
307
318
    UP_LOG(INFO) << "EMIT finished";
308
 
    emit finished();
 
319
    emit finished(path);
309
320
    _reply->deleteLater();
310
321
    _reply = nullptr;
311
322
}