1/* 2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "WebResourceLoader.h" 28 29#if ENABLE(NETWORK_PROCESS) 30 31#include "DataReference.h" 32#include "Logging.h" 33#include "NetworkProcessConnection.h" 34#include "NetworkResourceLoaderMessages.h" 35#include "WebCoreArgumentCoders.h" 36#include "WebErrors.h" 37#include "WebProcess.h" 38#include <WebCore/ApplicationCacheHost.h> 39#include <WebCore/CertificateInfo.h> 40#include <WebCore/DocumentLoader.h> 41#include <WebCore/ResourceBuffer.h> 42#include <WebCore/ResourceError.h> 43#include <WebCore/ResourceLoader.h> 44 45using namespace WebCore; 46 47namespace WebKit { 48 49PassRefPtr<WebResourceLoader> WebResourceLoader::create(PassRefPtr<ResourceLoader> coreLoader) 50{ 51 return adoptRef(new WebResourceLoader(coreLoader)); 52} 53 54WebResourceLoader::WebResourceLoader(PassRefPtr<WebCore::ResourceLoader> coreLoader) 55 : m_coreLoader(coreLoader) 56{ 57} 58 59WebResourceLoader::~WebResourceLoader() 60{ 61} 62 63IPC::Connection* WebResourceLoader::messageSenderConnection() 64{ 65 return WebProcess::shared().networkConnection()->connection(); 66} 67 68uint64_t WebResourceLoader::messageSenderDestinationID() 69{ 70 return m_coreLoader->identifier(); 71} 72 73void WebResourceLoader::cancelResourceLoader() 74{ 75 m_coreLoader->cancel(); 76} 77 78void WebResourceLoader::detachFromCoreLoader() 79{ 80 m_coreLoader = 0; 81} 82 83void WebResourceLoader::willSendRequest(const ResourceRequest& proposedRequest, const ResourceResponse& redirectResponse) 84{ 85 LOG(Network, "(WebProcess) WebResourceLoader::willSendRequest to '%s'", proposedRequest.url().string().utf8().data()); 86 87 Ref<WebResourceLoader> protect(*this); 88 89 ResourceRequest newRequest = proposedRequest; 90 if (m_coreLoader->documentLoader()->applicationCacheHost()->maybeLoadFallbackForRedirect(m_coreLoader.get(), newRequest, redirectResponse)) 91 return; 92 m_coreLoader->willSendRequest(newRequest, redirectResponse); 93 94 if (!m_coreLoader) 95 return; 96 97 send(Messages::NetworkResourceLoader::ContinueWillSendRequest(newRequest)); 98} 99 100void WebResourceLoader::didSendData(uint64_t bytesSent, uint64_t totalBytesToBeSent) 101{ 102 m_coreLoader->didSendData(bytesSent, totalBytesToBeSent); 103} 104 105void WebResourceLoader::didReceiveResponseWithCertificateInfo(const ResourceResponse& response, const CertificateInfo& certificateInfo, bool needsContinueDidReceiveResponseMessage) 106{ 107 LOG(Network, "(WebProcess) WebResourceLoader::didReceiveResponseWithCertificateInfo for '%s'. Status %d.", m_coreLoader->url().string().utf8().data(), response.httpStatusCode()); 108 109 Ref<WebResourceLoader> protect(*this); 110 111 ResourceResponse responseCopy(response); 112 113 // FIXME: This should use CertificateInfo to avoid the platform ifdefs. See https://bugs.webkit.org/show_bug.cgi?id=124724. 114#if PLATFORM(COCOA) 115 responseCopy.setCertificateChain(certificateInfo.certificateChain()); 116#elif USE(SOUP) 117 responseCopy.setSoupMessageCertificate(certificateInfo.certificate()); 118 responseCopy.setSoupMessageTLSErrors(certificateInfo.tlsErrors()); 119#endif 120 121 if (m_coreLoader->documentLoader()->applicationCacheHost()->maybeLoadFallbackForResponse(m_coreLoader.get(), responseCopy)) 122 return; 123 124#if USE(QUICK_LOOK) 125 // Refrain from calling didReceiveResponse if QuickLook will convert this response, since the MIME type of the 126 // converted resource isn't yet known. WebResourceLoaderQuickLookDelegate will later call didReceiveResponse upon 127 // receiving the converted data. 128 m_coreLoader->documentLoader()->setQuickLookHandle(QuickLookHandle::create(resourceLoader(), responseCopy.nsURLResponse())); 129 if (!m_coreLoader->documentLoader()->quickLookHandle()) 130#endif 131 m_coreLoader->didReceiveResponse(responseCopy); 132 133 // If m_coreLoader becomes null as a result of the didReceiveResponse callback, we can't use the send function(). 134 if (!m_coreLoader) 135 return; 136 137 if (needsContinueDidReceiveResponseMessage) 138 send(Messages::NetworkResourceLoader::ContinueDidReceiveResponse()); 139} 140 141void WebResourceLoader::didReceiveData(const IPC::DataReference& data, int64_t encodedDataLength) 142{ 143 LOG(Network, "(WebProcess) WebResourceLoader::didReceiveData of size %i for '%s'", (int)data.size(), m_coreLoader->url().string().utf8().data()); 144 145#if USE(QUICK_LOOK) 146 if (QuickLookHandle* quickLookHandle = m_coreLoader->documentLoader()->quickLookHandle()) { 147 if (quickLookHandle->didReceiveData(adoptCF(CFDataCreate(kCFAllocatorDefault, data.data(), data.size())).get())) 148 return; 149 } 150#endif 151 m_coreLoader->didReceiveData(reinterpret_cast<const char*>(data.data()), data.size(), encodedDataLength, DataPayloadBytes); 152} 153 154void WebResourceLoader::didFinishResourceLoad(double finishTime) 155{ 156 LOG(Network, "(WebProcess) WebResourceLoader::didFinishResourceLoad for '%s'", m_coreLoader->url().string().utf8().data()); 157 158#if USE(QUICK_LOOK) 159 if (QuickLookHandle* quickLookHandle = m_coreLoader->documentLoader()->quickLookHandle()) { 160 if (quickLookHandle->didFinishLoading()) 161 return; 162 } 163#endif 164 m_coreLoader->didFinishLoading(finishTime); 165} 166 167void WebResourceLoader::didFailResourceLoad(const ResourceError& error) 168{ 169 LOG(Network, "(WebProcess) WebResourceLoader::didFailResourceLoad for '%s'", m_coreLoader->url().string().utf8().data()); 170 171#if USE(QUICK_LOOK) 172 if (QuickLookHandle* quickLookHandle = m_coreLoader->documentLoader()->quickLookHandle()) 173 quickLookHandle->didFail(); 174#endif 175 if (m_coreLoader->documentLoader()->applicationCacheHost()->maybeLoadFallbackForError(m_coreLoader.get(), error)) 176 return; 177 m_coreLoader->didFail(error); 178} 179 180#if ENABLE(SHAREABLE_RESOURCE) 181void WebResourceLoader::didReceiveResource(const ShareableResource::Handle& handle, double finishTime) 182{ 183 LOG(Network, "(WebProcess) WebResourceLoader::didReceiveResource for '%s'", m_coreLoader->url().string().utf8().data()); 184 185#if USE(QUICK_LOOK) 186 if (QuickLookHandle* quickLookHandle = m_coreLoader->documentLoader()->quickLookHandle()) { 187 RetainPtr<CFDataRef> cfBuffer = handle.tryWrapInCFData(); 188 if (cfBuffer) { 189 if (quickLookHandle->didReceiveData(cfBuffer.get())) { 190 quickLookHandle->didFinishLoading(); 191 return; 192 } 193 } else 194 quickLookHandle->didFail(); 195 } 196#endif 197 198 RefPtr<SharedBuffer> buffer = handle.tryWrapInSharedBuffer(); 199 if (!buffer) { 200 LOG_ERROR("Unable to create buffer from ShareableResource sent from the network process."); 201 m_coreLoader->didFail(internalError(m_coreLoader->request().url())); 202 return; 203 } 204 205 Ref<WebResourceLoader> protect(*this); 206 207 // Only send data to the didReceiveData callback if it exists. 208 if (buffer->size()) 209 m_coreLoader->didReceiveBuffer(buffer.get(), buffer->size(), DataPayloadWholeResource); 210 211 if (!m_coreLoader) 212 return; 213 214 m_coreLoader->didFinishLoading(finishTime); 215} 216#endif 217 218#if USE(PROTECTION_SPACE_AUTH_CALLBACK) 219void WebResourceLoader::canAuthenticateAgainstProtectionSpace(const ProtectionSpace& protectionSpace) 220{ 221 Ref<WebResourceLoader> protect(*this); 222 223 bool result = m_coreLoader->canAuthenticateAgainstProtectionSpace(protectionSpace); 224 225 if (!m_coreLoader) 226 return; 227 228 send(Messages::NetworkResourceLoader::ContinueCanAuthenticateAgainstProtectionSpace(result)); 229} 230#endif 231 232} // namespace WebKit 233 234#endif // ENABLE(NETWORK_PROCESS) 235