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