Home | History | Annotate | Download | only in qt
      1 /*
      2  * Copyright (C) 2006 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
      4  * Copyright (C) 2008 Holger Hans Peter Freyther
      5  *
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     25  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include "config.h"
     31 
     32 #include "Frame.h"
     33 #include "DocLoader.h"
     34 #include "ResourceHandle.h"
     35 #include "ResourceHandleClient.h"
     36 #include "ResourceHandleInternal.h"
     37 #include "qwebpage_p.h"
     38 #include "qwebframe_p.h"
     39 #include "ChromeClientQt.h"
     40 #include "FrameLoaderClientQt.h"
     41 #include "Page.h"
     42 #include "QNetworkReplyHandler.h"
     43 
     44 #include "NotImplemented.h"
     45 
     46 #if QT_VERSION >= 0x040500
     47 #include <QAbstractNetworkCache>
     48 #endif
     49 #include <QCoreApplication>
     50 #include <QUrl>
     51 #include <QNetworkAccessManager>
     52 #include <QNetworkRequest>
     53 #include <QNetworkReply>
     54 
     55 namespace WebCore {
     56 
     57 class WebCoreSynchronousLoader : public ResourceHandleClient {
     58 public:
     59     WebCoreSynchronousLoader();
     60 
     61     void waitForCompletion();
     62 
     63     virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
     64     virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived);
     65     virtual void didFinishLoading(ResourceHandle*);
     66     virtual void didFail(ResourceHandle*, const ResourceError&);
     67 
     68     ResourceResponse resourceResponse() const { return m_response; }
     69     ResourceError resourceError() const { return m_error; }
     70     Vector<char> data() const { return m_data; }
     71 
     72 private:
     73     ResourceResponse m_response;
     74     ResourceError m_error;
     75     Vector<char> m_data;
     76     QEventLoop m_eventLoop;
     77 };
     78 
     79 WebCoreSynchronousLoader::WebCoreSynchronousLoader()
     80 {
     81 }
     82 
     83 void WebCoreSynchronousLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
     84 {
     85     m_response = response;
     86 }
     87 
     88 void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, int length, int)
     89 {
     90     m_data.append(data, length);
     91 }
     92 
     93 void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*)
     94 {
     95     m_eventLoop.exit();
     96 }
     97 
     98 void WebCoreSynchronousLoader::didFail(ResourceHandle*, const ResourceError& error)
     99 {
    100     m_error = error;
    101     m_eventLoop.exit();
    102 }
    103 
    104 void WebCoreSynchronousLoader::waitForCompletion()
    105 {
    106     m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
    107 }
    108 
    109 ResourceHandleInternal::~ResourceHandleInternal()
    110 {
    111 }
    112 
    113 ResourceHandle::~ResourceHandle()
    114 {
    115     if (d->m_job)
    116         cancel();
    117 }
    118 
    119 bool ResourceHandle::start(Frame* frame)
    120 {
    121     if (!frame)
    122         return false;
    123 
    124     Page *page = frame->page();
    125     // If we are no longer attached to a Page, this must be an attempted load from an
    126     // onUnload handler, so let's just block it.
    127     if (!page)
    128         return false;
    129 
    130     if (!(d->m_user.isEmpty() || d->m_pass.isEmpty())) {
    131         // If credentials were specified for this request, add them to the url,
    132         // so that they will be passed to QNetworkRequest.
    133         KURL urlWithCredentials(d->m_request.url());
    134         urlWithCredentials.setUser(d->m_user);
    135         urlWithCredentials.setPass(d->m_pass);
    136         d->m_request.setURL(urlWithCredentials);
    137     }
    138 
    139     getInternal()->m_frame = static_cast<FrameLoaderClientQt*>(frame->loader()->client())->webFrame();
    140     ResourceHandleInternal *d = getInternal();
    141     d->m_job = new QNetworkReplyHandler(this, QNetworkReplyHandler::LoadMode(d->m_defersLoading));
    142     return true;
    143 }
    144 
    145 void ResourceHandle::cancel()
    146 {
    147     if (d->m_job)
    148         d->m_job->abort();
    149 }
    150 
    151 bool ResourceHandle::loadsBlocked()
    152 {
    153     return false;
    154 }
    155 
    156 bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame* frame)
    157 {
    158     if (!frame)
    159         return false;
    160 
    161 #if QT_VERSION >= 0x040500
    162     QNetworkAccessManager* manager = QWebFramePrivate::kit(frame)->page()->networkAccessManager();
    163     QAbstractNetworkCache* cache = manager->cache();
    164 
    165     if (!cache)
    166         return false;
    167 
    168     QNetworkCacheMetaData data = cache->metaData(request.url());
    169     if (data.isValid()) {
    170         request.setCachePolicy(ReturnCacheDataDontLoad);
    171         return true;
    172     }
    173 
    174     return false;
    175 #else
    176     return false;
    177 #endif
    178 }
    179 
    180 bool ResourceHandle::supportsBufferedData()
    181 {
    182     return false;
    183 }
    184 
    185 PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
    186 {
    187     ASSERT_NOT_REACHED();
    188     return 0;
    189 }
    190 
    191 void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame* frame)
    192 {
    193     WebCoreSynchronousLoader syncLoader;
    194     ResourceHandle handle(request, &syncLoader, true, false, true);
    195 
    196     ResourceHandleInternal *d = handle.getInternal();
    197     if (!(d->m_user.isEmpty() || d->m_pass.isEmpty())) {
    198         // If credentials were specified for this request, add them to the url,
    199         // so that they will be passed to QNetworkRequest.
    200         KURL urlWithCredentials(d->m_request.url());
    201         urlWithCredentials.setUser(d->m_user);
    202         urlWithCredentials.setPass(d->m_pass);
    203         d->m_request.setURL(urlWithCredentials);
    204     }
    205     d->m_frame = static_cast<FrameLoaderClientQt*>(frame->loader()->client())->webFrame();
    206     d->m_job = new QNetworkReplyHandler(&handle, QNetworkReplyHandler::LoadNormal);
    207 
    208     syncLoader.waitForCompletion();
    209     error = syncLoader.resourceError();
    210     data = syncLoader.data();
    211     response = syncLoader.resourceResponse();
    212 }
    213 
    214 
    215 void ResourceHandle::setDefersLoading(bool defers)
    216 {
    217     d->m_defersLoading = defers;
    218 
    219     if (d->m_job)
    220         d->m_job->setLoadMode(QNetworkReplyHandler::LoadMode(defers));
    221 }
    222 
    223 } // namespace WebCore
    224