1/* 2 * Copyright (C) 2013 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#ifndef CurlDownload_h 27#define CurlDownload_h 28 29#include <WebCore/FileSystem.h> 30#include <WebCore/ResourceResponse.h> 31 32#if PLATFORM(WIN) 33#include <windows.h> 34#include <winsock2.h> 35#endif 36 37#include <curl/curl.h> 38 39class CurlDownloadManager { 40public: 41 CurlDownloadManager(); 42 ~CurlDownloadManager(); 43 44 bool add(CURL* curlHandle); 45 bool remove(CURL* curlHandle); 46 47 int getActiveDownloadCount() const; 48 int getPendingDownloadCount() const; 49 50private: 51 void startThreadIfNeeded(); 52 void stopThread(); 53 void stopThreadIfIdle(); 54 55 void updateHandleList(); 56 57 CURLM* getMultiHandle() const { return m_curlMultiHandle; } 58 59 bool runThread() const { return m_runThread; } 60 void setRunThread(bool runThread) { m_runThread = runThread; } 61 62 static void downloadThread(void* data); 63 64 ThreadIdentifier m_threadId; 65 CURLM* m_curlMultiHandle; 66 int m_activeDownloadCount; 67 Vector<CURL*> m_pendingHandleList; 68 Vector<CURL*> m_removedHandleList; 69 mutable Mutex m_mutex; 70 bool m_runThread; 71}; 72 73class CurlDownloadListener { 74public: 75 virtual void didReceiveResponse() { } 76 virtual void didReceiveDataOfLength(int size) { } 77 virtual void didFinish() { } 78 virtual void didFail() { } 79}; 80 81class CurlDownload { 82public: 83 CurlDownload(); 84 ~CurlDownload(); 85 86 void init(CurlDownloadListener*, const WebCore::KURL&); 87 bool start(); 88 bool cancel(); 89 90 String getTempPath() const; 91 String getUrl() const; 92 WebCore::ResourceResponse getResponse() const; 93 94 bool deletesFileUponFailure() const { return m_deletesFileUponFailure; } 95 void setDeletesFileUponFailure(bool deletesFileUponFailure) { m_deletesFileUponFailure = deletesFileUponFailure; } 96 97 void setDestination(const String& destination) { m_destination = destination; } 98 99private: 100 void closeFile(); 101 void moveFileToDestination(); 102 103 // Called on download thread. 104 void didReceiveHeader(const String& header); 105 void didReceiveData(void* data, int size); 106 107 // Called on main thread. 108 void didReceiveResponse(); 109 void didReceiveDataOfLength(int size); 110 void didFinish(); 111 void didFail(); 112 113 static size_t writeCallback(void* ptr, size_t, size_t nmemb, void* data); 114 static size_t headerCallback(char* ptr, size_t, size_t nmemb, void* data); 115 116 static void downloadFinishedCallback(CurlDownload*); 117 static void downloadFailedCallback(CurlDownload*); 118 static void receivedDataCallback(CurlDownload*, int size); 119 static void receivedResponseCallback(CurlDownload*); 120 121 CURL* m_curlHandle; 122 char* m_url; 123 String m_tempPath; 124 String m_destination; 125 WebCore::PlatformFileHandle m_tempHandle; 126 WebCore::ResourceResponse m_response; 127 bool m_deletesFileUponFailure; 128 mutable Mutex m_mutex; 129 CurlDownloadListener *m_listener; 130 131 static CurlDownloadManager m_downloadManager; 132 133 friend class CurlDownloadManager; 134}; 135 136#endif 137