1/* 2 * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@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 52namespace WebCore { 53 54class WebCoreSynchronousLoader : public ResourceHandleClient { 55public: 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; } 66private: 67 ResourceError& m_error; 68 ResourceResponse& m_response; 69 Vector<char>& m_data; 70}; 71 72ResourceHandleInternal::~ResourceHandleInternal() 73{ 74} 75 76ResourceHandle::~ResourceHandle() 77{ 78 if (d->m_job) 79 cancel(); 80} 81 82bool 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 104void ResourceHandle::cancel() 105{ 106 if (d->m_job) { 107 d->m_job->abort(); 108 d->m_job = 0; 109 } 110} 111 112bool ResourceHandle::loadsBlocked() 113{ 114 return false; 115} 116 117bool 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 141bool ResourceHandle::supportsBufferedData() 142{ 143 return false; 144} 145 146PassRefPtr<SharedBuffer> ResourceHandle::bufferedData() 147{ 148 ASSERT_NOT_REACHED(); 149 return 0; 150} 151 152void 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 173void ResourceHandle::platformSetDefersLoading(bool defers) 174{ 175 if (!d->m_job) 176 return; 177 d->m_job->setLoadingDeferred(defers); 178} 179 180} // namespace WebCore 181