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 QHTTPNETWORKCONNECTIONCHANNEL_H
41#define QHTTPNETWORKCONNECTIONCHANNEL_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 <QtNetwork/qnetworkrequest.h>
56#include <QtNetwork/qnetworkreply.h>
57#include <QtNetwork/qabstractsocket.h>
58
59#include <private/qobject_p.h>
60#include <qauthenticator.h>
61#include <qnetworkproxy.h>
62#include <qbuffer.h>
63
64#include <private/qhttpnetworkheader_p.h>
65#include <private/qhttpnetworkrequest_p.h>
66#include <private/qhttpnetworkreply_p.h>
67
68#include <private/qhttpnetworkconnection_p.h>
69#include <private/qabstractprotocolhandler_p.h>
70
71#ifndef QT_NO_SSL
72# include <QtNetwork/qsslsocket.h>
73# include <QtNetwork/qsslerror.h>
74# include <QtNetwork/qsslconfiguration.h>
75#else
76# include <QtNetwork/qtcpsocket.h>
77#endif
78
79#include <QtCore/qscopedpointer.h>
80
81QT_REQUIRE_CONFIG(http);
82
83QT_BEGIN_NAMESPACE
84
85class QHttpNetworkRequest;
86class QHttpNetworkReply;
87class QByteArray;
88
89#ifndef HttpMessagePair
90typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair;
91#endif
92
93class QHttpNetworkConnectionChannel : public QObject {
94 Q_OBJECT
95public:
96 // TODO: Refactor this to add an EncryptingState (and remove pendingEncrypt).
97 // Also add an Unconnected state so IdleState does not have double meaning.
98 enum ChannelState {
99 IdleState = 0, // ready to send request
100 ConnectingState = 1, // connecting to host
101 WritingState = 2, // writing the data
102 WaitingState = 4, // waiting for reply
103 ReadingState = 8, // reading the reply
104 ClosingState = 16,
105 BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|ClosingState)
106 };
107 QAbstractSocket *socket;
108 bool ssl;
109 bool isInitialized;
110 ChannelState state;
111 QHttpNetworkRequest request; // current request, only used for HTTP
112 QHttpNetworkReply *reply; // current reply for this request, only used for HTTP
113 qint64 written;
114 qint64 bytesTotal;
115 bool resendCurrent;
116 int lastStatus; // last status received on this channel
117 bool pendingEncrypt; // for https (send after encrypted)
118 int reconnectAttempts; // maximum 2 reconnection attempts
119 QAuthenticatorPrivate::Method authMethod;
120 QAuthenticatorPrivate::Method proxyAuthMethod;
121 QAuthenticator authenticator;
122 QAuthenticator proxyAuthenticator;
123 bool authenticationCredentialsSent;
124 bool proxyCredentialsSent;
125 QScopedPointer<QAbstractProtocolHandler> protocolHandler;
126 // SPDY or HTTP/2 requests; SPDY is TLS-only, but
127 // HTTP/2 can be cleartext also, that's why it's
128 // outside of QT_NO_SSL section. Sorted by priority:
129 QMultiMap<int, HttpMessagePair> spdyRequestsToSend;
130 bool switchedToHttp2 = false;
131#ifndef QT_NO_SSL
132 bool ignoreAllSslErrors;
133 QList<QSslError> ignoreSslErrorsList;
134 QScopedPointer<QSslConfiguration> sslConfiguration;
135 void ignoreSslErrors();
136 void ignoreSslErrors(const QList<QSslError> &errors);
137 void setSslConfiguration(const QSslConfiguration &config);
138 void requeueSpdyRequests(); // when we wanted SPDY but got HTTP
139#endif
140 // to emit the signal for all in-flight replies:
141 void emitFinishedWithError(QNetworkReply::NetworkError error, const char *message);
142#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section
143 QSharedPointer<QNetworkSession> networkSession;
144#endif
145
146 // HTTP pipelining -> http://en.wikipedia.org/wiki/Http_pipelining
147 enum PipeliningSupport {
148 PipeliningSupportUnknown, // default for a new connection
149 PipeliningProbablySupported, // after having received a server response that indicates support
150 PipeliningNotSupported // currently not used
151 };
152 PipeliningSupport pipeliningSupported;
153 QList<HttpMessagePair> alreadyPipelinedRequests;
154 QByteArray pipeline; // temporary buffer that gets sent to socket in pipelineFlush
155 void pipelineInto(HttpMessagePair &pair);
156 void pipelineFlush();
157 void requeueCurrentlyPipelinedRequests();
158 void detectPipeliningSupport();
159
160 QHttpNetworkConnectionChannel();
161
162 QAbstractSocket::NetworkLayerProtocol networkLayerPreference;
163
164 void setConnection(QHttpNetworkConnection *c);
165 QPointer<QHttpNetworkConnection> connection;
166
167#ifndef QT_NO_NETWORKPROXY
168 QNetworkProxy proxy;
169 void setProxy(const QNetworkProxy &networkProxy);
170#endif
171
172 void init();
173 void close();
174 void abort();
175
176 bool sendRequest();
177 void sendRequestDelayed();
178
179 bool ensureConnection();
180
181 void allDone(); // reply header + body have been read
182 void handleStatus(); // called from allDone()
183
184 bool resetUploadData(); // return true if resetting worked or there is no upload data
185
186 void handleUnexpectedEOF();
187 void closeAndResendCurrentRequest();
188 void resendCurrentRequest();
189
190 bool isSocketBusy() const;
191 bool isSocketWriting() const;
192 bool isSocketWaiting() const;
193 bool isSocketReading() const;
194
195 protected slots:
196 void _q_receiveReply();
197 void _q_bytesWritten(qint64 bytes); // proceed sending
198 void _q_readyRead(); // pending data to read
199 void _q_disconnected(); // disconnected from host
200 void _q_connected(); // start sending request
201 void _q_error(QAbstractSocket::SocketError); // error from socket
202#ifndef QT_NO_NETWORKPROXY
203 void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy
204#endif
205
206 void _q_uploadDataReadyRead();
207
208#ifndef QT_NO_SSL
209 void _q_encrypted(); // start sending request (https)
210 void _q_sslErrors(const QList<QSslError> &errors); // ssl errors from the socket
211 void _q_preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*); // tls-psk auth necessary
212 void _q_encryptedBytesWritten(qint64 bytes); // proceed sending
213#endif
214
215 friend class QHttpProtocolHandler;
216};
217
218QT_END_NAMESPACE
219
220#endif
221

source code of qtbase/src/network/access/qhttpnetworkconnectionchannel_p.h