Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qnetworkreplyfileimpl.cpp
Go to the documentation of this file.
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
5
6#include "QtCore/qdatetime.h"
8#include <QtCore/QCoreApplication>
9#include <QtCore/QFileInfo>
10#include <QtCore/QThread>
11#include "qnetworkfile_p.h"
12#include "qnetworkrequest.h"
13
15
16using namespace Qt::StringLiterals;
17
19
21 : QNetworkReplyPrivate(), managerPrivate(nullptr), realFile(nullptr)
22{
23 qRegisterMetaType<QNetworkRequest::KnownHeaders>();
24 qRegisterMetaType<QNetworkReply::NetworkError>();
25}
26
28{
30 if (d->realFile) {
31 if (d->realFile->thread() == QThread::currentThread())
32 delete d->realFile;
33 else
34 QMetaObject::invokeMethod(d->realFile, "deleteLater", Qt::QueuedConnection);
35 }
36}
37
40{
41 setRequest(req);
42 setUrl(req.url());
43 setOperation(op);
45
47
48 d->managerPrivate = manager->d_func();
49
50 QUrl url = req.url();
51 if (url.host() == "localhost"_L1)
53
54#if !defined(Q_OS_WIN)
55 // do not allow UNC paths on Unix
56 if (!url.host().isEmpty()) {
57 // we handle only local files
58 QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString());
60 setFinished(true); // We're finished, will emit finished() after ctor is done.
63 QMetaObject::invokeMethod(this, &QNetworkReplyFileImpl::fileOpenFinished, Qt::QueuedConnection, false);
64 return;
65 }
66#endif
67 if (url.path().isEmpty())
68 url.setPath("/"_L1);
69 setUrl(url);
70
72 if (fileName.isEmpty()) {
73 const QString scheme = url.scheme();
74 if (scheme == "qrc"_L1) {
75 fileName = u':' + url.path();
76 } else {
77#if defined(Q_OS_ANDROID)
78 if (scheme == "assets"_L1)
79 fileName = "assets:"_L1 + url.path();
80 else
81#endif
83 }
84 }
85
86 if (req.attribute(QNetworkRequest::BackgroundRequestAttribute).toBool()) { // Asynchronous open
87 auto realFile = new QNetworkFile(fileName);
92 connect(realFile, SIGNAL(finished(bool)), SLOT(fileOpenFinished(bool)),
94
95 realFile->moveToThread(d->managerPrivate->createThread());
97
98 d->realFile = realFile;
99 } else { // Synch open
100 setFinished(true);
101
103 if (fi.isDir()) {
104 QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString());
106 QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
109 return;
110 }
111 d->realFile = new QFile(fileName, this);
112 bool opened = d->realFile->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
113
114 // could we open the file?
115 if (!opened) {
116 QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2")
117 .arg(d->realFile->fileName(), d->realFile->errorString());
118
119 if (fi.exists()) {
121 QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
123 } else {
125 QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
127 }
129 return;
130 }
131 auto h = headers();
133 QNetworkHeadersPrivate::toHttpDate(fi.lastModified()));
135 QByteArray::number(fi.size()));
136 setHeaders(std::move(h));
137
138 QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
139 QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection,
140 Q_ARG(qint64, fi.size()), Q_ARG(qint64, fi.size()));
143 }
144}
145
147{
150 if (d->realFile) {
151 if (d->realFile->thread() == thread())
152 d->realFile->close();
153 else
155 }
156}
157
159{
160 close();
161}
162
164{
165 Q_D(const QNetworkReplyFileImpl);
166 if (!d->isFinished || !d->realFile || !d->realFile->isOpen())
168 return QNetworkReply::bytesAvailable() + d->realFile->bytesAvailable();
169}
170
172{
173 return true;
174}
175
177{
178 const auto totalSizeOpt = QNetworkHeadersPrivate::toInt(
180 return totalSizeOpt.value_or(0);
181}
182
187{
189 if (!d->isFinished || !d->realFile || !d->realFile->isOpen())
190 return -1;
191 qint64 ret = d->realFile->read(data, maxlen);
192 if (bytesAvailable() == 0)
193 d->realFile->close();
194 if (ret == 0 && bytesAvailable() == 0)
195 return -1;
196 else {
199 return ret;
200 }
201}
202
203void QNetworkReplyFileImpl::fileOpenFinished(bool isOpen)
204{
205 setFinished(true);
206 if (isOpen) {
207 const auto fileSize = size();
209 Q_EMIT downloadProgress(fileSize, fileSize);
211 }
213}
214
216
217#include "moc_qnetworkreplyfileimpl_p.cpp"
218
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
FileError error() const
Returns the file error status.
\inmodule QtCore
Definition qfile.h:93
virtual bool open(QIODeviceBase::OpenMode mode)
Opens the device and sets its OpenMode to mode.
void readyRead()
This signal is emitted once every time new data is available for reading from the device's current re...
bool isOpen() const
Returns true if the device is open; otherwise returns false.
virtual qint64 bytesAvailable() const
Returns the number of bytes that are available for reading.
The QNetworkAccessManager class allows the application to send network requests and receive replies.
Operation
Indicates the operation this reply is processing.
void headerRead(QHttpHeaders::WellKnownHeader, const QByteArray &value)
static std::optional< qint64 > toInt(QByteArrayView value)
static QByteArray toHttpDate(const QDateTime &dt)
QNetworkAccessManagerPrivate * managerPrivate
virtual void close() override
Closes this device for reading.
virtual qint64 readData(char *data, qint64 maxlen) override
virtual bool isSequential() const override
QNetworkReplyFileImpl(QNetworkAccessManager *manager, const QNetworkRequest &req, const QNetworkAccessManager::Operation op)
virtual qint64 bytesAvailable() const override
Returns the number of bytes that are available for reading.
virtual void abort() override
Aborts the operation immediately and close down any network connections still open.
qint64 size() const override
For open random-access devices, this function returns the size of the device.
The QNetworkReply class contains the data and headers for a request sent with QNetworkAccessManager.
QNetworkAccessManager * manager() const
Returns the QNetworkAccessManager that was used to create this QNetworkReply object.
void setError(NetworkError errorCode, const QString &errorString)
Sets the error condition to be errorCode.
virtual void close() override
Closes this device for reading.
void setWellKnownHeader(QHttpHeaders::WellKnownHeader name, const QByteArray &value)
QHttpHeaders headers() const
void setOperation(QNetworkAccessManager::Operation operation)
Sets the associated operation for this object to be operation.
void metaDataChanged()
\omit FIXME: Update name? \endomit
void setUrl(const QUrl &url)
Sets the URL being processed to be url.
void setHeaders(const QHttpHeaders &newHeaders)
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
This signal is emitted to indicate the progress of the download part of this network request,...
void setAttribute(QNetworkRequest::Attribute code, const QVariant &value)
Sets the attribute code to have value value.
void setRequest(const QNetworkRequest &request)
Sets the associated request for this object to be request.
NetworkError
Indicates all possible error conditions found during the processing of the request.
@ ContentOperationNotPermittedError
@ ProtocolInvalidOperationError
void setFinished(bool)
void finished()
This signal is emitted when the reply has finished processing.
QUrl url() const
Returns the URL of the content downloaded or uploaded.
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
KnownHeaders
List of known header types that QNetworkRequest parses.
QVariant attribute(Attribute code, const QVariant &defaultValue=QVariant()) const
Returns the attribute associated with the code code.
QUrl url() const
Returns the URL this network request is referring to.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QThread * currentThread()
Definition qthread.cpp:1039
\inmodule QtCore
Definition qurl.h:94
QString host(ComponentFormattingOptions=FullyDecoded) const
Returns the host of the URL if it is defined; otherwise an empty string is returned.
Definition qurl.cpp:2340
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1991
@ RemoveFragment
Definition qurl.h:112
@ RemoveQuery
Definition qurl.h:111
@ RemoveAuthority
Definition qurl.h:109
void setHost(const QString &host, ParsingMode mode=DecodedMode)
Sets the host of the URL to host.
Definition qurl.cpp:2289
void setPath(const QString &path, ParsingMode mode=DecodedMode)
Sets the path of the URL to path.
Definition qurl.cpp:2414
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2831
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Definition qurl.cpp:3425
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
Definition qurl.cpp:2468
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
Combined button and popup list for selecting options.
@ QueuedConnection
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
return ret
#define QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TAG)
Definition qmetatype.h:1384
#define SLOT(a)
Definition qobjectdefs.h:52
#define Q_ARG(Type, data)
Definition qobjectdefs.h:63
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat GLfloat GLfloat h
#define Q_EMIT
long long qint64
Definition qtypes.h:60
QNetworkAccessManager manager
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...