Home | History | Annotate | Download | only in curl
      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