1/* 2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 4 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of 16 * its contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32#include "ResourceLoadNotifier.h" 33 34#include "DocumentLoader.h" 35#include "Frame.h" 36#include "FrameLoader.h" 37#include "FrameLoaderClient.h" 38#include "InspectorInstrumentation.h" 39#include "Page.h" 40#include "ProgressTracker.h" 41#include "ResourceLoader.h" 42 43#if USE(QUICK_LOOK) 44#include "QuickLook.h" 45#endif 46 47namespace WebCore { 48 49ResourceLoadNotifier::ResourceLoadNotifier(Frame& frame) 50 : m_frame(frame) 51{ 52} 53 54void ResourceLoadNotifier::didReceiveAuthenticationChallenge(ResourceLoader* loader, const AuthenticationChallenge& currentWebChallenge) 55{ 56 didReceiveAuthenticationChallenge(loader->identifier(), loader->documentLoader(), currentWebChallenge); 57} 58 59void ResourceLoadNotifier::didReceiveAuthenticationChallenge(unsigned long identifier, DocumentLoader* loader, const AuthenticationChallenge& currentWebChallenge) 60{ 61 m_frame.loader().client().dispatchDidReceiveAuthenticationChallenge(loader, identifier, currentWebChallenge); 62} 63 64void ResourceLoadNotifier::didCancelAuthenticationChallenge(ResourceLoader* loader, const AuthenticationChallenge& currentWebChallenge) 65{ 66 didCancelAuthenticationChallenge(loader->identifier(), loader->documentLoader(), currentWebChallenge); 67} 68 69void ResourceLoadNotifier::didCancelAuthenticationChallenge(unsigned long identifier, DocumentLoader* loader, const AuthenticationChallenge& currentWebChallenge) 70{ 71 m_frame.loader().client().dispatchDidCancelAuthenticationChallenge(loader, identifier, currentWebChallenge); 72} 73 74void ResourceLoadNotifier::willSendRequest(ResourceLoader* loader, ResourceRequest& clientRequest, const ResourceResponse& redirectResponse) 75{ 76 m_frame.loader().applyUserAgent(clientRequest); 77 78 dispatchWillSendRequest(loader->documentLoader(), loader->identifier(), clientRequest, redirectResponse); 79} 80 81void ResourceLoadNotifier::didReceiveResponse(ResourceLoader* loader, const ResourceResponse& r) 82{ 83 loader->documentLoader()->addResponse(r); 84 85 if (Page* page = m_frame.page()) 86 page->progress().incrementProgress(loader->identifier(), r); 87 88 dispatchDidReceiveResponse(loader->documentLoader(), loader->identifier(), r, loader); 89} 90 91void ResourceLoadNotifier::didReceiveData(ResourceLoader* loader, const char* data, int dataLength, int encodedDataLength) 92{ 93 if (Page* page = m_frame.page()) 94 page->progress().incrementProgress(loader->identifier(), dataLength); 95 96 dispatchDidReceiveData(loader->documentLoader(), loader->identifier(), data, dataLength, encodedDataLength); 97} 98 99void ResourceLoadNotifier::didFinishLoad(ResourceLoader* loader, double finishTime) 100{ 101 if (Page* page = m_frame.page()) 102 page->progress().completeProgress(loader->identifier()); 103 dispatchDidFinishLoading(loader->documentLoader(), loader->identifier(), finishTime); 104} 105 106void ResourceLoadNotifier::didFailToLoad(ResourceLoader* loader, const ResourceError& error) 107{ 108 if (Page* page = m_frame.page()) 109 page->progress().completeProgress(loader->identifier()); 110 111 if (!error.isNull()) 112 m_frame.loader().client().dispatchDidFailLoading(loader->documentLoader(), loader->identifier(), error); 113 114 InspectorInstrumentation::didFailLoading(&m_frame, loader->documentLoader(), loader->identifier(), error); 115} 116 117void ResourceLoadNotifier::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) 118{ 119 m_frame.loader().client().assignIdentifierToInitialRequest(identifier, loader, request); 120} 121 122void ResourceLoadNotifier::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) 123{ 124#if USE(QUICK_LOOK) 125 // Always allow QuickLook-generated URLs based on the protocol scheme. 126 if (!request.isNull() && request.url().protocolIs(QLPreviewProtocol())) 127 return; 128#endif 129 130 String oldRequestURL = request.url().string(); 131 m_frame.loader().documentLoader()->didTellClientAboutLoad(request.url()); 132 133 m_frame.loader().client().dispatchWillSendRequest(loader, identifier, request, redirectResponse); 134 135 // If the URL changed, then we want to put that new URL in the "did tell client" set too. 136 if (!request.isNull() && oldRequestURL != request.url().string()) 137 m_frame.loader().documentLoader()->didTellClientAboutLoad(request.url()); 138 139 InspectorInstrumentation::willSendRequest(&m_frame, identifier, loader, request, redirectResponse); 140 141 // Report WebTiming for all frames. 142 if (loader && !request.isNull() && request.url() == loader->requestURL()) 143 request.setReportLoadTiming(true); 144 145#if ENABLE(RESOURCE_TIMING) 146 request.setReportLoadTiming(true); 147#endif 148} 149 150void ResourceLoadNotifier::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r, ResourceLoader* resourceLoader) 151{ 152 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceResponse(&m_frame, identifier, r); 153 m_frame.loader().client().dispatchDidReceiveResponse(loader, identifier, r); 154 InspectorInstrumentation::didReceiveResourceResponse(cookie, identifier, loader, r, resourceLoader); 155} 156 157void ResourceLoadNotifier::dispatchDidReceiveData(DocumentLoader* loader, unsigned long identifier, const char* data, int dataLength, int encodedDataLength) 158{ 159 m_frame.loader().client().dispatchDidReceiveContentLength(loader, identifier, dataLength); 160 161 InspectorInstrumentation::didReceiveData(&m_frame, identifier, data, dataLength, encodedDataLength); 162} 163 164void ResourceLoadNotifier::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier, double finishTime) 165{ 166 m_frame.loader().client().dispatchDidFinishLoading(loader, identifier); 167 168 InspectorInstrumentation::didFinishLoading(&m_frame, loader, identifier, finishTime); 169} 170 171void ResourceLoadNotifier::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error) 172{ 173 m_frame.loader().client().dispatchDidFailLoading(loader, identifier, error); 174 175 InspectorInstrumentation::didFailLoading(&m_frame, loader, identifier, error); 176} 177 178void ResourceLoadNotifier::sendRemainingDelegateMessages(DocumentLoader* loader, unsigned long identifier, const ResourceRequest& request, const ResourceResponse& response, const char* data, int dataLength, int encodedDataLength, const ResourceError& error) 179{ 180 // If the request is null, willSendRequest cancelled the load. We should 181 // only dispatch didFailLoading in this case. 182 if (request.isNull()) { 183 ASSERT(error.isCancellation()); 184 dispatchDidFailLoading(loader, identifier, error); 185 return; 186 } 187 188 if (!response.isNull()) 189 dispatchDidReceiveResponse(loader, identifier, response); 190 191 if (dataLength > 0) 192 dispatchDidReceiveData(loader, identifier, data, dataLength, encodedDataLength); 193 194 if (error.isNull()) 195 dispatchDidFinishLoading(loader, identifier, 0); 196 else 197 dispatchDidFailLoading(loader, identifier, error); 198} 199 200} // namespace WebCore 201