1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtNetwork module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QNETWORKREPLYIMPL_P_H
41#define QNETWORKREPLYIMPL_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists for the convenience
48// of the Network Access API. This header file may change from
49// version to version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <QtNetwork/private/qtnetworkglobal_p.h>
55#include "qnetworkreply.h"
56#include "qnetworkreply_p.h"
57#include "qnetworkaccessmanager.h"
58#include "qnetworkproxy.h"
59#include "QtCore/qmap.h"
60#include "QtCore/qqueue.h"
61#include "QtCore/qbuffer.h"
62#include "private/qringbuffer_p.h"
63#include "private/qbytedata_p.h"
64#include <QSharedPointer>
65#include <QtNetwork/QNetworkSession>
66
67QT_BEGIN_NAMESPACE
68
69class QAbstractNetworkCache;
70class QNetworkAccessBackend;
71
72class QNetworkReplyImplPrivate;
73class QNetworkReplyImpl: public QNetworkReply
74{
75 Q_OBJECT
76public:
77 QNetworkReplyImpl(QObject *parent = nullptr);
78 ~QNetworkReplyImpl();
79 virtual void abort() override;
80
81 // reimplemented from QNetworkReply / QIODevice
82 virtual void close() override;
83 virtual qint64 bytesAvailable() const override;
84 virtual void setReadBufferSize(qint64 size) override;
85
86 virtual qint64 readData(char *data, qint64 maxlen) override;
87 virtual bool event(QEvent *) override;
88
89 Q_DECLARE_PRIVATE(QNetworkReplyImpl)
90 Q_PRIVATE_SLOT(d_func(), void _q_startOperation())
91 Q_PRIVATE_SLOT(d_func(), void _q_copyReadyRead())
92 Q_PRIVATE_SLOT(d_func(), void _q_copyReadChannelFinished())
93 Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData())
94 Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished())
95#ifndef QT_NO_BEARERMANAGEMENT
96 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected())
97 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed())
98 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State))
99 Q_PRIVATE_SLOT(d_func(), void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies))
100#endif
101
102#ifndef QT_NO_SSL
103protected:
104 void sslConfigurationImplementation(QSslConfiguration &configuration) const override;
105 void setSslConfigurationImplementation(const QSslConfiguration &configuration) override;
106 virtual void ignoreSslErrors() override;
107 virtual void ignoreSslErrorsImplementation(const QList<QSslError> &errors) override;
108#endif
109};
110
111class QNetworkReplyImplPrivate: public QNetworkReplyPrivate
112{
113public:
114 enum InternalNotifications {
115 NotifyDownstreamReadyWrite,
116 NotifyCloseDownstreamChannel,
117 NotifyCopyFinished
118 };
119
120 QNetworkReplyImplPrivate();
121
122 void _q_startOperation();
123 void _q_copyReadyRead();
124 void _q_copyReadChannelFinished();
125 void _q_bufferOutgoingData();
126 void _q_bufferOutgoingDataFinished();
127#ifndef QT_NO_BEARERMANAGEMENT
128 void _q_networkSessionConnected();
129 void _q_networkSessionFailed();
130 void _q_networkSessionStateChanged(QNetworkSession::State);
131 void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies);
132#endif
133
134 void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request,
135 QIODevice *outgoingData);
136
137 void pauseNotificationHandling();
138 void resumeNotificationHandling();
139 void backendNotify(InternalNotifications notification);
140 void handleNotifications();
141 void createCache();
142 void completeCacheSave();
143
144 // callbacks from the backend (through the manager):
145 void setCachingEnabled(bool enable);
146 bool isCachingEnabled() const;
147 void consume(qint64 count);
148 void emitUploadProgress(qint64 bytesSent, qint64 bytesTotal);
149 qint64 nextDownstreamBlockSize() const;
150
151 void initCacheSaveDevice();
152 void appendDownstreamDataSignalEmissions();
153 void appendDownstreamData(QByteDataBuffer &data);
154 void appendDownstreamData(QIODevice *data);
155 void appendDownstreamData(const QByteArray &data);
156
157 void setDownloadBuffer(QSharedPointer<char> sp, qint64 size);
158 char* getDownloadBuffer(qint64 size);
159 void appendDownstreamDataDownloadBuffer(qint64, qint64);
160
161 void finished();
162 void error(QNetworkReply::NetworkError code, const QString &errorString);
163 void metaDataChanged();
164 void redirectionRequested(const QUrl &target);
165 void encrypted();
166 void sslErrors(const QList<QSslError> &errors);
167
168 QNetworkAccessBackend *backend;
169 QIODevice *outgoingData;
170 QSharedPointer<QRingBuffer> outgoingDataBuffer;
171 QIODevice *copyDevice;
172 QAbstractNetworkCache *networkCache() const;
173
174 bool migrateBackend();
175
176 bool cacheEnabled;
177 QIODevice *cacheSaveDevice;
178
179 std::vector<InternalNotifications> pendingNotifications;
180 bool notificationHandlingPaused;
181
182 QUrl urlForLastAuthentication;
183#ifndef QT_NO_NETWORKPROXY
184 QNetworkProxy lastProxyAuthentication;
185 QList<QNetworkProxy> proxyList;
186#endif
187
188 qint64 bytesDownloaded;
189 qint64 lastBytesDownloaded;
190 qint64 bytesUploaded;
191 qint64 preMigrationDownloaded;
192
193 QString httpReasonPhrase;
194 int httpStatusCode;
195
196 State state;
197
198 // Only used when the "zero copy" style is used.
199 // Please note that the whole "zero copy" download buffer API is private right now. Do not use it.
200 qint64 downloadBufferReadPosition;
201 qint64 downloadBufferCurrentSize;
202 qint64 downloadBufferMaximumSize;
203 QSharedPointer<char> downloadBufferPointer;
204 char* downloadBuffer;
205
206 Q_DECLARE_PUBLIC(QNetworkReplyImpl)
207};
208Q_DECLARE_TYPEINFO(QNetworkReplyImplPrivate::InternalNotifications, Q_PRIMITIVE_TYPE);
209
210class QDisabledNetworkReply : public QNetworkReply
211{
212 Q_OBJECT
213
214public:
215 QDisabledNetworkReply(QObject *parent, const QNetworkRequest &req,
216 QNetworkAccessManager::Operation op);
217 ~QDisabledNetworkReply();
218
219 void abort() override { }
220protected:
221 qint64 readData(char *, qint64) override { return -1; }
222};
223
224QT_END_NAMESPACE
225
226Q_DECLARE_METATYPE(QSharedPointer<char>)
227
228#endif
229