qBittorrent
DownloadHandlerImpl Class Referencefinal

#include <downloadhandlerimpl.h>

Inheritance diagram for DownloadHandlerImpl:
Collaboration diagram for DownloadHandlerImpl:

Public Member Functions

 DownloadHandlerImpl (Net::DownloadManager *manager, const Net::DownloadRequest &downloadRequest)
 
void cancel () override
 
QString url () const
 
const Net::DownloadRequest downloadRequest () const
 
void assignNetworkReply (QNetworkReply *reply)
 

Private Member Functions

void processFinishedDownload ()
 
void checkDownloadSize (qint64 bytesReceived, qint64 bytesTotal)
 
void handleRedirection (const QUrl &newUrl)
 
void setError (const QString &error)
 
void finish ()
 

Static Private Member Functions

static QString errorCodeToString (QNetworkReply::NetworkError status)
 

Private Attributes

Net::DownloadManagerm_manager = nullptr
 
QNetworkReply * m_reply = nullptr
 
const Net::DownloadRequest m_downloadRequest
 
short m_redirectionCount = 0
 
Net::DownloadResult m_result
 

Additional Inherited Members

- Signals inherited from Net::DownloadHandler
void finished (const DownloadResult &result)
 

Detailed Description

Definition at line 39 of file downloadhandlerimpl.h.

Constructor & Destructor Documentation

◆ DownloadHandlerImpl()

DownloadHandlerImpl::DownloadHandlerImpl ( Net::DownloadManager manager,
const Net::DownloadRequest downloadRequest 
)

Definition at line 56 of file downloadhandlerimpl.cpp.

57  : DownloadHandler {manager}
58  , m_manager {manager}
60 {
61  m_result.url = url();
63 }
Net::DownloadResult m_result
const Net::DownloadRequest downloadRequest() const
const Net::DownloadRequest m_downloadRequest
Net::DownloadManager * m_manager
DownloadStatus status

References m_result, Net::DownloadResult::status, Net::Success, url(), and Net::DownloadResult::url.

Here is the call graph for this function:

Member Function Documentation

◆ assignNetworkReply()

void DownloadHandlerImpl::assignNetworkReply ( QNetworkReply *  reply)

Definition at line 78 of file downloadhandlerimpl.cpp.

79 {
80  Q_ASSERT(reply);
81  Q_ASSERT(!m_reply);
82 
83  m_reply = reply;
84  m_reply->setParent(this);
85  if (m_downloadRequest.limit() > 0)
86  connect(m_reply, &QNetworkReply::downloadProgress, this, &DownloadHandlerImpl::checkDownloadSize);
87  connect(m_reply, &QNetworkReply::finished, this, &DownloadHandlerImpl::processFinishedDownload);
88 }
QNetworkReply * m_reply
void checkDownloadSize(qint64 bytesReceived, qint64 bytesTotal)

References checkDownloadSize(), Net::DownloadRequest::limit(), m_downloadRequest, m_reply, and processFinishedDownload().

Here is the call graph for this function:

◆ cancel()

void DownloadHandlerImpl::cancel ( )
overridevirtual

Implements Net::DownloadHandler.

Definition at line 65 of file downloadhandlerimpl.cpp.

66 {
67  if (m_reply)
68  {
69  m_reply->abort();
70  }
71  else
72  {
73  setError(errorCodeToString(QNetworkReply::OperationCanceledError));
74  finish();
75  }
76 }
static QString errorCodeToString(QNetworkReply::NetworkError status)
void setError(const QString &error)

References errorCodeToString(), finish(), m_reply, and setError().

Here is the call graph for this function:

◆ checkDownloadSize()

void DownloadHandlerImpl::checkDownloadSize ( qint64  bytesReceived,
qint64  bytesTotal 
)
private

Definition at line 152 of file downloadhandlerimpl.cpp.

153 {
154  if ((bytesTotal > 0) && (bytesTotal <= m_downloadRequest.limit()))
155  {
156  // Total number of bytes is available
157  disconnect(m_reply, &QNetworkReply::downloadProgress, this, &DownloadHandlerImpl::checkDownloadSize);
158  return;
159  }
160 
161  if ((bytesTotal > m_downloadRequest.limit()) || (bytesReceived > m_downloadRequest.limit()))
162  {
163  m_reply->abort();
164  setError(tr("The file size (%1) exceeds the download limit (%2)")
165  .arg(Utils::Misc::friendlyUnit(bytesTotal)
167  finish();
168  }
169 }
QString friendlyUnit(qint64 bytes, bool isSpeed=false)
Definition: misc.cpp:261

References finish(), Utils::Misc::friendlyUnit(), Net::DownloadRequest::limit(), m_downloadRequest, m_reply, and setError().

Referenced by assignNetworkReply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ downloadRequest()

const Net::DownloadRequest DownloadHandlerImpl::downloadRequest ( ) const

Definition at line 96 of file downloadhandlerimpl.cpp.

97 {
98  return m_downloadRequest;
99 }

References m_downloadRequest.

◆ errorCodeToString()

QString DownloadHandlerImpl::errorCodeToString ( QNetworkReply::NetworkError  status)
staticprivate

Definition at line 219 of file downloadhandlerimpl.cpp.

220 {
221  switch (status)
222  {
223  case QNetworkReply::HostNotFoundError:
224  return tr("The remote host name was not found (invalid hostname)");
225  case QNetworkReply::OperationCanceledError:
226  return tr("The operation was canceled");
227  case QNetworkReply::RemoteHostClosedError:
228  return tr("The remote server closed the connection prematurely, before the entire reply was received and processed");
229  case QNetworkReply::TimeoutError:
230  return tr("The connection to the remote server timed out");
231  case QNetworkReply::SslHandshakeFailedError:
232  return tr("SSL/TLS handshake failed");
233  case QNetworkReply::ConnectionRefusedError:
234  return tr("The remote server refused the connection");
235  case QNetworkReply::ProxyConnectionRefusedError:
236  return tr("The connection to the proxy server was refused");
237  case QNetworkReply::ProxyConnectionClosedError:
238  return tr("The proxy server closed the connection prematurely");
239  case QNetworkReply::ProxyNotFoundError:
240  return tr("The proxy host name was not found");
241  case QNetworkReply::ProxyTimeoutError:
242  return tr("The connection to the proxy timed out or the proxy did not reply in time to the request sent");
243  case QNetworkReply::ProxyAuthenticationRequiredError:
244  return tr("The proxy requires authentication in order to honor the request but did not accept any credentials offered");
245  case QNetworkReply::ContentAccessDenied:
246  return tr("The access to the remote content was denied (401)");
247  case QNetworkReply::ContentOperationNotPermittedError:
248  return tr("The operation requested on the remote content is not permitted");
249  case QNetworkReply::ContentNotFoundError:
250  return tr("The remote content was not found at the server (404)");
251  case QNetworkReply::AuthenticationRequiredError:
252  return tr("The remote server requires authentication to serve the content but the credentials provided were not accepted");
253  case QNetworkReply::ProtocolUnknownError:
254  return tr("The Network Access API cannot honor the request because the protocol is not known");
255  case QNetworkReply::ProtocolInvalidOperationError:
256  return tr("The requested operation is invalid for this protocol");
257  case QNetworkReply::UnknownNetworkError:
258  return tr("An unknown network-related error was detected");
259  case QNetworkReply::UnknownProxyError:
260  return tr("An unknown proxy-related error was detected");
261  case QNetworkReply::UnknownContentError:
262  return tr("An unknown error related to the remote content was detected");
263  case QNetworkReply::ProtocolFailure:
264  return tr("A breakdown in protocol was detected");
265  default:
266  return tr("Unknown error");
267  }
268 }

Referenced by cancel(), and processFinishedDownload().

Here is the caller graph for this function:

◆ finish()

void DownloadHandlerImpl::finish ( )
private

Definition at line 214 of file downloadhandlerimpl.cpp.

215 {
216  emit finished(m_result);
217 }
void finished(const DownloadResult &result)

References Net::DownloadHandler::finished(), and m_result.

Referenced by cancel(), checkDownloadSize(), handleRedirection(), and processFinishedDownload().

Here is the caller graph for this function:

◆ handleRedirection()

void DownloadHandlerImpl::handleRedirection ( const QUrl &  newUrl)
private

Definition at line 171 of file downloadhandlerimpl.cpp.

172 {
174  {
175  setError(tr("Exceeded max redirections (%1)").arg(MAX_REDIRECTIONS));
176  finish();
177  return;
178  }
179 
180  // Resolve relative urls
181  const QUrl resolvedUrl = newUrl.isRelative() ? m_reply->url().resolved(newUrl) : newUrl;
182  const QString newUrlString = resolvedUrl.toString();
183  qDebug("Redirecting from %s to %s...", qUtf8Printable(m_reply->url().toString()), qUtf8Printable(newUrlString));
184 
185  // Redirect to magnet workaround
186  if (newUrlString.startsWith("magnet:", Qt::CaseInsensitive))
187  {
188  qDebug("Magnet redirect detected.");
190  m_result.magnet = newUrlString;
191  m_result.errorString = tr("Redirected to magnet URI");
192 
193  finish();
194  return;
195  }
196 
197  auto redirected = static_cast<DownloadHandlerImpl *>(
199  redirected->m_redirectionCount = m_redirectionCount + 1;
200  connect(redirected, &DownloadHandlerImpl::finished, this, [this](const Net::DownloadResult &result)
201  {
202  m_result = result;
203  m_result.url = url();
204  finish();
205  });
206 }
DownloadHandler * download(const DownloadRequest &downloadRequest)
const int MAX_REDIRECTIONS

References Net::DownloadManager::download(), Net::DownloadResult::errorString, finish(), Net::DownloadHandler::finished(), m_downloadRequest, m_manager, m_redirectionCount, m_reply, m_result, Net::DownloadResult::magnet, MAX_REDIRECTIONS, Net::RedirectedToMagnet, setError(), Net::DownloadResult::status, url(), and Net::DownloadResult::url.

Referenced by processFinishedDownload().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ processFinishedDownload()

void DownloadHandlerImpl::processFinishedDownload ( )
private

Definition at line 101 of file downloadhandlerimpl.cpp.

102 {
103  qDebug("Download finished: %s", qUtf8Printable(url()));
104 
105  // Check if the request was successful
106  if (m_reply->error() != QNetworkReply::NoError)
107  {
108  // Failure
109  qDebug("Download failure (%s), reason: %s", qUtf8Printable(url()), qUtf8Printable(errorCodeToString(m_reply->error())));
111  finish();
112  return;
113  }
114 
115  // Check if the server ask us to redirect somewhere else
116  const QVariant redirection = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
117  if (redirection.isValid())
118  {
119  handleRedirection(redirection.toUrl());
120  return;
121  }
122 
123  // Success
124  m_result.data = (m_reply->rawHeader("Content-Encoding") == "gzip")
125  ? Utils::Gzip::decompress(m_reply->readAll())
126  : m_reply->readAll();
127 
129  {
130  const QString destinationPath = m_downloadRequest.destFileName();
131  if (destinationPath.isEmpty())
132  {
133  const nonstd::expected<QString, QString> result = saveToTempFile(m_result.data);
134  if (result)
135  m_result.filePath = result.value();
136  else
137  setError(tr("I/O Error: %1").arg(result.error()));
138  }
139  else
140  {
141  const nonstd::expected<void, QString> result = Utils::IO::saveToFile(destinationPath, m_result.data);
142  if (result)
143  m_result.filePath = destinationPath;
144  else
145  setError(tr("I/O Error: %1").arg(result.error()));
146  }
147  }
148 
149  finish();
150 }
void handleRedirection(const QUrl &newUrl)
QString destFileName() const
QByteArray decompress(const QByteArray &data, bool *ok=nullptr)
Definition: gzip.cpp:102
nonstd::expected< void, QString > saveToFile(const QString &path, const QByteArray &data)
Definition: io.cpp:69
nonstd::expected< QString, QString > saveToTempFile(const QByteArray &data)

References Net::DownloadResult::data, Utils::Gzip::decompress(), Net::DownloadRequest::destFileName(), errorCodeToString(), Net::DownloadResult::filePath, finish(), handleRedirection(), m_downloadRequest, m_reply, m_result, Net::DownloadRequest::saveToFile(), Utils::IO::saveToFile(), anonymous_namespace{downloadhandlerimpl.cpp}::saveToTempFile(), setError(), and url().

Referenced by assignNetworkReply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setError()

void DownloadHandlerImpl::setError ( const QString &  error)
private

Definition at line 208 of file downloadhandlerimpl.cpp.

References Net::DownloadResult::errorString, Net::Failed, m_result, and Net::DownloadResult::status.

Referenced by cancel(), checkDownloadSize(), handleRedirection(), and processFinishedDownload().

Here is the caller graph for this function:

◆ url()

QString DownloadHandlerImpl::url ( ) const

Definition at line 91 of file downloadhandlerimpl.cpp.

92 {
93  return m_downloadRequest.url();
94 }

References m_downloadRequest, and Net::DownloadRequest::url().

Referenced by DownloadHandlerImpl(), handleRedirection(), and processFinishedDownload().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_downloadRequest

const Net::DownloadRequest DownloadHandlerImpl::m_downloadRequest
private

◆ m_manager

Net::DownloadManager* DownloadHandlerImpl::m_manager = nullptr
private

Definition at line 63 of file downloadhandlerimpl.h.

Referenced by handleRedirection().

◆ m_redirectionCount

short DownloadHandlerImpl::m_redirectionCount = 0
private

Definition at line 66 of file downloadhandlerimpl.h.

Referenced by handleRedirection().

◆ m_reply

QNetworkReply* DownloadHandlerImpl::m_reply = nullptr
private

◆ m_result

Net::DownloadResult DownloadHandlerImpl::m_result
private

The documentation for this class was generated from the following files: