src/network/access/qfilenetworkreply.cpp
branchRCL_3
changeset 4 3b1da2848fc7
parent 3 41300fa6a67c
child 5 d3bac044e0f0
equal deleted inserted replaced
3:41300fa6a67c 4:3b1da2848fc7
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtNetwork module of the Qt Toolkit.
     7 ** This file is part of the QtNetwork module of the Qt Toolkit.
     8 **
     8 **
    42 #include "qfilenetworkreply_p.h"
    42 #include "qfilenetworkreply_p.h"
    43 
    43 
    44 #include "QtCore/qdatetime.h"
    44 #include "QtCore/qdatetime.h"
    45 #include <QtCore/QCoreApplication>
    45 #include <QtCore/QCoreApplication>
    46 #include <QtCore/QFileInfo>
    46 #include <QtCore/QFileInfo>
       
    47 #include <QDebug>
    47 
    48 
    48 QT_BEGIN_NAMESPACE
    49 QT_BEGIN_NAMESPACE
    49 
    50 
    50 QFileNetworkReplyPrivate::QFileNetworkReplyPrivate()
    51 QFileNetworkReplyPrivate::QFileNetworkReplyPrivate()
    51     : QNetworkReplyPrivate(), realFileSize(0), finished(false)
    52     : QNetworkReplyPrivate(), realFileSize(0)
    52 {
    53 {
    53 }
       
    54 
       
    55 QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req)
       
    56     : QNetworkReply(*new QFileNetworkReplyPrivate(), parent)
       
    57 {
       
    58     setRequest(req);
       
    59     setUrl(req.url());
       
    60     setOperation(QNetworkAccessManager::GetOperation);
       
    61     QMetaObject::invokeMethod(this, "_q_startOperation", Qt::QueuedConnection);
       
    62     QNetworkReply::open(QIODevice::ReadOnly);
       
    63 }
    54 }
    64 
    55 
    65 QFileNetworkReply::~QFileNetworkReply()
    56 QFileNetworkReply::~QFileNetworkReply()
    66 {
    57 {
    67 }
    58 }
    68 
    59 
    69 // This code is mostly inspired by QNetworkAccessFileBackend
    60 QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op)
    70 // We also use its translation context for error messages
    61     : QNetworkReply(*new QFileNetworkReplyPrivate(), parent)
    71 void QFileNetworkReplyPrivate::_q_startOperation()
       
    72 {
    62 {
    73     Q_Q(QFileNetworkReply);
    63     setRequest(req);
       
    64     setUrl(req.url());
       
    65     setOperation(op);
       
    66     QNetworkReply::open(QIODevice::ReadOnly);
    74 
    67 
    75     QUrl url = q->url();
    68     qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError");
       
    69 
       
    70     QFileNetworkReplyPrivate *d = (QFileNetworkReplyPrivate*) d_func();
       
    71 
       
    72     QUrl url = req.url();
    76     if (url.host() == QLatin1String("localhost"))
    73     if (url.host() == QLatin1String("localhost"))
    77         url.setHost(QString());
    74         url.setHost(QString());
    78 
    75 
    79 #if !defined(Q_OS_WIN)
    76 #if !defined(Q_OS_WIN)
    80     // do not allow UNC paths on Unix
    77     // do not allow UNC paths on Unix
    81     if (!url.host().isEmpty()) {
    78     if (!url.host().isEmpty()) {
    82         // we handle only local files
    79         // we handle only local files
    83         QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString());
    80         QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString());
    84         q->setError(QNetworkReply::ProtocolInvalidOperationError, msg);
    81         setError(QNetworkReply::ProtocolInvalidOperationError, msg);
    85         emit q->error(QNetworkReply::ProtocolInvalidOperationError);
    82         QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
    86         doFinished();
    83             Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolInvalidOperationError));
       
    84         QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
    87         return;
    85         return;
    88     }
    86     }
    89 #endif
    87 #endif
    90     if (url.path().isEmpty())
    88     if (url.path().isEmpty())
    91         url.setPath(QLatin1String("/"));
    89         url.setPath(QLatin1String("/"));
    92     q->setUrl(url);
    90     setUrl(url);
    93 
    91 
    94 
    92 
    95     QString fileName = url.toLocalFile();
    93     QString fileName = url.toLocalFile();
    96     if (fileName.isEmpty()) {
    94     if (fileName.isEmpty()) {
    97         fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);
    95         fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);
    98     }
    96     }
    99     realFile.setFileName(fileName);
    97     d->realFile.setFileName(fileName);
   100 
    98 
   101     QFileInfo fi(realFile);
    99     QFileInfo fi(d->realFile);
   102     if (fi.isDir()) {
   100     if (fi.isDir()) {
   103         QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString());
   101         QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString());
   104         q->setError(QNetworkReply::ContentOperationNotPermittedError, msg);
   102         setError(QNetworkReply::ContentOperationNotPermittedError, msg);
   105         emit q->error(QNetworkReply::ContentOperationNotPermittedError);
   103         QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
   106         doFinished();
   104             Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentOperationNotPermittedError));
       
   105         QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
   107         return;
   106         return;
   108     }
   107     }
   109 
   108 
   110     bool opened = realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
   109     bool opened = d->realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
   111 
   110 
   112     // could we open the file?
   111     // could we open the file?
   113     if (!opened) {
   112     if (!opened) {
   114         QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2")
   113         QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2")
   115                       .arg(realFile.fileName(), realFile.errorString());
   114                       .arg(d->realFile.fileName(), d->realFile.errorString());
   116 
   115 
   117         if (realFile.exists()) {
   116         if (d->realFile.exists()) {
   118             q->setError(QNetworkReply::ContentAccessDenied, msg);
   117             setError(QNetworkReply::ContentAccessDenied, msg);
   119             emit q->error(QNetworkReply::ContentAccessDenied);
   118             QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
       
   119                 Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentAccessDenied));
   120         } else {
   120         } else {
   121             q->setError(QNetworkReply::ContentNotFoundError, msg);
   121             setError(QNetworkReply::ContentNotFoundError, msg);
   122             emit q->error(QNetworkReply::ContentNotFoundError);
   122             QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
       
   123                 Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentNotFoundError));
   123         }
   124         }
   124         doFinished();
   125         QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
   125         return;
   126         return;
   126     }
   127     }
   127 
   128 
   128     realFileSize = fi.size();
   129     d->realFileSize = fi.size();
   129     q->setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified());
   130     setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified());
   130     q->setHeader(QNetworkRequest::ContentLengthHeader, realFileSize);
   131     setHeader(QNetworkRequest::ContentLengthHeader, d->realFileSize);
   131 
   132 
   132     emit q->metaDataChanged();
   133     QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
   133     emit q->downloadProgress(realFileSize, realFileSize);
   134     QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection,
   134     emit q->readyRead();
   135         Q_ARG(qint64, d->realFileSize), Q_ARG(qint64, d->realFileSize));
   135     doFinished();
   136     QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
       
   137     QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
   136 }
   138 }
   137 
   139 
   138 bool QFileNetworkReplyPrivate::isFinished() const
   140 bool QFileNetworkReplyPrivate::isFinished() const
   139 {
   141 {
   140     return finished;
   142     return true;
   141 }
   143 }
   142 
       
   143 void QFileNetworkReplyPrivate::doFinished()
       
   144 {
       
   145     Q_Q(QFileNetworkReply);
       
   146     finished = true;
       
   147     emit q->finished();
       
   148 }
       
   149 
       
   150 
   144 
   151 void QFileNetworkReply::close()
   145 void QFileNetworkReply::close()
   152 {
   146 {
   153     Q_D(QFileNetworkReply);
   147     Q_D(QFileNetworkReply);
   154     QNetworkReply::close();
   148     QNetworkReply::close();
   155     d->realFile.close();
   149     d->realFile.close();
   156 
       
   157     if (!d->finished)
       
   158         d->doFinished();
       
   159 }
   150 }
   160 
   151 
   161 void QFileNetworkReply::abort()
   152 void QFileNetworkReply::abort()
   162 {
   153 {
   163     Q_D(QFileNetworkReply);
   154     Q_D(QFileNetworkReply);
   164     QNetworkReply::close();
   155     QNetworkReply::close();
   165     d->realFile.close();
   156     d->realFile.close();
   166 
       
   167     if (!d->finished)
       
   168         d->doFinished();
       
   169 }
   157 }
   170 
   158 
   171 qint64 QFileNetworkReply::bytesAvailable() const
   159 qint64 QFileNetworkReply::bytesAvailable() const
   172 {
   160 {
   173     Q_D(const QFileNetworkReply);
   161     Q_D(const QFileNetworkReply);