6#include "QtCore/qdatastream.h"
7#include <QCoreApplication>
10#include "private/qnoncontiguousbytedevice_p.h"
14using namespace Qt::StringLiterals;
16#ifdef QT_BUILD_INTERNAL
19 ReadBufferSize = 16384,
20 WriteBufferSize = ReadBufferSize
23QStringList QNetworkAccessDebugPipeBackendFactory::supportedSchemes()
const
25 return QStringList(QStringLiteral(
"debugpipe"));
28QNetworkAccessBackend *
29QNetworkAccessDebugPipeBackendFactory::create(QNetworkAccessManager::Operation op,
30 const QNetworkRequest &request)
const
34 case QNetworkAccessManager::GetOperation:
35 case QNetworkAccessManager::PutOperation:
43 QUrl url = request.url();
44 if (url.scheme() ==
"debugpipe"_L1)
45 return new QNetworkAccessDebugPipeBackend;
49QNetworkAccessDebugPipeBackend::QNetworkAccessDebugPipeBackend()
50 : QNetworkAccessBackend(QNetworkAccessBackend::TargetType::Networked),
52 hasUploadFinished(
false),
53 hasDownloadFinished(
false),
54 hasEverythingFinished(
false),
60QNetworkAccessDebugPipeBackend::~QNetworkAccessDebugPipeBackend()
63 socket.disconnect(
this);
66void QNetworkAccessDebugPipeBackend::open()
68 socket.connectToHost(url().host(), url().port(12345));
69 socket.setReadBufferSize(ReadBufferSize);
72 connect(&socket, SIGNAL(readyRead()), SLOT(socketReadyRead()));
73 connect(&socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), SLOT(socketError()));
74 connect(&socket, SIGNAL(disconnected()), SLOT(socketDisconnected()));
75 connect(&socket, SIGNAL(connected()), SLOT(socketConnected()));
77 connect(&socket, SIGNAL(bytesWritten(qint64)), SLOT(socketBytesWritten(qint64)));
79 bareProtocol = QUrlQuery(url()).queryItemValue(
"bare"_L1) ==
"1"_L1;
81 if (operation() == QNetworkAccessManager::PutOperation) {
82 createUploadByteDevice();
83 QObject::connect(uploadByteDevice(), SIGNAL(readyRead()),
this,
84 SLOT(uploadReadyReadSlot()));
85 QMetaObject::invokeMethod(
this,
"uploadReadyReadSlot", Qt::QueuedConnection);
89void QNetworkAccessDebugPipeBackend::socketReadyRead()
94qint64 QNetworkAccessDebugPipeBackend::read(
char *data, qint64 maxlen)
96 qint64 haveRead = socket.read(data, maxlen);
99 hasDownloadFinished =
true;
102 h.removeAll(QHttpHeaders::WellKnownHeader::ContentLength);
103 setHeaders(std::move(h));
108 bytesDownloaded += haveRead;
112qint64 QNetworkAccessDebugPipeBackend::bytesAvailable()
const
114 return socket.bytesAvailable();
117void QNetworkAccessDebugPipeBackend::socketBytesWritten(qint64)
119 pushFromUpstreamToSocket();
122void QNetworkAccessDebugPipeBackend::uploadReadyReadSlot()
124 pushFromUpstreamToSocket();
127void QNetworkAccessDebugPipeBackend::pushFromUpstreamToSocket()
130 if (operation() == QNetworkAccessManager::PutOperation) {
131 if (hasUploadFinished)
135 if (socket.bytesToWrite() >= WriteBufferSize)
138 QByteArray data(WriteBufferSize, Qt::Uninitialized);
139 qint64 haveRead = uploadByteDevice()->peek(data.data(), data.size());
140 if (haveRead == -1) {
142 hasUploadFinished =
true;
145 }
else if (haveRead == 0) {
150 data.truncate(haveRead);
151 haveWritten = socket.write(std::move(data));
153 if (haveWritten < 0) {
155 QString msg = QCoreApplication::translate(
"QNetworkAccessDebugPipeBackend",
"Write error writing to %1: %2")
156 .arg(url().toString(), socket.errorString());
157 error(QNetworkReply::ProtocolFailure, msg);
161 uploadByteDevice()->skip(haveWritten);
162 bytesUploaded += haveWritten;
171void QNetworkAccessDebugPipeBackend::possiblyFinish()
173 if (hasEverythingFinished)
175 hasEverythingFinished =
true;
177 if ((operation() == QNetworkAccessManager::GetOperation) && hasDownloadFinished) {
180 }
else if ((operation() == QNetworkAccessManager::PutOperation) && hasUploadFinished) {
188void QNetworkAccessDebugPipeBackend::close()
190 qWarning(
"QNetworkAccessDebugPipeBackend::closeDownstreamChannel() %d",operation());
196void QNetworkAccessDebugPipeBackend::socketError()
198 qWarning(
"QNetworkAccessDebugPipeBackend::socketError() %d",socket.error());
199 QNetworkReply::NetworkError code;
200 switch (socket.error()) {
201 case QAbstractSocket::RemoteHostClosedError:
204 case QAbstractSocket::NetworkError:
205 code = QNetworkReply::UnknownNetworkError;
209 code = QNetworkReply::ProtocolFailure;
213 error(code, QNetworkAccessDebugPipeBackend::tr(
"Socket error on %1: %2")
214 .arg(url().toString(), socket.errorString()));
216 disconnect(&socket, SIGNAL(disconnected()),
this, SLOT(socketDisconnected()));
220void QNetworkAccessDebugPipeBackend::socketDisconnected()
222 if (socket.bytesToWrite() == 0) {
227 QString msg = QNetworkAccessDebugPipeBackend::tr(
"Remote host closed the connection prematurely on %1")
228 .arg(url().toString());
229 error(QNetworkReply::RemoteHostClosedError, msg);
234void QNetworkAccessDebugPipeBackend::socketConnected()
243#include "moc_qnetworkaccessdebugpipebackend_p.cpp"