Diff
Modified: trunk/Source/WebCore/ChangeLog (218946 => 218947)
--- trunk/Source/WebCore/ChangeLog 2017-06-29 18:06:14 UTC (rev 218946)
+++ trunk/Source/WebCore/ChangeLog 2017-06-29 18:07:32 UTC (rev 218947)
@@ -1,3 +1,77 @@
+2017-06-29 Basuke Suzuki <[email protected]>
+
+ [Curl] Separate global curl settings from ResourceHandleManager as CurlContext class
+ https://bugs.webkit.org/show_bug.cgi?id=173629
+
+ Reviewed by Alex Christensen.
+
+ * PlatformWinCairo.cmake:
+ * platform/network/curl/CookieJarCurl.cpp:
+ (WebCore::setCookiesFromDOM):
+ (WebCore::cookiesForSession):
+ * platform/network/curl/CurlContext.cpp: Added.
+ (WebCore::certificatePath):
+ (WebCore::cookieJarPath):
+ (WebCore::CurlContext::CurlContext):
+ (WebCore::CurlContext::~CurlContext):
+ (WebCore::CurlContext::initCookieSession):
+ (WebCore::CurlContext::ProxyInfo::url):
+ (WebCore::CurlContext::setProxyInfo):
+ (WebCore::CurlContext::getEffectiveURL):
+ (WebCore::CurlContext::createMultiHandle):
+ (WebCore::CurlContext::mutexFor):
+ (WebCore::CurlContext::lock):
+ (WebCore::CurlContext::unlock):
+ * platform/network/curl/CurlContext.h: Added.
+ (WebCore::CurlContext::singleton):
+ (WebCore::CurlContext::curlShareHandle):
+ (WebCore::CurlContext::getCookieJarFileName):
+ (WebCore::CurlContext::setCookieJarFileName):
+ (WebCore::CurlContext::getCertificatePath):
+ (WebCore::CurlContext::shouldIgnoreSSLErrors):
+ (WebCore::CurlContext::proxyInfo):
+ (WebCore::CurlContext::setProxyInfo):
+ (WebCore::CurlContext::getLogFile):
+ (WebCore::CurlContext::isVerbose):
+ * platform/network/curl/CurlDownload.cpp:
+ (WebCore::CurlDownload::init):
+ (WebCore::CurlDownload::start):
+ (WebCore::CurlDownload::cancel):
+ (WebCore::CurlDownload::didReceiveHeader):
+ * platform/network/curl/CurlDownload.h:
+ * platform/network/curl/CurlJobManager.cpp: Renamed from Source/WebCore/platform/network/curl/CurlManager.cpp.
+ (WebCore::CurlJobManager::CurlJobManager):
+ (WebCore::CurlJobManager::~CurlJobManager):
+ (WebCore::CurlJobManager::add):
+ (WebCore::CurlJobManager::remove):
+ (WebCore::CurlJobManager::getActiveCount):
+ (WebCore::CurlJobManager::getPendingCount):
+ (WebCore::CurlJobManager::startThreadIfNeeded):
+ (WebCore::CurlJobManager::stopThread):
+ (WebCore::CurlJobManager::stopThreadIfIdle):
+ (WebCore::CurlJobManager::updateHandleList):
+ (WebCore::CurlJobManager::addToCurl):
+ (WebCore::CurlJobManager::removeFromCurl):
+ (WebCore::CurlJobManager::workerThread):
+ * platform/network/curl/CurlJobManager.h: Renamed from Source/WebCore/platform/network/curl/CurlManager.h.
+ (WebCore::CurlJobManager::singleton):
+ * platform/network/curl/ResourceHandleManager.cpp:
+ (WebCore::ResourceHandleManager::ResourceHandleManager):
+ (WebCore::ResourceHandleManager::~ResourceHandleManager):
+ (WebCore::handleLocalReceiveResponse):
+ (WebCore::getProtectionSpace):
+ (WebCore::headerCallback):
+ (WebCore::ResourceHandleManager::downloadTimerCallback):
+ (WebCore::ResourceHandleManager::initializeHandle):
+ (WebCore::certificatePath): Deleted.
+ (WebCore::cookieJarPath): Deleted.
+ (WebCore::ResourceHandleManager::setCookieJarFileName): Deleted.
+ (WebCore::ResourceHandleManager::getCookieJarFileName): Deleted.
+ (WebCore::ResourceHandleManager::setProxyInfo): Deleted.
+ (WebCore::ResourceHandleManager::initCookieSession): Deleted.
+ * platform/network/curl/ResourceHandleManager.h:
+ (): Deleted.
+
2017-06-29 Chris Dumez <[email protected]>
Avoid copying ResourceLoadStatistics objects
Modified: trunk/Source/WebCore/PlatformWinCairo.cmake (218946 => 218947)
--- trunk/Source/WebCore/PlatformWinCairo.cmake 2017-06-29 18:06:14 UTC (rev 218946)
+++ trunk/Source/WebCore/PlatformWinCairo.cmake 2017-06-29 18:07:32 UTC (rev 218947)
@@ -33,8 +33,9 @@
platform/network/curl/CredentialStorageCurl.cpp
platform/network/curl/CurlCacheEntry.cpp
platform/network/curl/CurlCacheManager.cpp
+ platform/network/curl/CurlContext.cpp
platform/network/curl/CurlDownload.cpp
- platform/network/curl/CurlManager.cpp
+ platform/network/curl/CurlJobManager.cpp
platform/network/curl/DNSCurl.cpp
platform/network/curl/FormDataStreamCurl.cpp
platform/network/curl/MultipartHandle.cpp
Modified: trunk/Source/WebCore/platform/network/curl/CookieJarCurl.cpp (218946 => 218947)
--- trunk/Source/WebCore/platform/network/curl/CookieJarCurl.cpp 2017-06-29 18:06:14 UTC (rev 218946)
+++ trunk/Source/WebCore/platform/network/curl/CookieJarCurl.cpp 2017-06-29 18:07:32 UTC (rev 218947)
@@ -22,9 +22,8 @@
#if USE(CURL)
#include "Cookie.h"
-#include "CurlManager.h"
+#include "CurlContext.h"
#include "NotImplemented.h"
-#include "ResourceHandleManager.h"
#include "URL.h"
#include <wtf/DateMath.h>
@@ -243,13 +242,15 @@
void setCookiesFromDOM(const NetworkStorageSession&, const URL&, const URL& url, const String& value)
{
+ const CurlContext& context = CurlContext::singleton();
+
CURL* curl = curl_easy_init();
if (!curl)
return;
- const char* cookieJarFileName = ResourceHandleManager::sharedInstance()->getCookieJarFileName();
- CURLSH* curlsh = CurlManager::singleton().getCurlShareHandle();
+ const char* cookieJarFileName = context.getCookieJarFileName();
+ CURLSH* curlsh = context.curlShareHandle();
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, cookieJarFileName);
curl_easy_setopt(curl, CURLOPT_SHARE, curlsh);
@@ -278,7 +279,7 @@
if (!curl)
return cookies;
- CURLSH* curlsh = CurlManager::singleton().getCurlShareHandle();
+ CURLSH* curlsh = CurlContext::singleton().curlShareHandle();
curl_easy_setopt(curl, CURLOPT_SHARE, curlsh);
Added: trunk/Source/WebCore/platform/network/curl/CurlContext.cpp (0 => 218947)
--- trunk/Source/WebCore/platform/network/curl/CurlContext.cpp (rev 0)
+++ trunk/Source/WebCore/platform/network/curl/CurlContext.cpp 2017-06-29 18:07:32 UTC (rev 218947)
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2017 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(CURL)
+#include "CurlContext.h"
+
+#include <wtf/MainThread.h>
+#include <wtf/text/CString.h>
+
+#if OS(WINDOWS)
+#include "WebCoreBundleWin.h"
+#include <shlobj.h>
+#include <shlwapi.h>
+#endif
+
+#if USE(CF)
+#include <wtf/RetainPtr.h>
+#endif
+
+using namespace WebCore;
+
+namespace WebCore {
+
+static CString certificatePath()
+{
+ char* envPath = getenv("CURL_CA_BUNDLE_PATH");
+ if (envPath)
+ return envPath;
+
+#if USE(CF)
+ CFBundleRef webKitBundleRef = webKitBundle();
+ if (webKitBundleRef) {
+ RetainPtr<CFURLRef> certURLRef = adoptCF(CFBundleCopyResourceURL(webKitBundleRef, CFSTR("cacert"), CFSTR("pem"), CFSTR("certificates")));
+ if (certURLRef) {
+ char path[MAX_PATH];
+ CFURLGetFileSystemRepresentation(certURLRef.get(), false, reinterpret_cast<UInt8*>(path), MAX_PATH);
+ return path;
+ }
+ }
+#endif
+
+ return CString();
+}
+
+static CString cookieJarPath()
+{
+ char* cookieJarPath = getenv("CURL_COOKIE_JAR_PATH");
+ if (cookieJarPath)
+ return cookieJarPath;
+
+#if OS(WINDOWS)
+ char executablePath[MAX_PATH];
+ char appDataDirectory[MAX_PATH];
+ char cookieJarFullPath[MAX_PATH];
+ char cookieJarDirectory[MAX_PATH];
+
+ if (FAILED(::SHGetFolderPathA(0, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, appDataDirectory))
+ || FAILED(::GetModuleFileNameA(0, executablePath, MAX_PATH)))
+ return "cookies.dat";
+
+ ::PathRemoveExtensionA(executablePath);
+ LPSTR executableName = ::PathFindFileNameA(executablePath);
+ sprintf_s(cookieJarDirectory, MAX_PATH, "%s/%s", appDataDirectory, executableName);
+ sprintf_s(cookieJarFullPath, MAX_PATH, "%s/cookies.dat", cookieJarDirectory);
+
+ if (::SHCreateDirectoryExA(0, cookieJarDirectory, 0) != ERROR_SUCCESS
+ && ::GetLastError() != ERROR_FILE_EXISTS
+ && ::GetLastError() != ERROR_ALREADY_EXISTS)
+ return "cookies.dat";
+
+ return cookieJarFullPath;
+#else
+ return "cookies.dat";
+#endif
+}
+
+// CurlContext -------------------------------------------------------------------
+
+CurlContext::CurlContext()
+ : m_cookieJarFileName(cookieJarPath())
+ , m_certificatePath(certificatePath())
+{
+ curl_global_init(CURL_GLOBAL_ALL);
+ m_curlShareHandle = curl_share_init();
+ curl_share_setopt(m_curlShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
+ curl_share_setopt(m_curlShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
+ curl_share_setopt(m_curlShareHandle, CURLSHOPT_LOCKFUNC, lock);
+ curl_share_setopt(m_curlShareHandle, CURLSHOPT_UNLOCKFUNC, unlock);
+
+ initCookieSession();
+
+ m_ignoreSSLErrors = getenv("WEBKIT_IGNORE_SSL_ERRORS");
+
+#ifndef NDEBUG
+ m_verbose = getenv("DEBUG_CURL");
+
+ char* logFile = getenv("CURL_LOG_FILE");
+ if (logFile)
+ m_logFile = fopen(logFile, "a");
+#endif
+}
+
+CurlContext::~CurlContext()
+{
+ curl_share_cleanup(m_curlShareHandle);
+ curl_global_cleanup();
+
+#ifndef NDEBUG
+ if (m_logFile)
+ fclose(m_logFile);
+#endif
+}
+
+// Cookie =======================
+
+void CurlContext::initCookieSession()
+{
+ // Curl saves both persistent cookies, and session cookies to the cookie file.
+ // The session cookies should be deleted before starting a new session.
+
+ CURL* curl = curl_easy_init();
+
+ if (!curl)
+ return;
+
+ curl_easy_setopt(curl, CURLOPT_SHARE, curlShareHandle());
+
+ if (!m_cookieJarFileName.isNull()) {
+ curl_easy_setopt(curl, CURLOPT_COOKIEFILE, m_cookieJarFileName);
+ curl_easy_setopt(curl, CURLOPT_COOKIEJAR, m_cookieJarFileName);
+ }
+
+ curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1);
+
+ curl_easy_cleanup(curl);
+}
+
+// Proxy =======================
+
+const String CurlContext::ProxyInfo::url() const
+{
+ String userPass;
+ if (username.length() || password.length())
+ userPass = username + ":" + password + "@";
+
+ return String("http://") + userPass + host + ":" + String::number(port);
+}
+
+void CurlContext::setProxyInfo(const String& host,
+ unsigned long port,
+ CurlProxyType type,
+ const String& username,
+ const String& password)
+{
+ ProxyInfo info;
+
+ info.host = host;
+ info.port = port;
+ info.type = type;
+ info.username = username;
+ info.password = password;
+
+ setProxyInfo(info);
+}
+
+// Curl Utilities =======================
+
+URL CurlContext::getEffectiveURL(CURL* handle)
+{
+ const char* url;
+ CURLcode err = curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url);
+ if (CURLE_OK != err)
+ return URL();
+ return URL(URL(), url);
+}
+
+CURLM* CurlContext::createMultiHandle()
+{
+ return curl_multi_init();
+}
+
+// Shared Resource management =======================
+
+Lock* CurlContext::mutexFor(curl_lock_data data)
+{
+ DEPRECATED_DEFINE_STATIC_LOCAL(Lock, cookieMutex, ());
+ DEPRECATED_DEFINE_STATIC_LOCAL(Lock, dnsMutex, ());
+ DEPRECATED_DEFINE_STATIC_LOCAL(Lock, shareMutex, ());
+
+ switch (data) {
+ case CURL_LOCK_DATA_COOKIE:
+ return &cookieMutex;
+ case CURL_LOCK_DATA_DNS:
+ return &dnsMutex;
+ case CURL_LOCK_DATA_SHARE:
+ return &shareMutex;
+ default:
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+}
+
+// libcurl does not implement its own thread synchronization primitives.
+// these two functions provide mutexes for cookies, and for the global DNS
+// cache.
+void CurlContext::lock(CURL* /* handle */, curl_lock_data data, curl_lock_access /* access */, void* /* userPtr */)
+{
+ if (Lock* mutex = mutexFor(data))
+ mutex->lock();
+}
+
+void CurlContext::unlock(CURL* /* handle */, curl_lock_data data, void* /* userPtr */)
+{
+ if (Lock* mutex = mutexFor(data))
+ mutex->unlock();
+}
+
+}
+
+#endif
Added: trunk/Source/WebCore/platform/network/curl/CurlContext.h (0 => 218947)
--- trunk/Source/WebCore/platform/network/curl/CurlContext.h (rev 0)
+++ trunk/Source/WebCore/platform/network/curl/CurlContext.h 2017-06-29 18:07:32 UTC (rev 218947)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2017 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "URL.h"
+
+#include <WTF/Noncopyable.h>
+#include <wtf/Lock.h>
+#include <wtf/Threading.h>
+
+#if OS(WINDOWS)
+#include <windows.h>
+#include <winsock2.h>
+#endif
+
+#include <curl/curl.h>
+
+namespace WebCore {
+
+enum class CurlProxyType {
+ Invalid = -1,
+ HTTP = CURLPROXY_HTTP,
+ Socks4 = CURLPROXY_SOCKS4,
+ Socks4A = CURLPROXY_SOCKS4A,
+ Socks5 = CURLPROXY_SOCKS5,
+ Socks5Hostname = CURLPROXY_SOCKS5_HOSTNAME
+};
+
+class CurlContext {
+ WTF_MAKE_NONCOPYABLE(CurlContext);
+
+public:
+ struct ProxyInfo {
+ String host;
+ unsigned long port;
+ CurlProxyType type { CurlProxyType::Invalid };
+ String username;
+ String password;
+
+ const String url() const;
+ };
+
+ static CurlContext& singleton()
+ {
+ static CurlContext shared;
+ return shared;
+ }
+
+ ~CurlContext();
+
+ CURLSH* curlShareHandle() const { return m_curlShareHandle; }
+
+ CURLM* createMultiHandle();
+
+ // Cookie
+ const char* getCookieJarFileName() const { return m_cookieJarFileName.data(); }
+ void setCookieJarFileName(const char* cookieJarFileName) { m_cookieJarFileName = CString(cookieJarFileName); }
+
+ // Certificate
+ const char* getCertificatePath() const { return m_certificatePath.data(); }
+ bool shouldIgnoreSSLErrors() const { return m_ignoreSSLErrors; }
+
+ // Proxy
+ const ProxyInfo& proxyInfo() const { return m_proxy; }
+ void setProxyInfo(const ProxyInfo& info) { m_proxy = info; }
+ void setProxyInfo(const String& host = emptyString(), unsigned long port = 0, CurlProxyType = CurlProxyType::HTTP, const String& username = emptyString(), const String& password = emptyString());
+
+ // Utilities
+ URL getEffectiveURL(CURL* handle);
+
+#ifndef NDEBUG
+ FILE* getLogFile() const { return m_logFile; }
+ bool isVerbose() const { return m_verbose; }
+#endif
+
+private:
+
+ CURLSH* m_curlShareHandle { nullptr };
+
+ CString m_cookieJarFileName;
+
+ CString m_certificatePath;
+ bool m_ignoreSSLErrors { false };
+
+ ProxyInfo m_proxy;
+
+ CurlContext();
+ void initCookieSession();
+
+ static void lock(CURL*, curl_lock_data, curl_lock_access, void*);
+ static void unlock(CURL*, curl_lock_data, void*);
+ static Lock* mutexFor(curl_lock_data);
+
+#ifndef NDEBUG
+ FILE* m_logFile { nullptr };
+ bool m_verbose { false };
+#endif
+};
+
+}
Modified: trunk/Source/WebCore/platform/network/curl/CurlDownload.cpp (218946 => 218947)
--- trunk/Source/WebCore/platform/network/curl/CurlDownload.cpp 2017-06-29 18:06:14 UTC (rev 218946)
+++ trunk/Source/WebCore/platform/network/curl/CurlDownload.cpp 2017-06-29 18:07:32 UTC (rev 218947)
@@ -29,6 +29,8 @@
#include "CurlDownload.h"
+#include "CurlContext.h"
+
#include "HTTPHeaderNames.h"
#include "HTTPParsers.h"
#include "ResourceRequest.h"
@@ -85,7 +87,7 @@
if (certPath)
curl_easy_setopt(m_curlHandle, CURLOPT_CAINFO, certPath);
- CURLSH* curlsh = CurlManager::singleton().getCurlShareHandle();
+ CURLSH* curlsh = CurlContext::singleton().curlShareHandle();
if (curlsh)
curl_easy_setopt(m_curlHandle, CURLOPT_SHARE, curlsh);
@@ -106,13 +108,13 @@
bool CurlDownload::start()
{
- ref(); // CurlDownloadManager::downloadThread will call deref when the download has finished.
- return CurlManager::singleton().add(m_curlHandle);
+ ref(); // CurlJobManager will call deref when the download has finished.
+ return CurlJobManager::singleton().add(m_curlHandle);
}
bool CurlDownload::cancel()
{
- return CurlManager::singleton().remove(m_curlHandle);
+ return CurlJobManager::singleton().remove(m_curlHandle);
}
String CurlDownload::getTempPath() const
@@ -203,7 +205,7 @@
UNUSED_PARAM(err);
if (httpCode >= 200 && httpCode < 300) {
- URL url = ""
+ URL url = ""
callOnMainThread([this, url = "" protectedThis = makeRef(*this)] {
m_response.setURL(url);
m_response.setMimeType(extractMIMETypeFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType)));
Modified: trunk/Source/WebCore/platform/network/curl/CurlDownload.h (218946 => 218947)
--- trunk/Source/WebCore/platform/network/curl/CurlDownload.h 2017-06-29 18:06:14 UTC (rev 218946)
+++ trunk/Source/WebCore/platform/network/curl/CurlDownload.h 2017-06-29 18:07:32 UTC (rev 218947)
@@ -36,7 +36,7 @@
#include <winsock2.h>
#endif
-#include "CurlManager.h"
+#include "CurlJobManager.h"
namespace WebCore {
Copied: trunk/Source/WebCore/platform/network/curl/CurlJobManager.cpp (from rev 218944, trunk/Source/WebCore/platform/network/curl/CurlManager.cpp) (0 => 218947)
--- trunk/Source/WebCore/platform/network/curl/CurlJobManager.cpp (rev 0)
+++ trunk/Source/WebCore/platform/network/curl/CurlJobManager.cpp 2017-06-29 18:07:32 UTC (rev 218947)
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2017 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(CURL)
+#include "CurlJobManager.h"
+
+#include "CurlContext.h"
+
+#include <wtf/MainThread.h>
+#include <wtf/text/CString.h>
+
+using namespace WebCore;
+
+namespace WebCore {
+
+CurlJobManager::CurlJobManager()
+{
+ m_curlMultiHandle = CurlContext::singleton().createMultiHandle();
+}
+
+CurlJobManager::~CurlJobManager()
+{
+ stopThread();
+ curl_multi_cleanup(m_curlMultiHandle);
+}
+
+bool CurlJobManager::add(CURL* curlHandle)
+{
+ ASSERT(isMainThread());
+
+ {
+ LockHolder locker(m_mutex);
+ m_pendingHandleList.append(curlHandle);
+ }
+
+ startThreadIfNeeded();
+
+ return true;
+}
+
+bool CurlJobManager::remove(CURL* curlHandle)
+{
+ LockHolder locker(m_mutex);
+
+ m_removedHandleList.append(curlHandle);
+
+ return true;
+}
+
+int CurlJobManager::getActiveCount() const
+{
+ LockHolder locker(m_mutex);
+ return m_activeHandleList.size();
+}
+
+int CurlJobManager::getPendingCount() const
+{
+ LockHolder locker(m_mutex);
+ return m_pendingHandleList.size();
+}
+
+void CurlJobManager::startThreadIfNeeded()
+{
+ ASSERT(isMainThread());
+
+ if (!runThread()) {
+ if (m_thread)
+ m_thread->waitForCompletion();
+ setRunThread(true);
+ m_thread = Thread::create("curlThread", [this] {
+ workerThread();
+ });
+ }
+}
+
+void CurlJobManager::stopThread()
+{
+ setRunThread(false);
+
+ if (m_thread) {
+ m_thread->waitForCompletion();
+ m_thread = nullptr;
+ }
+}
+
+void CurlJobManager::stopThreadIfIdle()
+{
+ if (!getActiveCount() && !getPendingCount())
+ setRunThread(false);
+}
+
+void CurlJobManager::updateHandleList()
+{
+ LockHolder locker(m_mutex);
+
+ // Remove curl easy handles from multi list
+ int size = m_removedHandleList.size();
+ for (int i = 0; i < size; i++) {
+ removeFromCurl(m_removedHandleList[0]);
+ m_removedHandleList.remove(0);
+ }
+
+ // Add pending curl easy handles to multi list
+ size = m_pendingHandleList.size();
+ for (int i = 0; i < size; i++) {
+ addToCurl(m_pendingHandleList[0]);
+ m_pendingHandleList.remove(0);
+ }
+}
+
+bool CurlJobManager::addToCurl(CURL* curlHandle)
+{
+ CURLMcode retval = curl_multi_add_handle(m_curlMultiHandle, curlHandle);
+ if (retval == CURLM_OK) {
+ m_activeHandleList.append(curlHandle);
+ return true;
+ }
+ return false;
+}
+
+bool CurlJobManager::removeFromCurl(CURL* curlHandle)
+{
+ int handlePos = m_activeHandleList.find(curlHandle);
+
+ if (handlePos < 0)
+ return true;
+
+ CURLMcode retval = curl_multi_remove_handle(m_curlMultiHandle, curlHandle);
+ if (retval == CURLM_OK) {
+ m_activeHandleList.remove(handlePos);
+ curl_easy_cleanup(curlHandle);
+ return true;
+ }
+ return false;
+}
+
+void CurlJobManager::workerThread()
+{
+ ASSERT(!isMainThread());
+
+ while (runThread()) {
+
+ updateHandleList();
+
+ // Retry 'select' if it was interrupted by a process signal.
+ int rc = 0;
+ do {
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+
+ int maxfd = 0;
+
+ const int selectTimeoutMS = 5;
+
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = selectTimeoutMS * 1000; // select waits microseconds
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+ curl_multi_fdset(getMultiHandle(), &fdread, &fdwrite, &fdexcep, &maxfd);
+ // When the 3 file descriptors are empty, winsock will return -1
+ // and bail out, stopping the file download. So make sure we
+ // have valid file descriptors before calling select.
+ if (maxfd >= 0)
+ rc = ::select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
+ } while (rc == -1 && errno == EINTR);
+
+ int activeCount = 0;
+ while (curl_multi_perform(getMultiHandle(), &activeCount) == CURLM_CALL_MULTI_PERFORM) { }
+
+ int messagesInQueue = 0;
+ CURLMsg* msg = curl_multi_info_read(getMultiHandle(), &messagesInQueue);
+
+ if (!msg)
+ continue;
+
+
+ CurlJob* job = nullptr;
+ CURLcode err = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &job);
+ UNUSED_PARAM(err);
+ ASSERT(job);
+
+ CurlJobAction action = ""
+
+ if (action == CurlJobAction::Finished)
+ removeFromCurl(msg->easy_handle);
+
+ stopThreadIfIdle();
+ }
+}
+
+}
+
+#endif
Copied: trunk/Source/WebCore/platform/network/curl/CurlJobManager.h (from rev 218944, trunk/Source/WebCore/platform/network/curl/CurlManager.h) (0 => 218947)
--- trunk/Source/WebCore/platform/network/curl/CurlJobManager.h (rev 0)
+++ trunk/Source/WebCore/platform/network/curl/CurlJobManager.h 2017-06-29 18:07:32 UTC (rev 218947)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2017 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Lock.h>
+#include <wtf/Threading.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(WIN)
+#include <windows.h>
+#include <winsock2.h>
+#endif
+
+#include <curl/curl.h>
+
+namespace WebCore {
+
+enum class CurlJobAction { None, Finished };
+
+class CurlJob {
+public:
+ virtual CurlJobAction handleCurlMsg(CURLMsg*) = 0;
+};
+
+class CurlJobManager {
+public:
+ static CurlJobManager& singleton()
+ {
+ // Since it's a static variable, if the class has already been created,
+ // It won't be created again.
+ // And it **is** thread-safe in C++11.
+
+ static CurlJobManager shared;
+ return shared;
+ }
+
+ CurlJobManager();
+ virtual ~CurlJobManager();
+
+ bool add(CURL* curlHandle);
+ bool remove(CURL* curlHandle);
+
+ int getActiveCount() const;
+ int getPendingCount() const;
+
+private:
+ void startThreadIfNeeded();
+ void stopThread();
+ void stopThreadIfIdle();
+
+ void updateHandleList();
+
+ CURLM* getMultiHandle() const { return m_curlMultiHandle; }
+
+ bool runThread() const { LockHolder locker(m_mutex); return m_runThread; }
+ void setRunThread(bool runThread) { LockHolder locker(m_mutex); m_runThread = runThread; }
+
+ bool addToCurl(CURL* curlHandle);
+ bool removeFromCurl(CURL* curlHandle);
+
+ void workerThread();
+
+ RefPtr<Thread> m_thread;
+ CURLM* m_curlMultiHandle { nullptr };
+ Vector<CURL*> m_pendingHandleList;
+ Vector<CURL*> m_activeHandleList;
+ Vector<CURL*> m_removedHandleList;
+ mutable Lock m_mutex;
+ bool m_runThread { false };
+
+ friend class CurlJob;
+};
+
+}
Deleted: trunk/Source/WebCore/platform/network/curl/CurlManager.cpp (218946 => 218947)
--- trunk/Source/WebCore/platform/network/curl/CurlManager.cpp 2017-06-29 18:06:14 UTC (rev 218946)
+++ trunk/Source/WebCore/platform/network/curl/CurlManager.cpp 2017-06-29 18:07:32 UTC (rev 218947)
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- * Copyright (C) 2017 Sony Interactive Entertainment Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if USE(CURL)
-#include "CurlManager.h"
-
-#include <wtf/MainThread.h>
-#include <wtf/text/CString.h>
-
-using namespace WebCore;
-
-namespace WebCore {
-
-class CurlSharedResources {
-public:
- static void lock(CURL*, curl_lock_data, curl_lock_access, void*);
- static void unlock(CURL*, curl_lock_data, void*);
-
-private:
- static Lock* mutexFor(curl_lock_data);
-};
-
-// CurlDownloadManager -------------------------------------------------------------------
-
-CurlManager::CurlManager()
-{
- curl_global_init(CURL_GLOBAL_ALL);
- m_curlMultiHandle = curl_multi_init();
- m_curlShareHandle = curl_share_init();
- curl_share_setopt(m_curlShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
- curl_share_setopt(m_curlShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
- curl_share_setopt(m_curlShareHandle, CURLSHOPT_LOCKFUNC, CurlSharedResources::lock);
- curl_share_setopt(m_curlShareHandle, CURLSHOPT_UNLOCKFUNC, CurlSharedResources::unlock);
-}
-
-CurlManager::~CurlManager()
-{
- stopThread();
- curl_multi_cleanup(m_curlMultiHandle);
- curl_share_cleanup(m_curlShareHandle);
- curl_global_cleanup();
-}
-
-bool CurlManager::add(CURL* curlHandle)
-{
- ASSERT(isMainThread());
-
- {
- LockHolder locker(m_mutex);
- m_pendingHandleList.append(curlHandle);
- }
-
- startThreadIfNeeded();
-
- return true;
-}
-
-bool CurlManager::remove(CURL* curlHandle)
-{
- LockHolder locker(m_mutex);
-
- m_removedHandleList.append(curlHandle);
-
- return true;
-}
-
-int CurlManager::getActiveCount() const
-{
- LockHolder locker(m_mutex);
- return m_activeHandleList.size();
-}
-
-int CurlManager::getPendingCount() const
-{
- LockHolder locker(m_mutex);
- return m_pendingHandleList.size();
-}
-
-void CurlManager::startThreadIfNeeded()
-{
- ASSERT(isMainThread());
-
- if (!runThread()) {
- if (m_thread)
- m_thread->waitForCompletion();
- setRunThread(true);
- m_thread = Thread::create("curlThread", [this] {
- workerThread();
- });
- }
-}
-
-void CurlManager::stopThread()
-{
- ASSERT(isMainThread());
-
- setRunThread(false);
-
- if (m_thread) {
- m_thread->waitForCompletion();
- m_thread = nullptr;
- }
-}
-
-void CurlManager::stopThreadIfIdle()
-{
- if (!getActiveCount() && !getPendingCount())
- setRunThread(false);
-}
-
-void CurlManager::updateHandleList()
-{
- LockHolder locker(m_mutex);
-
- // Remove curl easy handles from multi list
- int size = m_removedHandleList.size();
- for (int i = 0; i < size; i++) {
- removeFromCurl(m_removedHandleList[0]);
- m_removedHandleList.remove(0);
- }
-
- // Add pending curl easy handles to multi list
- size = m_pendingHandleList.size();
- for (int i = 0; i < size; i++) {
- addToCurl(m_pendingHandleList[0]);
- m_pendingHandleList.remove(0);
- }
-}
-
-bool CurlManager::addToCurl(CURL* curlHandle)
-{
- CURLMcode retval = curl_multi_add_handle(m_curlMultiHandle, curlHandle);
- if (retval == CURLM_OK) {
- m_activeHandleList.append(curlHandle);
- return true;
- }
- return false;
-}
-
-bool CurlManager::removeFromCurl(CURL* curlHandle)
-{
- int handlePos = m_activeHandleList.find(curlHandle);
-
- if (handlePos < 0)
- return true;
-
- CURLMcode retval = curl_multi_remove_handle(m_curlMultiHandle, curlHandle);
- if (retval == CURLM_OK) {
- m_activeHandleList.remove(handlePos);
- curl_easy_cleanup(curlHandle);
- return true;
- }
- return false;
-}
-
-void CurlManager::workerThread()
-{
- ASSERT(!isMainThread());
-
- while (runThread()) {
-
- updateHandleList();
-
- // Retry 'select' if it was interrupted by a process signal.
- int rc = 0;
- do {
- fd_set fdread;
- fd_set fdwrite;
- fd_set fdexcep;
-
- int maxfd = 0;
-
- const int selectTimeoutMS = 5;
-
- struct timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = selectTimeoutMS * 1000; // select waits microseconds
-
- FD_ZERO(&fdread);
- FD_ZERO(&fdwrite);
- FD_ZERO(&fdexcep);
- curl_multi_fdset(getMultiHandle(), &fdread, &fdwrite, &fdexcep, &maxfd);
- // When the 3 file descriptors are empty, winsock will return -1
- // and bail out, stopping the file download. So make sure we
- // have valid file descriptors before calling select.
- if (maxfd >= 0)
- rc = ::select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
- } while (rc == -1 && errno == EINTR);
-
- int activeCount = 0;
- while (curl_multi_perform(getMultiHandle(), &activeCount) == CURLM_CALL_MULTI_PERFORM) { }
-
- int messagesInQueue = 0;
- CURLMsg* msg = curl_multi_info_read(getMultiHandle(), &messagesInQueue);
-
- if (!msg)
- continue;
-
-
- CurlJob* job = nullptr;
- CURLcode err = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &job);
- UNUSED_PARAM(err);
- ASSERT(job);
-
- CurlJobAction action = ""
-
- if (action == CurlJobAction::Finished)
- removeFromCurl(msg->easy_handle);
-
- stopThreadIfIdle();
- }
-}
-
-// CURL Utilities
-
-URL CurlUtils::getEffectiveURL(CURL* handle)
-{
- const char* url;
- CURLcode err = curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url);
- if (CURLE_OK != err)
- return URL();
- return URL(URL(), url);
-}
-
-// Shared Resource management =======================
-
-Lock* CurlSharedResources::mutexFor(curl_lock_data data)
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(Lock, cookieMutex, ());
- DEPRECATED_DEFINE_STATIC_LOCAL(Lock, dnsMutex, ());
- DEPRECATED_DEFINE_STATIC_LOCAL(Lock, shareMutex, ());
-
- switch (data) {
- case CURL_LOCK_DATA_COOKIE:
- return &cookieMutex;
- case CURL_LOCK_DATA_DNS:
- return &dnsMutex;
- case CURL_LOCK_DATA_SHARE:
- return &shareMutex;
- default:
- ASSERT_NOT_REACHED();
- return nullptr;
- }
-}
-
-// libcurl does not implement its own thread synchronization primitives.
-// these two functions provide mutexes for cookies, and for the global DNS
-// cache.
-void CurlSharedResources::lock(CURL* /* handle */, curl_lock_data data, curl_lock_access /* access */, void* /* userPtr */)
-{
- if (Lock* mutex = CurlSharedResources::mutexFor(data))
- mutex->lock();
-}
-
-void CurlSharedResources::unlock(CURL* /* handle */, curl_lock_data data, void* /* userPtr */)
-{
- if (Lock* mutex = CurlSharedResources::mutexFor(data))
- mutex->unlock();
-}
-
-}
-
-#endif
Deleted: trunk/Source/WebCore/platform/network/curl/CurlManager.h (218946 => 218947)
--- trunk/Source/WebCore/platform/network/curl/CurlManager.h 2017-06-29 18:06:14 UTC (rev 218946)
+++ trunk/Source/WebCore/platform/network/curl/CurlManager.h 2017-06-29 18:07:32 UTC (rev 218947)
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- * Copyright (C) 2017 Sony Interactive Entertainment Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <wtf/Lock.h>
-#include <wtf/Threading.h>
-
-#if PLATFORM(WIN)
-#include <windows.h>
-#include <winsock2.h>
-#endif
-
-#include <curl/curl.h>
-#include "URL.h"
-
-namespace WebCore {
-
-enum class CurlJobAction { None, Finished };
-
-class CurlJob {
-public:
- virtual CurlJobAction handleCurlMsg(CURLMsg*) = 0;
-};
-
-class CurlManager {
-public:
- static CurlManager& singleton()
- {
- // Since it's a static variable, if the class has already been created,
- // It won't be created again.
- // And it **is** thread-safe in C++11.
-
- static CurlManager shared;
- return shared;
- }
-
- CurlManager();
- virtual ~CurlManager();
-
- bool add(CURL* curlHandle);
- bool remove(CURL* curlHandle);
-
- int getActiveCount() const;
- int getPendingCount() const;
-
- CURLSH* getCurlShareHandle() const { return m_curlShareHandle; }
-
-private:
- void startThreadIfNeeded();
- void stopThread();
- void stopThreadIfIdle();
-
- void updateHandleList();
-
- CURLM* getMultiHandle() const { return m_curlMultiHandle; }
-
- bool runThread() const { LockHolder locker(m_mutex); return m_runThread; }
- void setRunThread(bool runThread) { LockHolder locker(m_mutex); m_runThread = runThread; }
-
- bool addToCurl(CURL* curlHandle);
- bool removeFromCurl(CURL* curlHandle);
-
- void workerThread();
-
- RefPtr<Thread> m_thread;
- CURLM* m_curlMultiHandle { nullptr };
- Vector<CURL*> m_pendingHandleList;
- Vector<CURL*> m_activeHandleList;
- Vector<CURL*> m_removedHandleList;
- mutable Lock m_mutex;
- bool m_runThread { false };
-
- CURLSH* m_curlShareHandle { nullptr };
-
- friend class CurlJob;
-};
-
-class CurlUtils {
-public:
- static URL getEffectiveURL(CURL* handle);
-};
-
-}
Modified: trunk/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp (218946 => 218947)
--- trunk/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp 2017-06-29 18:06:14 UTC (rev 218946)
+++ trunk/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp 2017-06-29 18:07:32 UTC (rev 218947)
@@ -42,7 +42,7 @@
#include "CredentialStorage.h"
#include "CurlCacheManager.h"
-#include "CurlManager.h"
+#include "CurlContext.h"
#include "HTTPHeaderNames.h"
#include "HTTPParsers.h"
#include "MIMETypeRegistry.h"
@@ -60,9 +60,6 @@
#include <wtf/text/StringView.h>
#if OS(WINDOWS)
-#include "WebCoreBundleWin.h"
-#include <shlobj.h>
-#include <shlwapi.h>
#else
#include <sys/param.h>
#define MAX_PATH MAXPATHLEN
@@ -73,13 +70,9 @@
#if ENABLE(WEB_TIMING)
#include <wtf/CurrentTime.h>
#endif
-#if USE(CF)
-#include <wtf/RetainPtr.h>
-#endif
#include <wtf/Lock.h>
#include <wtf/Threading.h>
#include <wtf/Vector.h>
-#include <wtf/text/CString.h>
namespace WebCore {
@@ -88,61 +81,6 @@
const int maxRunningJobs = 128;
const char* const errorDomainCurl = "CurlErrorDomain";
-static const bool ignoreSSLErrors = getenv("WEBKIT_IGNORE_SSL_ERRORS");
-
-static CString certificatePath()
-{
- char* envPath = getenv("CURL_CA_BUNDLE_PATH");
- if (envPath)
- return envPath;
-
-#if USE(CF)
- CFBundleRef webKitBundleRef = webKitBundle();
- if (webKitBundleRef) {
- RetainPtr<CFURLRef> certURLRef = adoptCF(CFBundleCopyResourceURL(webKitBundleRef, CFSTR("cacert"), CFSTR("pem"), CFSTR("certificates")));
- if (certURLRef) {
- char path[MAX_PATH];
- CFURLGetFileSystemRepresentation(certURLRef.get(), false, reinterpret_cast<UInt8*>(path), MAX_PATH);
- return path;
- }
- }
-#endif
-
- return CString();
-}
-
-static char* cookieJarPath()
-{
- char* cookieJarPath = getenv("CURL_COOKIE_JAR_PATH");
- if (cookieJarPath)
- return fastStrDup(cookieJarPath);
-
-#if OS(WINDOWS)
- char executablePath[MAX_PATH];
- char appDataDirectory[MAX_PATH];
- char cookieJarFullPath[MAX_PATH];
- char cookieJarDirectory[MAX_PATH];
-
- if (FAILED(::SHGetFolderPathA(0, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, appDataDirectory))
- || FAILED(::GetModuleFileNameA(0, executablePath, MAX_PATH)))
- return fastStrDup("cookies.dat");
-
- ::PathRemoveExtensionA(executablePath);
- LPSTR executableName = ::PathFindFileNameA(executablePath);
- sprintf_s(cookieJarDirectory, MAX_PATH, "%s/%s", appDataDirectory, executableName);
- sprintf_s(cookieJarFullPath, MAX_PATH, "%s/cookies.dat", cookieJarDirectory);
-
- if (::SHCreateDirectoryExA(0, cookieJarDirectory, 0) != ERROR_SUCCESS
- && ::GetLastError() != ERROR_FILE_EXISTS
- && ::GetLastError() != ERROR_ALREADY_EXISTS)
- return fastStrDup("cookies.dat");
-
- return fastStrDup(cookieJarFullPath);
-#else
- return fastStrDup("cookies.dat");
-#endif
-}
-
#if ENABLE(WEB_TIMING)
static void calculateWebTimingInformations(ResourceHandleInternal* d)
{
@@ -192,49 +130,16 @@
ResourceHandleManager::ResourceHandleManager()
: m_downloadTimer(*this, &ResourceHandleManager::downloadTimerCallback)
- , m_cookieJarFileName(cookieJarPath())
- , m_certificatePath(certificatePath())
, m_runningJobs(0)
-#ifndef NDEBUG
- , m_logFile(nullptr)
-#endif
{
- CURLSH* h = CurlManager::singleton().getCurlShareHandle();
- m_curlShareHandle = h;
- m_curlMultiHandle = curl_multi_init();
-
-
- initCookieSession();
-
-#ifndef NDEBUG
- char* logFile = getenv("CURL_LOG_FILE");
- if (logFile)
- m_logFile = fopen(logFile, "a");
-#endif
+ m_curlMultiHandle = CurlContext::singleton().createMultiHandle();
}
ResourceHandleManager::~ResourceHandleManager()
{
curl_multi_cleanup(m_curlMultiHandle);
- if (m_cookieJarFileName)
- fastFree(m_cookieJarFileName);
-
-#ifndef NDEBUG
- if (m_logFile)
- fclose(m_logFile);
-#endif
}
-void ResourceHandleManager::setCookieJarFileName(const char* cookieJarFileName)
-{
- m_cookieJarFileName = fastStrDup(cookieJarFileName);
-}
-
-const char* ResourceHandleManager::getCookieJarFileName() const
-{
- return m_cookieJarFileName;
-}
-
ResourceHandleManager* ResourceHandleManager::sharedInstance()
{
static ResourceHandleManager* sharedInstance = 0;
@@ -250,7 +155,7 @@
// which means the ResourceLoader's response does not contain the URL.
// Run the code here for local files to resolve the issue.
// TODO: See if there is a better approach for handling this.
- URL url = ""
+ URL url = ""
ASSERT(url.isValid());
d->m_response.setURL(url);
if (d->client())
@@ -361,7 +266,7 @@
if (err != CURLE_OK)
return false;
- URL url = ""
+ URL url = ""
if (!url.isValid())
return false;
@@ -450,7 +355,7 @@
curl_easy_getinfo(h, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength);
d->m_response.setExpectedContentLength(static_cast<long long int>(contentLength));
- d->m_response.setURL(CurlUtils::getEffectiveURL(h));
+ d->m_response.setURL(CurlContext::singleton().getEffectiveURL(h));
d->m_response.setHTTPStatusCode(httpCode);
d->m_response.setMimeType(extractMIMETypeFromMediaType(d->m_response.httpHeaderField(HTTPHeaderName::ContentType)).convertToASCIILowercase());
@@ -657,7 +562,7 @@
CurlCacheManager::getInstance().didFinishLoading(*job);
}
} else {
- URL url = ""
+ URL url = ""
#ifndef NDEBUG
fprintf(stderr, "Curl ERROR for url='', error: '%s'\n", url.string().utf8().data(), curl_easy_strerror(msg->data.result));
#endif
@@ -678,25 +583,6 @@
m_downloadTimer.startOneShot(pollTime);
}
-void ResourceHandleManager::setProxyInfo(const String& host,
- unsigned long port,
- ProxyType type,
- const String& username,
- const String& password)
-{
- m_proxyType = type;
-
- if (!host.length()) {
- m_proxy = emptyString();
- } else {
- String userPass;
- if (username.length() || password.length())
- userPass = username + ":" + password + "@";
-
- m_proxy = String("http://") + userPass + host + ":" + String::number(port);
- }
-}
-
void ResourceHandleManager::removeFromCurl(ResourceHandle* job)
{
ResourceHandleInternal* d = job->getInternal();
@@ -1019,6 +905,8 @@
void ResourceHandleManager::initializeHandle(ResourceHandle* job)
{
+ CurlContext& context = CurlContext::singleton();
+
static const int allowedProtocols = CURLPROTO_FILE | CURLPROTO_FTP | CURLPROTO_FTPS | CURLPROTO_HTTP | CURLPROTO_HTTPS;
URL url = ""
@@ -1048,10 +936,10 @@
ASSERT_UNUSED(error, error == CURLE_OK);
}
#ifndef NDEBUG
- if (getenv("DEBUG_CURL"))
+ if (context.isVerbose())
curl_easy_setopt(d->m_handle, CURLOPT_VERBOSE, 1);
- if (m_logFile)
- curl_easy_setopt(d->m_handle, CURLOPT_STDERR, m_logFile);
+ if (context.getLogFile())
+ curl_easy_setopt(d->m_handle, CURLOPT_STDERR, context.getLogFile());
#endif
curl_easy_setopt(d->m_handle, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(d->m_handle, CURLOPT_SSL_VERIFYHOST, 2L);
@@ -1065,19 +953,20 @@
curl_easy_setopt(d->m_handle, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(d->m_handle, CURLOPT_MAXREDIRS, 10);
curl_easy_setopt(d->m_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
- curl_easy_setopt(d->m_handle, CURLOPT_SHARE, m_curlShareHandle);
+ curl_easy_setopt(d->m_handle, CURLOPT_SHARE, CurlContext::singleton().curlShareHandle());
curl_easy_setopt(d->m_handle, CURLOPT_DNS_CACHE_TIMEOUT, 60 * 5); // 5 minutes
curl_easy_setopt(d->m_handle, CURLOPT_PROTOCOLS, allowedProtocols);
curl_easy_setopt(d->m_handle, CURLOPT_REDIR_PROTOCOLS, allowedProtocols);
setSSLClientCertificate(job);
- if (ignoreSSLErrors)
+ if (context.shouldIgnoreSSLErrors())
curl_easy_setopt(d->m_handle, CURLOPT_SSL_VERIFYPEER, false);
else
setSSLVerifyOptions(job);
- if (!m_certificatePath.isNull())
- curl_easy_setopt(d->m_handle, CURLOPT_CAINFO, m_certificatePath.data());
+ const char* certificate = context.getCertificatePath();
+ if (certificate)
+ curl_easy_setopt(d->m_handle, CURLOPT_CAINFO, certificate);
// enable gzip and deflate through Accept-Encoding:
curl_easy_setopt(d->m_handle, CURLOPT_ENCODING, "");
@@ -1089,8 +978,9 @@
d->m_url = fastStrDup(urlString.latin1().data());
curl_easy_setopt(d->m_handle, CURLOPT_URL, d->m_url);
- if (m_cookieJarFileName)
- curl_easy_setopt(d->m_handle, CURLOPT_COOKIEJAR, m_cookieJarFileName);
+ const char* cookieJar = context.getCookieJarFileName();
+ if (cookieJar)
+ curl_easy_setopt(d->m_handle, CURLOPT_COOKIEJAR, cookieJar);
struct curl_slist* headers = 0;
if (job->firstRequest().httpHeaderFields().size() > 0) {
@@ -1150,34 +1040,13 @@
applyAuthenticationToRequest(job, job->firstRequest());
// Set proxy options if we have them.
- if (m_proxy.length()) {
- curl_easy_setopt(d->m_handle, CURLOPT_PROXY, m_proxy.utf8().data());
- curl_easy_setopt(d->m_handle, CURLOPT_PROXYTYPE, m_proxyType);
+ auto& proxy = CurlContext::singleton().proxyInfo();
+ if (proxy.type != CurlProxyType::Invalid) {
+ curl_easy_setopt(d->m_handle, CURLOPT_PROXY, proxy.url().utf8().data());
+ curl_easy_setopt(d->m_handle, CURLOPT_PROXYTYPE, proxy.type);
}
}
-void ResourceHandleManager::initCookieSession()
-{
- // Curl saves both persistent cookies, and session cookies to the cookie file.
- // The session cookies should be deleted before starting a new session.
-
- CURL* curl = curl_easy_init();
-
- if (!curl)
- return;
-
- curl_easy_setopt(curl, CURLOPT_SHARE, m_curlShareHandle);
-
- if (m_cookieJarFileName) {
- curl_easy_setopt(curl, CURLOPT_COOKIEFILE, m_cookieJarFileName);
- curl_easy_setopt(curl, CURLOPT_COOKIEJAR, m_cookieJarFileName);
- }
-
- curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1);
-
- curl_easy_cleanup(curl);
-}
-
void ResourceHandleManager::cancel(ResourceHandle* job)
{
if (removeScheduledJob(job))
Modified: trunk/Source/WebCore/platform/network/curl/ResourceHandleManager.h (218946 => 218947)
--- trunk/Source/WebCore/platform/network/curl/ResourceHandleManager.h 2017-06-29 18:06:14 UTC (rev 218946)
+++ trunk/Source/WebCore/platform/network/curl/ResourceHandleManager.h 2017-06-29 18:07:32 UTC (rev 218947)
@@ -46,27 +46,15 @@
class ResourceHandleManager {
public:
- enum ProxyType {
- HTTP = CURLPROXY_HTTP,
- Socks4 = CURLPROXY_SOCKS4,
- Socks4A = CURLPROXY_SOCKS4A,
- Socks5 = CURLPROXY_SOCKS5,
- Socks5Hostname = CURLPROXY_SOCKS5_HOSTNAME
- };
static ResourceHandleManager* sharedInstance();
void add(ResourceHandle*);
void cancel(ResourceHandle*);
- void setCookieJarFileName(const char* cookieJarFileName);
- const char* getCookieJarFileName() const;
-
void dispatchSynchronousJob(ResourceHandle*);
void setupPOST(ResourceHandle*, struct curl_slist**);
void setupPUT(ResourceHandle*, struct curl_slist**);
- void setProxyInfo(const String& host = emptyString(), unsigned long port = 0, ProxyType = HTTP, const String& username = emptyString(), const String& password = emptyString());
-
private:
ResourceHandleManager();
~ResourceHandleManager();
@@ -79,23 +67,11 @@
void initializeHandle(ResourceHandle*);
- void initCookieSession();
-
Timer m_downloadTimer;
CURLM* m_curlMultiHandle;
- CURLSH* m_curlShareHandle;
- char* m_cookieJarFileName;
char m_curlErrorBuffer[CURL_ERROR_SIZE];
Vector<ResourceHandle*> m_resourceHandleList;
- const CString m_certificatePath;
int m_runningJobs;
-
- String m_proxy;
- ProxyType m_proxyType;
-
-#ifndef NDEBUG
- FILE* m_logFile;
-#endif
};
}