ResourceHandleCurl.cpp [plain text]
#include "config.h"
#include "ResourceHandle.h"
#include "CachedResourceLoader.h"
#include "NotImplemented.h"
#include "ResourceHandleInternal.h"
#include "ResourceHandleManager.h"
#include "SharedBuffer.h"
#if PLATFORM(WIN) && USE(CF)
#include <wtf/PassRefPtr.h>
#include <wtf/RetainPtr.h>
#endif
namespace WebCore {
class WebCoreSynchronousLoader : public ResourceHandleClient {
public:
WebCoreSynchronousLoader();
virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
virtual void didReceiveData(ResourceHandle*, const char*, int, int encodedDataLength);
virtual void didFinishLoading(ResourceHandle*, double );
virtual void didFail(ResourceHandle*, const ResourceError&);
ResourceResponse resourceResponse() const { return m_response; }
ResourceError resourceError() const { return m_error; }
Vector<char> data() const { return m_data; }
private:
ResourceResponse m_response;
ResourceError m_error;
Vector<char> m_data;
};
WebCoreSynchronousLoader::WebCoreSynchronousLoader()
{
}
void WebCoreSynchronousLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
{
m_response = response;
}
void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, int length, int)
{
m_data.append(data, length);
}
void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*, double)
{
}
void WebCoreSynchronousLoader::didFail(ResourceHandle*, const ResourceError& error)
{
m_error = error;
}
ResourceHandleInternal::~ResourceHandleInternal()
{
fastFree(m_url);
if (m_customHeaders)
curl_slist_free_all(m_customHeaders);
}
ResourceHandle::~ResourceHandle()
{
cancel();
}
bool ResourceHandle::start(NetworkingContext* context)
{
if (context && !context->isValid())
return false;
ResourceHandleManager::sharedInstance()->add(this);
return true;
}
void ResourceHandle::cancel()
{
ResourceHandleManager::sharedInstance()->cancel(this);
}
#if PLATFORM(WIN) && USE(CF)
static HashSet<String>& allowsAnyHTTPSCertificateHosts()
{
static HashSet<String> hosts;
return hosts;
}
void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host)
{
allowsAnyHTTPSCertificateHosts().add(host.lower());
}
#endif
#if PLATFORM(WIN) && USE(CF)
static HashMap<String, RetainPtr<CFDataRef> >& clientCerts()
{
static HashMap<String, RetainPtr<CFDataRef> > certs;
return certs;
}
void ResourceHandle::setClientCertificate(const String& host, CFDataRef cert)
{
clientCerts().set(host.lower(), cert);
}
#endif
void ResourceHandle::platformSetDefersLoading(bool defers)
{
#if LIBCURL_VERSION_NUM > 0x071200
if (!d->m_handle)
return;
if (defers) {
CURLcode error = curl_easy_pause(d->m_handle, CURLPAUSE_ALL);
if (error != CURLE_OK)
return;
} else {
CURLcode error = curl_easy_pause(d->m_handle, CURLPAUSE_CONT);
if (error != CURLE_OK)
cancel();
}
#else
LOG_ERROR("Deferred loading is implemented if libcURL version is above 7.18.0");
#endif
}
bool ResourceHandle::willLoadFromCache(ResourceRequest&, Frame*)
{
notImplemented();
return false;
}
bool ResourceHandle::loadsBlocked()
{
notImplemented();
return false;
}
void ResourceHandle::loadResourceSynchronously(NetworkingContext*, const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data)
{
WebCoreSynchronousLoader syncLoader;
RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, &syncLoader, true, false));
ResourceHandleManager* manager = ResourceHandleManager::sharedInstance();
manager->dispatchSynchronousJob(handle.get());
error = syncLoader.resourceError();
data = syncLoader.data();
response = syncLoader.resourceResponse();
}
void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&)
{
notImplemented();
}
void ResourceHandle::receivedCredential(const AuthenticationChallenge&, const Credential&)
{
notImplemented();
}
void ResourceHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&)
{
notImplemented();
}
void ResourceHandle::receivedCancellation(const AuthenticationChallenge&)
{
notImplemented();
}
}