ResourceHandle.cpp revision cad810f21b803229eb11403f9209855525a25d57
1/* 2 * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010 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 COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "ResourceHandle.h" 28#include "ResourceHandleInternal.h" 29 30#include "BlobRegistry.h" 31#include "DNS.h" 32#include "Logging.h" 33#include "ResourceHandleClient.h" 34#include "Timer.h" 35#include <algorithm> 36 37namespace WebCore { 38 39static bool shouldForceContentSniffing; 40 41ResourceHandle::ResourceHandle(const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff) 42 : d(new ResourceHandleInternal(this, request, client, defersLoading, shouldContentSniff && shouldContentSniffURL(request.url()))) 43{ 44 if (!request.url().isValid()) { 45 scheduleFailure(InvalidURLFailure); 46 return; 47 } 48 49 if (!portAllowed(request.url())) { 50 scheduleFailure(BlockedFailure); 51 return; 52 } 53} 54 55PassRefPtr<ResourceHandle> ResourceHandle::create(NetworkingContext* context, const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff) 56{ 57#if ENABLE(BLOB) 58 if (request.url().protocolIs("blob")) { 59 PassRefPtr<ResourceHandle> handle = blobRegistry().createResourceHandle(request, client); 60 if (handle) 61 return handle; 62 } 63#endif 64 65 RefPtr<ResourceHandle> newHandle(adoptRef(new ResourceHandle(request, client, defersLoading, shouldContentSniff))); 66 67 if (newHandle->d->m_scheduledFailureType != NoFailure) 68 return newHandle.release(); 69 70 if (newHandle->start(context)) 71 return newHandle.release(); 72 73 return 0; 74} 75 76void ResourceHandle::scheduleFailure(FailureType type) 77{ 78 d->m_scheduledFailureType = type; 79 d->m_failureTimer.startOneShot(0); 80} 81 82void ResourceHandle::fireFailure(Timer<ResourceHandle>*) 83{ 84 if (!client()) 85 return; 86 87 switch (d->m_scheduledFailureType) { 88 case NoFailure: 89 ASSERT_NOT_REACHED(); 90 return; 91 case BlockedFailure: 92 d->m_scheduledFailureType = NoFailure; 93 client()->wasBlocked(this); 94 return; 95 case InvalidURLFailure: 96 d->m_scheduledFailureType = NoFailure; 97 client()->cannotShowURL(this); 98 return; 99 } 100 101 ASSERT_NOT_REACHED(); 102} 103 104ResourceHandleClient* ResourceHandle::client() const 105{ 106 return d->m_client; 107} 108 109void ResourceHandle::setClient(ResourceHandleClient* client) 110{ 111 d->m_client = client; 112} 113 114ResourceRequest& ResourceHandle::firstRequest() 115{ 116 return d->m_firstRequest; 117} 118 119const String& ResourceHandle::lastHTTPMethod() const 120{ 121 return d->m_lastHTTPMethod; 122} 123 124bool ResourceHandle::hasAuthenticationChallenge() const 125{ 126 return !d->m_currentWebChallenge.isNull(); 127} 128 129void ResourceHandle::clearAuthentication() 130{ 131#if PLATFORM(MAC) 132 d->m_currentMacChallenge = nil; 133#endif 134 d->m_currentWebChallenge.nullify(); 135} 136 137bool ResourceHandle::shouldContentSniff() const 138{ 139 return d->m_shouldContentSniff; 140} 141 142bool ResourceHandle::shouldContentSniffURL(const KURL& url) 143{ 144#if PLATFORM(MAC) 145 if (shouldForceContentSniffing) 146 return true; 147#endif 148 // We shouldn't content sniff file URLs as their MIME type should be established via their extension. 149 return !url.protocolIs("file"); 150} 151 152void ResourceHandle::forceContentSniffing() 153{ 154 shouldForceContentSniffing = true; 155} 156 157void ResourceHandle::setDefersLoading(bool defers) 158{ 159 LOG(Network, "Handle %p setDefersLoading(%s)", this, defers ? "true" : "false"); 160 161 ASSERT(d->m_defersLoading != defers); // Deferring is not counted, so calling setDefersLoading() repeatedly is likely to be in error. 162 d->m_defersLoading = defers; 163 164 if (defers) { 165 ASSERT(d->m_failureTimer.isActive() == (d->m_scheduledFailureType != NoFailure)); 166 if (d->m_failureTimer.isActive()) 167 d->m_failureTimer.stop(); 168 } else if (d->m_scheduledFailureType != NoFailure) { 169 ASSERT(!d->m_failureTimer.isActive()); 170 d->m_failureTimer.startOneShot(0); 171 } 172 173 platformSetDefersLoading(defers); 174} 175 176#if !USE(SOUP) 177void ResourceHandle::prepareForURL(const KURL& url) 178{ 179 return prefetchDNS(url.host()); 180} 181#endif 182 183void ResourceHandle::cacheMetadata(const ResourceResponse&, const Vector<char>&) 184{ 185 // Optionally implemented by platform. 186} 187 188} // namespace WebCore 189