1 /* 2 * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. 3 * Copyright (C) 2005, 2006 Michael Emmel mike.emmel (at) gmail.com 4 * All rights reserved. 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 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "config.h" 29 #include "ResourceHandle.h" 30 31 #include "CachedResourceLoader.h" 32 #include "NotImplemented.h" 33 #include "ResourceHandleInternal.h" 34 #include "ResourceHandleManager.h" 35 #include "SharedBuffer.h" 36 37 #if PLATFORM(WIN) && USE(CF) 38 #include <wtf/PassRefPtr.h> 39 #include <wtf/RetainPtr.h> 40 #endif 41 42 namespace WebCore { 43 44 class WebCoreSynchronousLoader : public ResourceHandleClient { 45 public: 46 WebCoreSynchronousLoader(); 47 48 virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); 49 virtual void didReceiveData(ResourceHandle*, const char*, int, int encodedDataLength); 50 virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); 51 virtual void didFail(ResourceHandle*, const ResourceError&); 52 53 ResourceResponse resourceResponse() const { return m_response; } 54 ResourceError resourceError() const { return m_error; } 55 Vector<char> data() const { return m_data; } 56 57 private: 58 ResourceResponse m_response; 59 ResourceError m_error; 60 Vector<char> m_data; 61 }; 62 63 WebCoreSynchronousLoader::WebCoreSynchronousLoader() 64 { 65 } 66 67 void WebCoreSynchronousLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) 68 { 69 m_response = response; 70 } 71 72 void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, int length, int) 73 { 74 m_data.append(data, length); 75 } 76 77 void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*, double) 78 { 79 } 80 81 void WebCoreSynchronousLoader::didFail(ResourceHandle*, const ResourceError& error) 82 { 83 m_error = error; 84 } 85 86 ResourceHandleInternal::~ResourceHandleInternal() 87 { 88 fastFree(m_url); 89 if (m_customHeaders) 90 curl_slist_free_all(m_customHeaders); 91 } 92 93 ResourceHandle::~ResourceHandle() 94 { 95 cancel(); 96 } 97 98 bool ResourceHandle::start(NetworkingContext* context) 99 { 100 // The frame could be null if the ResourceHandle is not associated to any 101 // Frame, e.g. if we are downloading a file. 102 // If the frame is not null but the page is null this must be an attempted 103 // load from an unload handler, so let's just block it. 104 // If both the frame and the page are not null the context is valid. 105 if (context && !context->isValid()) 106 return false; 107 108 ResourceHandleManager::sharedInstance()->add(this); 109 return true; 110 } 111 112 void ResourceHandle::cancel() 113 { 114 ResourceHandleManager::sharedInstance()->cancel(this); 115 } 116 117 PassRefPtr<SharedBuffer> ResourceHandle::bufferedData() 118 { 119 return 0; 120 } 121 122 bool ResourceHandle::supportsBufferedData() 123 { 124 return false; 125 } 126 127 #if PLATFORM(WIN) && USE(CF) 128 static HashSet<String>& allowsAnyHTTPSCertificateHosts() 129 { 130 static HashSet<String> hosts; 131 132 return hosts; 133 } 134 135 void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host) 136 { 137 allowsAnyHTTPSCertificateHosts().add(host.lower()); 138 } 139 #endif 140 141 #if PLATFORM(WIN) && USE(CF) 142 // FIXME: The CFDataRef will need to be something else when 143 // building without 144 static HashMap<String, RetainPtr<CFDataRef> >& clientCerts() 145 { 146 static HashMap<String, RetainPtr<CFDataRef> > certs; 147 return certs; 148 } 149 150 void ResourceHandle::setClientCertificate(const String& host, CFDataRef cert) 151 { 152 clientCerts().set(host.lower(), cert); 153 } 154 #endif 155 156 void ResourceHandle::platformSetDefersLoading(bool defers) 157 { 158 #if LIBCURL_VERSION_NUM > 0x071200 159 if (!d->m_handle) 160 return; 161 162 if (defers) { 163 CURLcode error = curl_easy_pause(d->m_handle, CURLPAUSE_ALL); 164 // If we could not defer the handle, so don't do it. 165 if (error != CURLE_OK) 166 return; 167 } else { 168 CURLcode error = curl_easy_pause(d->m_handle, CURLPAUSE_CONT); 169 if (error != CURLE_OK) 170 // Restarting the handle has failed so just cancel it. 171 cancel(); 172 } 173 #else 174 LOG_ERROR("Deferred loading is implemented if libcURL version is above 7.18.0"); 175 #endif 176 } 177 178 bool ResourceHandle::willLoadFromCache(ResourceRequest&, Frame*) 179 { 180 notImplemented(); 181 return false; 182 } 183 184 bool ResourceHandle::loadsBlocked() 185 { 186 notImplemented(); 187 return false; 188 } 189 190 void ResourceHandle::loadResourceSynchronously(NetworkingContext*, const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data) 191 { 192 WebCoreSynchronousLoader syncLoader; 193 RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, &syncLoader, true, false)); 194 195 ResourceHandleManager* manager = ResourceHandleManager::sharedInstance(); 196 197 manager->dispatchSynchronousJob(handle.get()); 198 199 error = syncLoader.resourceError(); 200 data = syncLoader.data(); 201 response = syncLoader.resourceResponse(); 202 } 203 204 //stubs needed for windows version 205 void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&) 206 { 207 notImplemented(); 208 } 209 210 void ResourceHandle::receivedCredential(const AuthenticationChallenge&, const Credential&) 211 { 212 notImplemented(); 213 } 214 215 void ResourceHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&) 216 { 217 notImplemented(); 218 } 219 220 void ResourceHandle::receivedCancellation(const AuthenticationChallenge&) 221 { 222 notImplemented(); 223 } 224 225 } // namespace WebCore 226