30 const QNetworkRequest &request)
const
34 case QNetworkAccessManager::GetOperation:
35 case QNetworkAccessManager::PutOperation:
43 QUrl url = request.url();
44 if (url.scheme().compare(
"qrc"_L1, Qt::CaseInsensitive) == 0
45#if defined(Q_OS_ANDROID)
46 || url.scheme().compare(
"assets"_L1, Qt::CaseInsensitive) == 0
48 || url.isLocalFile()) {
49 return new QNetworkAccessFileBackend;
50 }
else if (!url.scheme().isEmpty() && url.authority().isEmpty() && (url.scheme().size() > 1)) {
57 QFileInfo fi(url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery));
58 if (fi.exists() || (op == QNetworkAccessManager::PutOperation && fi.dir().exists()))
59 return new QNetworkAccessFileBackend;
78void QNetworkAccessFileBackend::open()
80 QUrl url =
this->url();
82 if (url.host() ==
"localhost"_L1)
83 url.setHost(QString());
86 if (!url.host().isEmpty()) {
88 error(QNetworkReply::ProtocolInvalidOperationError,
89 QCoreApplication::translate(
"QNetworkAccessFileBackend",
"Request for opening non-local file %1").arg(url.toString()));
94 if (url.path().isEmpty())
98 QString fileName = url.toLocalFile();
99 if (fileName.isEmpty()) {
100 if (url.scheme() ==
"qrc"_L1) {
101 fileName = u':' + url.path();
103#if defined(Q_OS_ANDROID)
104 if (url.scheme() ==
"assets"_L1)
105 fileName =
"assets:"_L1 + url.path();
108 fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);
111 file.setFileName(fileName);
113 if (operation() == QNetworkAccessManager::GetOperation) {
118 QIODevice::OpenMode mode;
119 switch (operation()) {
120 case QNetworkAccessManager::GetOperation:
121 mode = QIODevice::ReadOnly;
123 case QNetworkAccessManager::PutOperation:
124 mode = QIODevice::WriteOnly | QIODevice::Truncate;
125 createUploadByteDevice();
126 QObject::connect(uploadByteDevice(), SIGNAL(readyRead()),
this, SLOT(uploadReadyReadSlot()));
127 QMetaObject::invokeMethod(
this,
"uploadReadyReadSlot", Qt::QueuedConnection);
130 Q_ASSERT_X(
false,
"QNetworkAccessFileBackend::open",
131 "Got a request operation I cannot handle!!");
135 mode |= QIODevice::Unbuffered;
136 bool opened = file.open(mode);
137 if (file.isSequential())
138 connect(&file, &QIODevice::readChannelFinished,
this, [
this]() { finished(); });
142 QString msg = QCoreApplication::translate(
"QNetworkAccessFileBackend",
"Error opening %1: %2")
143 .arg(
this->url().toString(), file.errorString());
148 if (file.exists() || operation() == QNetworkAccessManager::PutOperation)
149 error(QNetworkReply::ContentAccessDenied, msg);
151 error(QNetworkReply::ContentNotFoundError, msg);
156void QNetworkAccessFileBackend::uploadReadyReadSlot()
158 if (hasUploadFinished)
162 QByteArray data(16 * 1024, Qt::Uninitialized);
163 qint64 haveRead = uploadByteDevice()->peek(data.data(), data.size());
164 if (haveRead == -1) {
166 hasUploadFinished =
true;
171 }
else if (haveRead == 0) {
176 data.truncate(haveRead);
177 haveWritten = file.write(data);
179 if (haveWritten < 0) {
181 QString msg = QCoreApplication::translate(
"QNetworkAccessFileBackend",
"Write error writing to %1: %2")
182 .arg(url().toString(), file.errorString());
183 error(QNetworkReply::ProtocolFailure, msg);
188 uploadByteDevice()->skip(haveWritten);
230qint64 QNetworkAccessFileBackend::read(
char *data, qint64 maxlen)
232 if (operation() != QNetworkAccessManager::GetOperation)
234 qint64 actuallyRead = file.read(data, maxlen);
235 if (actuallyRead <= 0) {
237 if (file.error() != QFile::NoError) {
238 QString msg = QCoreApplication::translate(
"QNetworkAccessFileBackend",
"Read error reading from %1: %2")
239 .arg(url().toString(), file.errorString());
240 error(QNetworkReply::ProtocolFailure, msg);
249 if (!file.isSequential() && file.atEnd())
251 totalBytes += actuallyRead;