1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QHTTPNETWORKCONNECTIONCHANNEL_H
5#define QHTTPNETWORKCONNECTIONCHANNEL_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of the Network Access API. This header file may change from
13// version to version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtNetwork/private/qtnetworkglobal_p.h>
19#include <QtNetwork/qnetworkrequest.h>
20#include <QtNetwork/qnetworkreply.h>
21#include <QtNetwork/qabstractsocket.h>
22
23#include <private/qobject_p.h>
24#include <qauthenticator.h>
25#include <qnetworkproxy.h>
26#include <qbuffer.h>
27
28#include <private/qhttpnetworkheader_p.h>
29#include <private/qhttpnetworkrequest_p.h>
30#include <private/qhttpnetworkreply_p.h>
31
32#include <private/qhttpnetworkconnection_p.h>
33#include <private/qabstractprotocolhandler_p.h>
34
35#ifndef QT_NO_SSL
36# include <QtNetwork/qsslsocket.h>
37# include <QtNetwork/qsslerror.h>
38# include <QtNetwork/qsslconfiguration.h>
39#else
40# include <QtNetwork/qtcpsocket.h>
41#endif
42#if QT_CONFIG(localserver)
43# include <QtNetwork/qlocalsocket.h>
44#endif
45
46
47#include <QtCore/qpointer.h>
48#include <QtCore/qscopedpointer.h>
49
50#include <memory>
51
52QT_REQUIRE_CONFIG(http);
53
54QT_BEGIN_NAMESPACE
55
56class QHttpNetworkRequest;
57class QHttpNetworkReply;
58class QByteArray;
59
60#ifndef HttpMessagePair
61typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair;
62#endif
63
64class QHttpNetworkConnectionChannel : public QObject {
65 Q_OBJECT
66public:
67 // TODO: Refactor this to add an EncryptingState (and remove pendingEncrypt).
68 // Also add an Unconnected state so IdleState does not have double meaning.
69 enum ChannelState {
70 IdleState = 0, // ready to send request
71 ConnectingState = 1, // connecting to host
72 WritingState = 2, // writing the data
73 WaitingState = 4, // waiting for reply
74 ReadingState = 8, // reading the reply
75 ClosingState = 16,
76 BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|ClosingState)
77 };
78 QIODevice *socket;
79 bool ssl;
80 bool isInitialized;
81 bool waitingForPotentialAbort = false;
82 bool needInvokeReceiveReply = false;
83 bool needInvokeReadyRead = false;
84 bool needInvokeSendRequest = false;
85 ChannelState state;
86 QHttpNetworkRequest request; // current request, only used for HTTP
87 QHttpNetworkReply *reply; // current reply for this request, only used for HTTP
88 qint64 written;
89 qint64 bytesTotal;
90 bool resendCurrent;
91 int lastStatus; // last status received on this channel
92 bool pendingEncrypt; // for https (send after encrypted)
93 int reconnectAttempts; // maximum 2 reconnection attempts
94 QAuthenticator authenticator;
95 QAuthenticator proxyAuthenticator;
96 bool authenticationCredentialsSent;
97 bool proxyCredentialsSent;
98 std::unique_ptr<QAbstractProtocolHandler> protocolHandler;
99 QMultiMap<int, HttpMessagePair> h2RequestsToSend;
100 bool switchedToHttp2 = false;
101#ifndef QT_NO_SSL
102 bool ignoreAllSslErrors;
103 QList<QSslError> ignoreSslErrorsList;
104 QScopedPointer<QSslConfiguration> sslConfiguration;
105 void ignoreSslErrors();
106 void ignoreSslErrors(const QList<QSslError> &errors);
107 void setSslConfiguration(const QSslConfiguration &config);
108 void requeueHttp2Requests(); // when we wanted HTTP/2 but got HTTP/1.1
109#endif
110 // to emit the signal for all in-flight replies:
111 void emitFinishedWithError(QNetworkReply::NetworkError error, const char *message);
112
113 // HTTP pipelining -> http://en.wikipedia.org/wiki/Http_pipelining
114 enum PipeliningSupport {
115 PipeliningSupportUnknown, // default for a new connection
116 PipeliningProbablySupported, // after having received a server response that indicates support
117 PipeliningNotSupported // currently not used
118 };
119 PipeliningSupport pipeliningSupported;
120 QList<HttpMessagePair> alreadyPipelinedRequests;
121 QByteArray pipeline; // temporary buffer that gets sent to socket in pipelineFlush
122 void pipelineInto(HttpMessagePair &pair);
123 void pipelineFlush();
124 void requeueCurrentlyPipelinedRequests();
125 void detectPipeliningSupport();
126
127 QHttpNetworkConnectionChannel();
128
129 QAbstractSocket::NetworkLayerProtocol networkLayerPreference;
130
131 void setConnection(QHttpNetworkConnection *c);
132 QPointer<QHttpNetworkConnection> connection;
133
134#ifndef QT_NO_NETWORKPROXY
135 QNetworkProxy proxy;
136 void setProxy(const QNetworkProxy &networkProxy);
137#endif
138
139 void init();
140 void close();
141 void abort();
142
143 bool sendRequest();
144 void sendRequestDelayed();
145
146 bool ensureConnection();
147
148 void allDone(); // reply header + body have been read
149 void handleStatus(); // called from allDone()
150
151 bool resetUploadData(); // return true if resetting worked or there is no upload data
152
153 void handleUnexpectedEOF();
154 void closeAndResendCurrentRequest();
155 void resendCurrentRequest();
156
157 void checkAndResumeCommunication();
158
159 bool isSocketBusy() const;
160 bool isSocketWriting() const;
161 bool isSocketWaiting() const;
162 bool isSocketReading() const;
163
164 protected slots:
165 void _q_receiveReply();
166 void _q_bytesWritten(qint64 bytes); // proceed sending
167 void _q_readyRead(); // pending data to read
168 void _q_disconnected(); // disconnected from host
169 void _q_connected_abstract_socket(QAbstractSocket *socket);
170#if QT_CONFIG(localserver)
171 void _q_connected_local_socket(QLocalSocket *socket);
172#endif
173 void _q_connected(); // start sending request
174 void _q_error(QAbstractSocket::SocketError); // error from socket
175#ifndef QT_NO_NETWORKPROXY
176 void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy
177#endif
178
179 void _q_uploadDataReadyRead();
180
181#ifndef QT_NO_SSL
182 void _q_encrypted(); // start sending request (https)
183 void _q_sslErrors(const QList<QSslError> &errors); // ssl errors from the socket
184 void _q_preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*); // tls-psk auth necessary
185 void _q_encryptedBytesWritten(qint64 bytes); // proceed sending
186#endif
187
188 friend class QHttpProtocolHandler;
189};
190
191QT_END_NAMESPACE
192
193#endif
194

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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