Title: [95631] trunk/Source
Revision
95631
Author
commit-qu...@webkit.org
Date
2011-09-21 08:10:43 -0700 (Wed, 21 Sep 2011)

Log Message

[Qt][WK2] Implement Download support in WebProcess
https://bugs.webkit.org/show_bug.cgi?id=68153

Patch by Jesus Sanchez-Palencia <jesus.palen...@openbossa.org> on 2011-09-21
Reviewed by Andreas Kling.

Source/WebCore:

Refactored QNetworkReplyHandler::finish() in order to add
and use the static function QNetworkReplyHandler::errorForReply().
This will be used by our Download implementation in WebKit2 (WebProcess)
when handling ResourceError.

* platform/network/qt/QNetworkReplyHandler.cpp:
(WebCore::QNetworkReplyHandler::finish):
(WebCore::QNetworkReplyHandler::errorForReply):
* platform/network/qt/QNetworkReplyHandler.h:
* platform/network/qt/ResourceRequest.h:

Source/WebKit2:

We implement the necessary functions of Download.h, and our QtFileDownloader
to handle all network communication and call the necessary functions of Download.

We use the download policy for any MIME type not supported by WebKit. This
behaves like Qt non-WebKit2 except that we don't force download when
we encounter Content-Disposition: attachment. We still use the "filename="
field for file name suggestion though.

Based on original patches by: Kimmo Kinnunen <kimmo.t.kinnu...@nokia.com>,
Jocelyn Turcotte <jocelyn.turco...@nokia.com>, Simon Hausmann <simon.hausm...@nokia.com>
and Zalan Bujtas <zalan.buj...@nokia.com>.

* UIProcess/API/qt/qweberror.cpp: Adding DownloadError
(QWebError::type):
* UIProcess/API/qt/qweberror.h: Adding DownloadError
* WebKit2.pro:
* WebProcess/Downloads/Download.cpp: Adding QtFileDownloader, Qt platform specific
(WebKit::Download::Download):
* WebProcess/Downloads/Download.h: Adding QtFileDownloader, Qt platform specific
* WebProcess/Downloads/qt/DownloadQt.cpp:
(WebKit::Download::start):
(WebKit::Download::startWithHandle):
(WebKit::Download::cancel):
(WebKit::Download::platformInvalidate):
(WebKit::Download::didDecideDestination):
* WebProcess/Downloads/qt/QtFileDownloader.cpp: Added.
(WebKit::QtFileDownloader::QtFileDownloader):
(WebKit::QtFileDownloader::~QtFileDownloader):
(WebKit::QtFileDownloader::determineFilename):
(WebKit::QtFileDownloader::decidedDestination):
(WebKit::QtFileDownloader::abortDownloadWritingAndEmitError):
(WebKit::QtFileDownloader::onReadyRead):
(WebKit::QtFileDownloader::onFinished):
(WebKit::QtFileDownloader::onError):
(WebKit::QtFileDownloader::cancel):
* WebProcess/Downloads/qt/QtFileDownloader.h: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (95630 => 95631)


--- trunk/Source/WebCore/ChangeLog	2011-09-21 14:59:13 UTC (rev 95630)
+++ trunk/Source/WebCore/ChangeLog	2011-09-21 15:10:43 UTC (rev 95631)
@@ -1,3 +1,21 @@
+2011-09-21  Jesus Sanchez-Palencia  <jesus.palen...@openbossa.org>
+
+        [Qt][WK2] Implement Download support in WebProcess
+        https://bugs.webkit.org/show_bug.cgi?id=68153
+
+        Reviewed by Andreas Kling.
+
+        Refactored QNetworkReplyHandler::finish() in order to add
+        and use the static function QNetworkReplyHandler::errorForReply().
+        This will be used by our Download implementation in WebKit2 (WebProcess)
+        when handling ResourceError.
+
+        * platform/network/qt/QNetworkReplyHandler.cpp:
+        (WebCore::QNetworkReplyHandler::finish):
+        (WebCore::QNetworkReplyHandler::errorForReply):
+        * platform/network/qt/QNetworkReplyHandler.h:
+        * platform/network/qt/ResourceRequest.h:
+
 2011-09-21  Pavel Feldman  <pfeld...@google.com>
 
         Web Inspector: paint box model colors in Metrics sidebar at all times, do not draw box outlines.

Modified: trunk/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp (95630 => 95631)


--- trunk/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp	2011-09-21 14:59:13 UTC (rev 95630)
+++ trunk/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp	2011-09-21 15:10:43 UTC (rev 95631)
@@ -455,19 +455,9 @@
 
     if (!m_replyWrapper->reply()->error() || shouldIgnoreHttpError(m_replyWrapper->reply(), m_replyWrapper->responseContainsData()))
         client->didFinishLoading(m_resourceHandle, 0);
-    else {
-        QUrl url = ""
-        int httpStatusCode = m_replyWrapper->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+    else
+        client->didFail(m_resourceHandle, errorForReply(m_replyWrapper->reply()));
 
-        if (httpStatusCode) {
-            ResourceError error("HTTP", httpStatusCode, url.toString(), m_replyWrapper->reply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString());
-            client->didFail(m_resourceHandle, error);
-        } else {
-            ResourceError error("QtNetwork", m_replyWrapper->reply()->error(), url.toString(), m_replyWrapper->reply()->errorString());
-            client->didFail(m_resourceHandle, error);
-        }
-    }
-
     m_replyWrapper = nullptr;
 }
 
@@ -694,6 +684,17 @@
         connect(m_replyWrapper->reply(), SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64, qint64)));
 }
 
+ResourceError QNetworkReplyHandler::errorForReply(QNetworkReply* reply)
+{
+    QUrl url = ""
+    int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+
+    if (httpStatusCode)
+        return ResourceError("HTTP", httpStatusCode, url.toString(), reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString());
+
+    return ResourceError("QtNetwork", reply->error(), url.toString(), reply->errorString());
 }
 
+}
+
 #include "moc_QNetworkReplyHandler.cpp"

Modified: trunk/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h (95630 => 95631)


--- trunk/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h	2011-09-21 14:59:13 UTC (rev 95630)
+++ trunk/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h	2011-09-21 15:10:43 UTC (rev 95631)
@@ -36,6 +36,7 @@
 namespace WebCore {
 
 class FormDataIODevice;
+class ResourceError;
 class ResourceHandle;
 class ResourceRequest;
 class ResourceResponse;
@@ -133,6 +134,8 @@
     void forwardData();
     void sendResponseIfNeeded();
 
+    static ResourceError errorForReply(QNetworkReply*);
+
 private slots:
     void uploadProgress(qint64 bytesSent, qint64 bytesTotal);
 

Modified: trunk/Source/WebCore/platform/network/qt/ResourceRequest.h (95630 => 95631)


--- trunk/Source/WebCore/platform/network/qt/ResourceRequest.h	2011-09-21 14:59:13 UTC (rev 95630)
+++ trunk/Source/WebCore/platform/network/qt/ResourceRequest.h	2011-09-21 15:10:43 UTC (rev 95631)
@@ -59,7 +59,7 @@
         {
         }
 
-        QNetworkRequest toNetworkRequest(QObject* originatingObject) const;
+        QNetworkRequest toNetworkRequest(QObject* originatingObject = 0) const;
 
     private:
         friend class ResourceRequestBase;

Modified: trunk/Source/WebKit2/ChangeLog (95630 => 95631)


--- trunk/Source/WebKit2/ChangeLog	2011-09-21 14:59:13 UTC (rev 95630)
+++ trunk/Source/WebKit2/ChangeLog	2011-09-21 15:10:43 UTC (rev 95631)
@@ -1,3 +1,47 @@
+2011-09-21  Jesus Sanchez-Palencia  <jesus.palen...@openbossa.org>
+
+        [Qt][WK2] Implement Download support in WebProcess
+        https://bugs.webkit.org/show_bug.cgi?id=68153
+
+        Reviewed by Andreas Kling.
+
+        We implement the necessary functions of Download.h, and our QtFileDownloader
+        to handle all network communication and call the necessary functions of Download.
+
+        We use the download policy for any MIME type not supported by WebKit. This
+        behaves like Qt non-WebKit2 except that we don't force download when
+        we encounter Content-Disposition: attachment. We still use the "filename="
+        field for file name suggestion though.
+
+        Based on original patches by: Kimmo Kinnunen <kimmo.t.kinnu...@nokia.com>,
+        Jocelyn Turcotte <jocelyn.turco...@nokia.com>, Simon Hausmann <simon.hausm...@nokia.com>
+        and Zalan Bujtas <zalan.buj...@nokia.com>.
+
+        * UIProcess/API/qt/qweberror.cpp: Adding DownloadError
+        (QWebError::type):
+        * UIProcess/API/qt/qweberror.h: Adding DownloadError
+        * WebKit2.pro:
+        * WebProcess/Downloads/Download.cpp: Adding QtFileDownloader, Qt platform specific
+        (WebKit::Download::Download):
+        * WebProcess/Downloads/Download.h: Adding QtFileDownloader, Qt platform specific
+        * WebProcess/Downloads/qt/DownloadQt.cpp:
+        (WebKit::Download::start):
+        (WebKit::Download::startWithHandle):
+        (WebKit::Download::cancel):
+        (WebKit::Download::platformInvalidate):
+        (WebKit::Download::didDecideDestination):
+        * WebProcess/Downloads/qt/QtFileDownloader.cpp: Added.
+        (WebKit::QtFileDownloader::QtFileDownloader):
+        (WebKit::QtFileDownloader::~QtFileDownloader):
+        (WebKit::QtFileDownloader::determineFilename):
+        (WebKit::QtFileDownloader::decidedDestination):
+        (WebKit::QtFileDownloader::abortDownloadWritingAndEmitError):
+        (WebKit::QtFileDownloader::onReadyRead):
+        (WebKit::QtFileDownloader::onFinished):
+        (WebKit::QtFileDownloader::onError):
+        (WebKit::QtFileDownloader::cancel):
+        * WebProcess/Downloads/qt/QtFileDownloader.h: Added.
+
 2011-09-21  Mark Rowe  <mr...@apple.com>
 
         <rdar://problem/9890932> "Open PDF in Preview" on two PDFs of the same name does nothing the second time

Modified: trunk/Source/WebKit2/UIProcess/API/qt/qweberror.cpp (95630 => 95631)


--- trunk/Source/WebKit2/UIProcess/API/qt/qweberror.cpp	2011-09-21 14:59:13 UTC (rev 95630)
+++ trunk/Source/WebKit2/UIProcess/API/qt/qweberror.cpp	2011-09-21 15:10:43 UTC (rev 95631)
@@ -65,6 +65,8 @@
         return QWebError::NetworkError;
     if (errorDomain == "HTTP")
         return QWebError::HttpError;
+    if (errorDomain == "Download")
+        return QWebError::DownloadError;
     // FIXME: Redirection overflow currently puts the URL hostname in the errorDomain field.
     //        We should expose that error somehow. Source is QNetworkReplyHandler::redirect().
     return QWebError::EngineError;

Modified: trunk/Source/WebKit2/UIProcess/API/qt/qweberror.h (95630 => 95631)


--- trunk/Source/WebKit2/UIProcess/API/qt/qweberror.h	2011-09-21 14:59:13 UTC (rev 95630)
+++ trunk/Source/WebKit2/UIProcess/API/qt/qweberror.h	2011-09-21 15:10:43 UTC (rev 95631)
@@ -36,7 +36,8 @@
     enum Type {
         EngineError,
         NetworkError,
-        HttpError
+        HttpError,
+        DownloadError
     };
 
     Type type() const;

Modified: trunk/Source/WebKit2/WebKit2.pro (95630 => 95631)


--- trunk/Source/WebKit2/WebKit2.pro	2011-09-21 14:59:13 UTC (rev 95630)
+++ trunk/Source/WebKit2/WebKit2.pro	2011-09-21 15:10:43 UTC (rev 95631)
@@ -271,6 +271,7 @@
     WebProcess/Cookies/WebCookieManager.h \
     WebProcess/Downloads/Download.h \
     WebProcess/Downloads/DownloadManager.h \
+    WebProcess/Downloads/qt/QtFileDownloader.h \
     WebProcess/FullScreen/WebFullScreenManager.h \
     WebProcess/FullScreen/qt/WebFullScreenManagerQt.h \
     WebProcess/Geolocation/GeolocationPermissionRequestManager.h \
@@ -513,6 +514,7 @@
     WebProcess/Downloads/Download.cpp \
     WebProcess/Downloads/DownloadManager.cpp \
     WebProcess/Downloads/qt/DownloadQt.cpp \
+    WebProcess/Downloads/qt/QtFileDownloader.cpp \
     WebProcess/FullScreen/WebFullScreenManager.cpp \
     WebProcess/FullScreen/qt/WebFullScreenManagerQt.cpp \
     WebProcess/Geolocation/GeolocationPermissionRequestManager.cpp \
@@ -524,7 +526,7 @@
     WebProcess/InjectedBundle/InjectedBundleBackForwardList.cpp \
     WebProcess/InjectedBundle/InjectedBundleBackForwardListItem.cpp \
     WebProcess/InjectedBundle/InjectedBundleClient.cpp \
-    WebProcess/InjectedBundle/InjectedBundleHitTestResult.cpp \    
+    WebProcess/InjectedBundle/InjectedBundleHitTestResult.cpp \
     WebProcess/InjectedBundle/InjectedBundleNavigationAction.cpp \
     WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp \
     WebProcess/InjectedBundle/InjectedBundlePageEditorClient.cpp \

Modified: trunk/Source/WebKit2/WebProcess/Downloads/Download.cpp (95630 => 95631)


--- trunk/Source/WebKit2/WebProcess/Downloads/Download.cpp	2011-09-21 14:59:13 UTC (rev 95630)
+++ trunk/Source/WebKit2/WebProcess/Downloads/Download.cpp	2011-09-21 15:10:43 UTC (rev 95631)
@@ -51,6 +51,9 @@
 #if USE(CFNETWORK)
     , m_allowOverwrite(false)
 #endif
+#if PLATFORM(QT)
+    , m_qtDownloader(0)
+#endif
 {
     ASSERT(m_downloadID);
 

Modified: trunk/Source/WebKit2/WebProcess/Downloads/Download.h (95630 => 95631)


--- trunk/Source/WebKit2/WebProcess/Downloads/Download.h	2011-09-21 14:59:13 UTC (rev 95630)
+++ trunk/Source/WebKit2/WebProcess/Downloads/Download.h	2011-09-21 15:10:43 UTC (rev 95631)
@@ -60,6 +60,10 @@
 class SandboxExtension;
 class WebPage;
 
+#if PLATFORM(QT)
+class QtFileDownloader;
+#endif
+
 class Download : public CoreIPC::MessageSender<Download> {
     WTF_MAKE_NONCOPYABLE(Download);
 public:
@@ -126,6 +130,9 @@
     RetainPtr<CFURLDownloadRef> m_download;
     RefPtr<DownloadAuthenticationClient> m_authenticationClient;
 #endif
+#if PLATFORM(QT)
+    QtFileDownloader* m_qtDownloader;
+#endif
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/WebProcess/Downloads/qt/DownloadQt.cpp (95630 => 95631)


--- trunk/Source/WebKit2/WebProcess/Downloads/qt/DownloadQt.cpp	2011-09-21 14:59:13 UTC (rev 95630)
+++ trunk/Source/WebKit2/WebProcess/Downloads/qt/DownloadQt.cpp	2011-09-21 15:10:43 UTC (rev 95631)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,7 +27,13 @@
 #include "config.h"
 #include "Download.h"
 
+#include "QtFileDownloader.h"
+#include "WebProcess.h"
 #include <WebCore/NotImplemented.h>
+#include <WebCore/QNetworkReplyHandler.h>
+#include <WebCore/ResourceHandle.h>
+#include <WebCore/ResourceHandleInternal.h>
+#include <WebCore/ResourceResponse.h>
 
 using namespace WebCore;
 
@@ -34,27 +41,35 @@
 
 void Download::start(WebPage* initiatingWebPage)
 {
-    notImplemented();
+    QNetworkAccessManager* manager = WebProcess::shared().networkAccessManager();
+    ASSERT(manager);
+    ASSERT(!m_qtDownloader);
+
+    m_qtDownloader = new QtFileDownloader(this, adoptPtr(manager->get(m_request.toNetworkRequest())));
 }
 
-void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle*, const ResourceRequest& initialRequest, const ResourceResponse&)
+void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle* handle, const ResourceRequest& initialRequest, const ResourceResponse& resp)
 {
-    notImplemented();
+    ASSERT(!m_qtDownloader);
+    m_qtDownloader = new QtFileDownloader(this, adoptPtr(handle->getInternal()->m_job->release()));
 }
 
 void Download::cancel()
 {
-    notImplemented();
+    ASSERT(m_qtDownloader);
+    m_qtDownloader->cancel();
 }
 
 void Download::platformInvalidate()
 {
-    notImplemented();
+    ASSERT(m_qtDownloader);
+    m_qtDownloader->deleteLater();
+    m_qtDownloader = 0;
 }
 
 void Download::didDecideDestination(const String& destination, bool allowOverwrite)
 {
-    notImplemented();
+    m_qtDownloader->decidedDestination(destination, allowOverwrite);
 }
 
 void Download::platformDidFinish()

Added: trunk/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.cpp (0 => 95631)


--- trunk/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.cpp	                        (rev 0)
+++ trunk/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.cpp	2011-09-21 15:10:43 UTC (rev 95631)
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+#include "config.h"
+#include "QtFileDownloader.h"
+
+#include "DataReference.h"
+#include "Download.h"
+#include "HTTPParsers.h"
+#include "MIMETypeRegistry.h"
+#include <QCoreApplication>
+#include <QFile>
+#include <QFileInfo>
+#include <QNetworkAccessManager>
+#include <WebCore/QNetworkReplyHandler.h>
+#include <WebCore/ResourceError.h>
+#include <WebCore/ResourceResponse.h>
+
+using namespace WebCore;
+using namespace WTF;
+
+namespace WebKit {
+
+QtFileDownloader::QtFileDownloader(Download* download, PassOwnPtr<QNetworkReply> reply)
+    : m_download(download)
+    , m_reply(reply)
+    , m_error(QNetworkReply::NoError)
+    , m_headersRead(false)
+{
+    connect(m_reply.get(), SIGNAL(readyRead()), SLOT(onReadyRead()));
+    connect(m_reply.get(), SIGNAL(finished()), SLOT(onFinished()));
+    connect(m_reply.get(), SIGNAL(error(QNetworkReply::NetworkError)), SLOT(onError(QNetworkReply::NetworkError)));
+
+    // Call onReadyRead just in case some data is already waiting.
+    onReadyRead();
+}
+
+QtFileDownloader::~QtFileDownloader()
+{
+    if (!m_destinationFile)
+        return;
+
+    abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorAborted);
+}
+
+void QtFileDownloader::determineFilename()
+{
+    ASSERT(!m_destinationFile);
+
+    QString fileNameCandidate = filenameFromHTTPContentDisposition(QString::fromLatin1(m_reply->rawHeader("Content-Disposition")));
+    if (fileNameCandidate.isEmpty()) {
+        KURL kurl = m_reply->url();
+        fileNameCandidate = decodeURLEscapeSequences(kurl.lastPathComponent());
+    }
+
+    if (fileNameCandidate.isEmpty()) {
+        abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorCannotDetermineFilename);
+        return;
+    }
+
+    // Make sure that we remove possible "../.." parts in the given file name.
+    QFileInfo fileNameFilter(fileNameCandidate);
+    QString fileName = fileNameFilter.fileName();
+
+    if (fileName.isEmpty()) {
+        abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorCannotDetermineFilename);
+        return;
+    }
+
+    bool allowOverwrite;
+    m_download->decideDestinationWithSuggestedFilename(fileName, allowOverwrite);
+}
+
+void QtFileDownloader::decidedDestination(const QString& decidedFilePath, bool allowOverwrite)
+{
+    ASSERT(!m_destinationFile);
+
+    // Error might have occured during destination query.
+    if (m_error != QNetworkReply::NoError) {
+        abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorNetworkFailure);
+        return;
+    }
+
+    if (decidedFilePath.isEmpty()) {
+        abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorCancelledByCaller);
+        return;
+    }
+
+    OwnPtr<QFile> downloadFile = adoptPtr(new QFile(decidedFilePath));
+
+    if (!allowOverwrite && downloadFile->exists()) {
+        abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorFileAlreadyExists);
+        return;
+    }
+
+    if (!downloadFile->open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+        abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorCannotOpenFile);
+        return;
+    }
+
+    // Assigning to m_destinationFile flags that either error or
+    // finished shall be called in the end.
+    m_destinationFile = downloadFile.release();
+
+    m_download->didCreateDestination(m_destinationFile->fileName());
+
+    // We might have gotten readyRead already even before this function
+    // was called.
+    if (m_reply->bytesAvailable())
+        onReadyRead();
+
+    // We might have gotten finished already even before this
+    // function was called.
+    if (m_reply->isFinished())
+        onFinished();
+
+}
+
+void QtFileDownloader::abortDownloadWritingAndEmitError(QtFileDownloader::DownloadError errorCode)
+{
+    m_reply->abort();
+
+    // On network failures it's QNetworkReplyHandler::errorForReply who will handle errors.
+    if (errorCode == QtFileDownloader::DownloadErrorNetworkFailure) {
+        m_download->didFail(QNetworkReplyHandler::errorForReply(m_reply.get()), CoreIPC::DataReference(0, 0));
+        return;
+    }
+
+    QString translatedErrorMessage;
+    switch (errorCode) {
+    case QtFileDownloader::DownloadErrorAborted:
+        translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "Download aborted");
+        break;
+    case QtFileDownloader::DownloadErrorCannotWriteToFile:
+        translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "Cannot write to file");
+        break;
+    case QtFileDownloader::DownloadErrorCannotOpenFile:
+        translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "Cannot open file for writing");
+        break;
+    case QtFileDownloader::DownloadErrorFileAlreadyExists:
+        translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "File already exists");
+        break;
+    case QtFileDownloader::DownloadErrorCancelledByCaller:
+        translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "Download cancelled by caller");
+        break;
+    case QtFileDownloader::DownloadErrorCannotDetermineFilename:
+        translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "Cannot determine filename");
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+
+    ResourceError downloadError("Download", errorCode, m_reply->url().toString(), translatedErrorMessage);
+
+    m_download->didFail(downloadError, CoreIPC::DataReference(0, 0));
+}
+
+void QtFileDownloader::onReadyRead()
+{
+    if (m_destinationFile) {
+        QByteArray content = m_reply->readAll();
+        if (content.size() <= 0)
+            return;
+
+        qint64 bytesWritten = m_destinationFile->write(content);
+
+        if (bytesWritten == -1) {
+            abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorCannotWriteToFile);
+            return;
+        }
+
+        // There might a corner case to be fixed here if bytesWritten != content.size()
+        // does not actually represent an error.
+        ASSERT(bytesWritten == content.size());
+
+        m_download->didReceiveData(bytesWritten);
+    } else if (!m_headersRead) {
+        // By API contract, QNetworkReply::metaDataChanged cannot really be trusted.
+        // Thus we need to call this upon receiving first data.
+        String contentType = m_reply->header(QNetworkRequest::ContentTypeHeader).toString();
+        String encoding = extractCharsetFromMediaType(contentType);
+        String mimeType = extractMIMETypeFromMediaType(contentType);
+
+        // Let's try to guess from the extension.
+        if (mimeType.isEmpty())
+            mimeType = MIMETypeRegistry::getMIMETypeForPath(m_reply->url().path());
+
+        ResourceResponse response(m_reply->url(), mimeType, m_reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), encoding, String());
+        m_download->didReceiveResponse(response);
+
+        determineFilename();
+
+        m_headersRead = true;
+    }
+}
+
+void QtFileDownloader::onFinished()
+{
+    if (!m_destinationFile)
+        return;
+
+    m_destinationFile.clear();
+
+    if (m_error == QNetworkReply::NoError)
+        m_download->didFinish();
+    else
+        abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorNetworkFailure);
+}
+
+void QtFileDownloader::onError(QNetworkReply::NetworkError code)
+{
+    m_error = code;
+}
+
+void QtFileDownloader::cancel()
+{
+    m_reply->abort();
+}
+
+} // namespace WebKit
+#include "moc_QtFileDownloader.cpp"

Added: trunk/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.h (0 => 95631)


--- trunk/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.h	                        (rev 0)
+++ trunk/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.h	2011-09-21 15:10:43 UTC (rev 95631)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef QtFileDownloader_h
+#define QtFileDownloader_h
+
+#include <QNetworkReply>
+#include <QNetworkRequest>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+
+QT_BEGIN_NAMESPACE
+class QFile;
+class QNetworkAccessManager;
+class QNetworkRequest;
+QT_END_NAMESPACE
+
+namespace WebCore {
+class ResourceError;
+}
+
+namespace WebKit {
+class Download;
+
+class QtFileDownloader : public QObject {
+    Q_OBJECT
+public:
+    QtFileDownloader(Download*, PassOwnPtr<QNetworkReply>);
+    virtual ~QtFileDownloader();
+    void decidedDestination(const QString& decidedFilePath, bool allowOverwrite);
+    void cancel();
+
+    enum DownloadError {
+        DownloadErrorAborted = 0,
+        DownloadErrorCannotWriteToFile,
+        DownloadErrorCannotOpenFile,
+        DownloadErrorFileAlreadyExists,
+        DownloadErrorCancelledByCaller,
+        DownloadErrorCannotDetermineFilename,
+        DownloadErrorNetworkFailure
+    };
+
+private slots:
+    void onReadyRead();
+    void onFinished();
+    void onError(QNetworkReply::NetworkError);
+
+private:
+    void abortDownloadWritingAndEmitError(QtFileDownloader::DownloadError);
+    void determineFilename();
+
+    Download* m_download;
+    OwnPtr<QNetworkReply> m_reply;
+    OwnPtr<QFile> m_destinationFile;
+    QNetworkReply::NetworkError m_error;
+    bool m_headersRead;
+};
+
+} // namespace WebKit
+
+#endif
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to