20void QHttpProtocolHandler::_q_receiveReply()
25 if (m_socket->bytesAvailable() > 0)
26 qWarning() <<
"QAbstractProtocolHandler::_q_receiveReply() called without QHttpNetworkReply,"
27 << m_socket->bytesAvailable() <<
"bytes on socket.";
35 if (!qobject_cast<QHttpNetworkConnection*>(m_connection)) {
40 if (QSocketAbstraction::socketState(m_socket) == QAbstractSocket::UnconnectedState) {
41 if (m_socket->bytesAvailable() <= 0) {
42 if (m_reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) {
44 m_reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;
48 m_channel->handleUnexpectedEOF();
58 qint64 lastBytes = bytes;
62 QHttpNetworkReplyPrivate::ReplyState state = m_reply->d_func()->state;
64 case QHttpNetworkReplyPrivate::NothingDoneState: {
65 m_reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;
68 case QHttpNetworkReplyPrivate::ReadingStatusState: {
69 qint64 statusBytes = m_reply->d_func()->readStatus(m_socket);
70 if (statusBytes == -1) {
72 m_channel->handleUnexpectedEOF();
76 m_channel->lastStatus = m_reply->statusCode();
79 case QHttpNetworkReplyPrivate::ReadingHeaderState: {
80 QHttpNetworkReplyPrivate *replyPrivate = m_reply->d_func();
81 qint64 headerBytes = replyPrivate->readHeader(m_socket);
82 if (headerBytes == -1) {
84 m_channel->handleUnexpectedEOF();
89 if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) {
90 if (replyPrivate->isCompressed() && replyPrivate->autoDecompress) {
92 replyPrivate->removeAutoDecompressHeader();
94 replyPrivate->autoDecompress =
false;
96 const int statusCode = m_reply->statusCode();
97 if (statusCode == 100 || (102 <= statusCode && statusCode <= 199)) {
98 replyPrivate->clearHttpLayerInformation();
99 replyPrivate->state = QHttpNetworkReplyPrivate::ReadingStatusState;
102 if (replyPrivate->shouldEmitSignals())
103 emit m_reply->headerChanged();
108 if (!replyPrivate->expectContent()) {
109 replyPrivate->state = QHttpNetworkReplyPrivate::AllDoneState;
110 m_channel->allDone();
116 case QHttpNetworkReplyPrivate::ReadingDataState: {
117 QHttpNetworkReplyPrivate *replyPrivate = m_reply->d_func();
118 if (QSocketAbstraction::socketState(m_socket) == QAbstractSocket::ConnectedState &&
119 replyPrivate->downstreamLimited && !replyPrivate->responseData.isEmpty() && replyPrivate->shouldEmitSignals()) {
130 if (replyPrivate->userProvidedDownloadBuffer) {
135 qint64 haveRead = replyPrivate->readBodyVeryFast(m_socket, replyPrivate->userProvidedDownloadBuffer + replyPrivate->totalProgress);
138 replyPrivate->totalProgress += haveRead;
140 emit m_reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
141 }
else if (haveRead == 0) {
143 }
else if (haveRead < 0) {
144 m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::RemoteHostClosedError);
147 }
else if (!replyPrivate->isChunked() && replyPrivate->bodyLength > 0) {
150 qint64 haveRead = replyPrivate->readBodyFast(m_socket, &replyPrivate->responseData);
152 replyPrivate->totalProgress += haveRead;
153 if (replyPrivate->shouldEmitSignals()) {
154 emit m_reply->readyRead();
155 emit m_reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
162 qint64 haveRead = replyPrivate->readBody(m_socket, &replyPrivate->responseData);
165 replyPrivate->totalProgress += haveRead;
166 if (replyPrivate->shouldEmitSignals()) {
167 emit m_reply->readyRead();
168 emit m_reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
170 }
else if (haveRead == -1) {
172 m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::ProtocolFailure);
177 if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState)
183 case QHttpNetworkReplyPrivate::AllDoneState:
184 m_channel->allDone();
185 if (state == QHttpNetworkReplyPrivate::AllDoneState)
191 }
while (bytes != lastBytes && m_reply);
225bool QHttpProtocolHandler::sendRequest()
227 m_reply = m_channel->reply;
231 qWarning(
"QAbstractProtocolHandler::sendRequest() called without QHttpNetworkReply");
235 switch (m_channel->state) {
236 case QHttpNetworkConnectionChannel::IdleState: {
237 if (!m_channel->ensureConnection()) {
243 if (m_channel->request.isPreConnect()) {
244 m_channel->state = QHttpNetworkConnectionChannel::IdleState;
245 m_reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;
246 m_channel->allDone();
247 m_connection->preConnectFinished();
252 m_channel->written = 0;
253 m_channel->bytesTotal = 0;
255 QHttpNetworkReplyPrivate *replyPrivate = m_reply->d_func();
256 replyPrivate->clear();
257 replyPrivate->connection = m_connection;
258 replyPrivate->connectionChannel = m_channel;
259 replyPrivate->autoDecompress = m_channel->request.d->autoDecompress;
260 replyPrivate->pipeliningUsed =
false;
264 if (!m_channel->request.url().userInfo().isEmpty() && m_channel->request.withCredentials()) {
265 QUrl url = m_channel->request.url();
266 QAuthenticator &auth = m_channel->authenticator;
267 if (url.userName() != auth.user()
268 || (!url.password().isEmpty() && url.password() != auth.password())) {
269 auth.setUser(url.userName());
270 auth.setPassword(url.password());
271 m_connection->d_func()->copyCredentials(m_connection->d_func()->indexOf(m_socket), &auth,
false);
275 url.setUserInfo(QString());
276 m_channel->request.setUrl(url);
280 if (m_channel->request.withCredentials())
281 m_connection->d_func()->createAuthorization(m_socket, m_channel->request);
282#ifndef QT_NO_NETWORKPROXY
283 m_header = QHttpNetworkRequestPrivate::header(m_channel->request,
284 (m_connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy));
286 m_header = QHttpNetworkRequestPrivate::header(m_channel->request,
false);
291 QNonContiguousByteDevice* uploadByteDevice = m_channel->request.uploadByteDevice();
292 if (uploadByteDevice) {
294 QObject::connect(uploadByteDevice, SIGNAL(readyRead()), m_channel, SLOT(_q_uploadDataReadyRead()));
296 m_channel->bytesTotal = m_channel->request.contentLength();
298 m_channel->state = QHttpNetworkConnectionChannel::WritingState;
302 m_socket->write(std::exchange(m_header, {}));
303 QMetaObject::invokeMethod(m_reply,
"requestSent", Qt::QueuedConnection);
304 m_channel->state = QHttpNetworkConnectionChannel::WaitingState;
310 case QHttpNetworkConnectionChannel::WritingState:
313 QNonContiguousByteDevice* uploadByteDevice = m_channel->request.uploadByteDevice();
314 if (!uploadByteDevice || m_channel->bytesTotal == m_channel->written) {
317 if (!m_header.isEmpty())
318 m_socket->write(std::exchange(m_header, {}));
319 if (uploadByteDevice)
320 emit m_reply->dataSendProgress(m_channel->written, m_channel->bytesTotal);
321 m_channel->state = QHttpNetworkConnectionChannel::WaitingState;
328 const qint64 socketBufferFill = 32*1024;
329 const qint64 socketWriteMaxSize = 16*1024;
333 QSslSocket *sslSocket = qobject_cast<QSslSocket*>(m_socket);
334 const auto encryptedBytesToWrite = [sslSocket]() -> qint64
336 return sslSocket ? sslSocket->encryptedBytesToWrite() : 0;
339 const auto encryptedBytesToWrite = [](){
return qint64(0); };
345 while ((m_socket->bytesToWrite() + encryptedBytesToWrite()) <= socketBufferFill
346 && m_channel->bytesTotal != m_channel->written)
349 qint64 currentReadSize = 0;
350 const qint64 desiredReadSize = qMin(socketWriteMaxSize, m_channel->bytesTotal - m_channel->written);
351 const char *readPointer = uploadByteDevice->readPointer(desiredReadSize, currentReadSize);
353 if (currentReadSize == -1) {
355 m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::UnknownNetworkError);
357 }
else if (readPointer ==
nullptr || currentReadSize == 0) {
361 if (m_channel->written != uploadByteDevice->pos()) {
363 qWarning() <<
"QHttpProtocolHandler: Internal error in sendRequest. Expected to write at position" << m_channel->written <<
"but read device is at" << uploadByteDevice->pos();
364 Q_ASSERT(m_channel->written == uploadByteDevice->pos());
365 m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::ProtocolFailure);
368 qint64 currentWriteSize;
369 if (m_header.isEmpty()) {
370 currentWriteSize = m_socket->write(readPointer, currentReadSize);
373 const qint64 headerSize = m_header.size();
374 m_header.append(readPointer, currentReadSize);
375 currentWriteSize = m_socket->write(std::exchange(m_header, {}));
376 if (currentWriteSize != -1)
377 currentWriteSize -= headerSize;
378 QMetaObject::invokeMethod(m_reply,
"requestSent", Qt::QueuedConnection);
380 if (currentWriteSize == -1 || currentWriteSize != currentReadSize) {
382 m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::UnknownNetworkError);
385 m_channel->written += currentWriteSize;
386 uploadByteDevice->advanceReadPointer(currentWriteSize);
388 emit m_reply->dataSendProgress(m_channel->written, m_channel->bytesTotal);
390 if (m_channel->written == m_channel->bytesTotal) {
392 m_channel->state = QHttpNetworkConnectionChannel::WaitingState;
402 case QHttpNetworkConnectionChannel::WaitingState:
404 QNonContiguousByteDevice* uploadByteDevice = m_channel->request.uploadByteDevice();
405 if (uploadByteDevice) {
406 QObject::disconnect(uploadByteDevice, SIGNAL(readyRead()), m_channel, SLOT(_q_uploadDataReadyRead()));
416 if (m_socket->bytesAvailable())
417 QMetaObject::invokeMethod(m_channel,
"_q_receiveReply", Qt::QueuedConnection);
420 case QHttpNetworkConnectionChannel::ReadingState: