Welcome to mirror list, hosted at ThFree Co, Russian Federation.

abstractcorejob.h « libsync « src - github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 002c9f199fa054f834d8cc06e975bffd4c3b12d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
 * Copyright (C) Hannah von Reth <hannah.vonreth@owncloud.com>
 * Copyright (C) Fabian Müller <fmueller@owncloud.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 */

#pragma once

#include <QNetworkAccessManager>
#include <QNetworkReply>

#include "abstractnetworkjob.h"
#include "owncloudlib.h"

namespace OCC {

/**
 * This class manages an (HTTP) network job's result. It holds a result on success and error details on failures.
 * The class is universally usable for all kinds of network requests, there is no difference in handling the responses.
 * Instead, instances are created that start a suitable request and wire up the signals accordingly.
 * In contrast to the traditional network jobs (e.g., SimpleNetworkJob), core jobs are not bound to an account. Therefore,
 * they can be used with ease in situations where an account object is not available (e.g., the new wizard).
 */
class OWNCLOUDSYNC_EXPORT CoreJob : public QObject
{
    Q_OBJECT

    friend class AbstractCoreJobFactory;

public:
    explicit CoreJob(QObject *parent = nullptr);

    [[nodiscard]] const QVariant &result() const;

    [[nodiscard]] const QString &errorMessage() const;

    [[nodiscard]] QNetworkReply *reply() const;

    [[nodiscard]] bool success() const;

protected:
    /**
     * Set job result. This emits the finished() signal, and marks the job as successful.
     * The job result or error can be set only once.
     * @param result job result
     */
    void setResult(const QVariant &result);

    /**
     * Set job error details. This emits the finished() signal, and marks the job as failed.
     * The job result or error can be set only once.
     * @param errorMessage network error or other suitable error message
     * @param reply reply received from server
     */
    void setError(const QString &errorMessage, QNetworkReply *reply = nullptr);

Q_SIGNALS:
    /**
     * Emitted when a result or error is set. May be emitted once only.
     */
    void finished();

    /**
     * Emitted whenever the user accepts a CA certificate which is not trusted yet using the TlsErrorDialog.
     * Handlers should store the certificate in the access manager passed to the corresponding job.
     * @param caCertificate accepted CA certificate
     */
    void caCertificateAccepted(const QSslCertificate &caCertificate);

private:
    // job result/error should be set only once, because that emits the "finished" signal
    void assertNotFinished();

    bool _success = false;

    QVariant _result;

    QString _errorMessage;
    QNetworkReply *_reply = nullptr;
};


/**
 * Abstract base class for core job factories.
 *
 * Jobs are built by the startJob factory method, which creates a job instance as well as a network request, wires the required signals up, then sends the request.
 */
class OWNCLOUDSYNC_EXPORT AbstractCoreJobFactory : public QObject
{
    Q_OBJECT

public:
    /**
     * Create a new instance
     * @param nam network access manager used to send the requests
     * @param parent optional parent which will be set at this object's parent as well as all jobs' parent.
     */
    explicit AbstractCoreJobFactory(QNetworkAccessManager *nam, QObject *parent = nullptr);
    ~AbstractCoreJobFactory() override;

    /**
     * Send network request and return associated job.
     * @param url URL to send request to
     * @return job
     */
    virtual CoreJob *startJob(const QUrl &url) = 0;

protected:
    [[nodiscard]] QNetworkAccessManager *nam() const;

    /**
     * Set job result. Needed because the jobs' methods are protected, and this class is a friend of Job.
     * The job result or error can be set only once.
     * @param result job result
     */
    static void setJobResult(CoreJob *job, const QVariant &result);

    /**
     * Set job error details. Needed because the jobs' methods are protected, and this class is a friend of Job.
     * @param errorMessage network error or other suitable error message
     * @param networkError network error instance or NoError if the error is not caused by a network issue
     */
    static void setJobError(CoreJob *job, const QString &errorMessage, QNetworkReply *reply);

    /**
     * Factory to create QNetworkRequests with properly set timeout.
     */
    template <typename... Params>
    static QNetworkRequest makeRequest(Params... params)
    {
        auto request = QNetworkRequest(params...);

        const auto timeoutMilliseconds = static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(AbstractNetworkJob::httpTimeout).count());
        request.setTransferTimeout(timeoutMilliseconds);

        return request;
    }

private:
    QNetworkAccessManager *_nam;
};

}