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 #include "ResourceHandle.h"
     32 
     33 #include "ChromeClientQt.h"
     34 #include "CachedResourceLoader.h"
     35 #include "Frame.h"
     36 #include "FrameNetworkingContext.h"
     37 #include "FrameLoaderClientQt.h"
     38 #include "NotImplemented.h"
     39 #include "Page.h"
     40 #include "QNetworkReplyHandler.h"
     41 #include "ResourceHandleClient.h"
     42 #include "ResourceHandleInternal.h"
     43 #include "SharedBuffer.h"
     44 
     45 #include <QAbstractNetworkCache>
     46 #include <QCoreApplication>
     47 #include <QUrl>
     48 #include <QNetworkAccessManager>
     49 #include <QNetworkRequest>
     50 #include <QNetworkReply>
     51 
     52 namespace WebCore {
     53 
     54 class WebCoreSynchronousLoader : public ResourceHandleClient {
     55 public:
     56     WebCoreSynchronousLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data)
     57         : m_error(error)
     58         , m_response(response)
     59         , m_data(data)
     60     {}
     61 
     62     virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse& response) { m_response = response; }
     63     virtual void didReceiveData(ResourceHandle*, const char* data, int length, int) { m_data.append(data, length); }
     64     virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/) {}
     65     virtual void didFail(ResourceHandle*, const ResourceError& error) { m_error = error; }
     66 private:
     67     ResourceError& m_error;
     68     ResourceResponse& m_response;
     69     Vector<char>& m_data;
     70 };
     71 
     72 ResourceHandleInternal::~ResourceHandleInternal()
     73 {
     74 }
     75 
     76 ResourceHandle::~ResourceHandle()
     77 {
     78     if (d->m_job)
     79         cancel();
     80 }
     81 
     82 bool ResourceHandle::start(NetworkingContext* context)
     83 {
     84     // If NetworkingContext is invalid then we are no longer attached to a Page,
     85     // this must be an attempted load from an unload event handler, so let's just block it.
     86     if (context && !context->isValid())
     87         return false;
     88 
     89     if (!d->m_user.isEmpty() || !d->m_pass.isEmpty()) {
     90         // If credentials were specified for this request, add them to the url,
     91         // so that they will be passed to QNetworkRequest.
     92         KURL urlWithCredentials(firstRequest().url());
     93         urlWithCredentials.setUser(d->m_user);
     94         urlWithCredentials.setPass(d->m_pass);
     95         d->m_firstRequest.setURL(urlWithCredentials);
     96     }
     97 
     98     getInternal()->m_context = context;
     99     ResourceHandleInternal *d = getInternal();
    100     d->m_job = new QNetworkReplyHandler(this, QNetworkReplyHandler::AsynchronousLoad, d->m_defersLoading);
    101     return true;
    102 }
    103 
    104 void ResourceHandle::cancel()
    105 {
    106     if (d->m_job) {
    107         d->m_job->abort();
    108         d->m_job = 0;
    109     }
    110 }
    111 
    112 bool ResourceHandle::loadsBlocked()
    113 {
    114     return false;
    115 }
    116 
    117 bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame* frame)
    118 {
    119     if (!frame)
    120         return false;
    121 
    122     QNetworkAccessManager* manager = 0;
    123     QAbstractNetworkCache* cache = 0;
    124     if (frame->loader()->networkingContext()) {
    125         manager = frame->loader()->networkingContext()->networkAccessManager();
    126         cache = manager->cache();
    127     }
    128 
    129     if (!cache)
    130         return false;
    131 
    132     QNetworkCacheMetaData data = cache->metaData(request.url());
    133     if (data.isValid()) {
    134         request.setCachePolicy(ReturnCacheDataDontLoad);
    135         return true;
    136     }
    137 
    138     return false;
    139 }
    140 
    141 bool ResourceHandle::supportsBufferedData()
    142 {
    143     return false;
    144 }
    145 
    146 PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
    147 {
    148     ASSERT_NOT_REACHED();
    149     return 0;
    150 }
    151 
    152 void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data)
    153 {
    154     WebCoreSynchronousLoader syncLoader(error, response, data);
    155     RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, &syncLoader, true, false));
    156 
    157     ResourceHandleInternal* d = handle->getInternal();
    158     if (!d->m_user.isEmpty() || !d->m_pass.isEmpty()) {
    159         // If credentials were specified for this request, add them to the url,
    160         // so that they will be passed to QNetworkRequest.
    161         KURL urlWithCredentials(d->m_firstRequest.url());
    162         urlWithCredentials.setUser(d->m_user);
    163         urlWithCredentials.setPass(d->m_pass);
    164         d->m_firstRequest.setURL(urlWithCredentials);
    165     }
    166     d->m_context = context;
    167 
    168     // starting in deferred mode gives d->m_job the chance of being set before sending the request.
    169     d->m_job = new QNetworkReplyHandler(handle.get(), QNetworkReplyHandler::SynchronousLoad, true);
    170     d->m_job->setLoadingDeferred(false);
    171 }
    172 
    173 void ResourceHandle::platformSetDefersLoading(bool defers)
    174 {
    175     if (!d->m_job)
    176         return;
    177     d->m_job->setLoadingDeferred(defers);
    178 }
    179 
    180 } // namespace WebCore
    181