summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/network
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:52 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:30:52 -0800
commit8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2 (patch)
tree11425ea0b299d6fb89c6d3618a22d97d5bf68d0f /WebCore/platform/network
parent648161bb0edfc3d43db63caed5cc5213bc6cb78f (diff)
downloadexternal_webkit-8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2.zip
external_webkit-8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2.tar.gz
external_webkit-8e35f3cfc7fba1d1c829dc557ebad6409cbe16a2.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'WebCore/platform/network')
-rw-r--r--WebCore/platform/network/AuthenticationChallengeBase.cpp113
-rw-r--r--WebCore/platform/network/AuthenticationChallengeBase.h70
-rw-r--r--WebCore/platform/network/Credential.cpp80
-rw-r--r--WebCore/platform/network/Credential.h59
-rw-r--r--WebCore/platform/network/DNS.h36
-rw-r--r--WebCore/platform/network/FormData.cpp167
-rw-r--r--WebCore/platform/network/FormData.h109
-rw-r--r--WebCore/platform/network/HTTPHeaderMap.h38
-rw-r--r--WebCore/platform/network/HTTPParsers.cpp186
-rw-r--r--WebCore/platform/network/HTTPParsers.h42
-rw-r--r--WebCore/platform/network/NetworkStateNotifier.cpp47
-rw-r--r--WebCore/platform/network/NetworkStateNotifier.h103
-rw-r--r--WebCore/platform/network/ProtectionSpace.cpp119
-rw-r--r--WebCore/platform/network/ProtectionSpace.h79
-rw-r--r--WebCore/platform/network/ResourceErrorBase.cpp62
-rw-r--r--WebCore/platform/network/ResourceErrorBase.h88
-rw-r--r--WebCore/platform/network/ResourceHandle.cpp202
-rw-r--r--WebCore/platform/network/ResourceHandle.h194
-rw-r--r--WebCore/platform/network/ResourceHandleClient.h92
-rw-r--r--WebCore/platform/network/ResourceHandleInternal.h223
-rw-r--r--WebCore/platform/network/ResourceRequestBase.cpp272
-rw-r--r--WebCore/platform/network/ResourceRequestBase.h144
-rw-r--r--WebCore/platform/network/ResourceResponseBase.cpp236
-rw-r--r--WebCore/platform/network/ResourceResponseBase.h131
-rw-r--r--WebCore/platform/network/android/AuthenticationChallenge.h55
-rw-r--r--WebCore/platform/network/android/Cookie.cpp58
-rw-r--r--WebCore/platform/network/android/CookieClient.h47
-rw-r--r--WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp42
-rw-r--r--WebCore/platform/network/android/ResourceError.h49
-rw-r--r--WebCore/platform/network/android/ResourceHandleAndroid.cpp157
-rw-r--r--WebCore/platform/network/android/ResourceRequest.h93
-rw-r--r--WebCore/platform/network/android/ResourceResponse.h60
-rw-r--r--WebCore/platform/network/cf/AuthenticationCF.cpp266
-rw-r--r--WebCore/platform/network/cf/AuthenticationCF.h49
-rw-r--r--WebCore/platform/network/cf/AuthenticationChallenge.h57
-rw-r--r--WebCore/platform/network/cf/DNSCFNet.cpp38
-rw-r--r--WebCore/platform/network/cf/FormDataStreamCFNet.cpp422
-rw-r--r--WebCore/platform/network/cf/FormDataStreamCFNet.h44
-rw-r--r--WebCore/platform/network/cf/ResourceError.h73
-rw-r--r--WebCore/platform/network/cf/ResourceErrorCF.cpp164
-rw-r--r--WebCore/platform/network/cf/ResourceHandleCFNet.cpp443
-rw-r--r--WebCore/platform/network/cf/ResourceRequest.h77
-rw-r--r--WebCore/platform/network/cf/ResourceRequestCFNet.cpp116
-rw-r--r--WebCore/platform/network/cf/ResourceRequestCFNet.h39
-rw-r--r--WebCore/platform/network/cf/ResourceResponse.h69
-rw-r--r--WebCore/platform/network/cf/ResourceResponseCFNet.cpp117
-rw-r--r--WebCore/platform/network/cf/ResourceResponseCFNet.h39
-rw-r--r--WebCore/platform/network/curl/AuthenticationChallenge.h54
-rw-r--r--WebCore/platform/network/curl/CookieJarCurl.cpp45
-rw-r--r--WebCore/platform/network/curl/DNSCurl.cpp38
-rw-r--r--WebCore/platform/network/curl/FormDataStreamCurl.cpp113
-rw-r--r--WebCore/platform/network/curl/FormDataStreamCurl.h63
-rw-r--r--WebCore/platform/network/curl/ResourceError.h48
-rw-r--r--WebCore/platform/network/curl/ResourceHandleCurl.cpp230
-rw-r--r--WebCore/platform/network/curl/ResourceHandleManager.cpp700
-rw-r--r--WebCore/platform/network/curl/ResourceHandleManager.h74
-rw-r--r--WebCore/platform/network/curl/ResourceRequest.h71
-rw-r--r--WebCore/platform/network/curl/ResourceResponse.h55
-rw-r--r--WebCore/platform/network/mac/AuthenticationChallenge.h59
-rw-r--r--WebCore/platform/network/mac/AuthenticationMac.h51
-rw-r--r--WebCore/platform/network/mac/AuthenticationMac.mm245
-rw-r--r--WebCore/platform/network/mac/FormDataStreamMac.h49
-rw-r--r--WebCore/platform/network/mac/FormDataStreamMac.mm390
-rw-r--r--WebCore/platform/network/mac/NetworkStateNotifierMac.cpp132
-rw-r--r--WebCore/platform/network/mac/ResourceError.h74
-rw-r--r--WebCore/platform/network/mac/ResourceErrorMac.mm85
-rw-r--r--WebCore/platform/network/mac/ResourceHandleMac.mm779
-rw-r--r--WebCore/platform/network/mac/ResourceRequest.h82
-rw-r--r--WebCore/platform/network/mac/ResourceRequestMac.mm110
-rw-r--r--WebCore/platform/network/mac/ResourceResponse.h74
-rw-r--r--WebCore/platform/network/mac/ResourceResponseMac.mm115
-rw-r--r--WebCore/platform/network/mac/WebCoreURLResponse.h34
-rw-r--r--WebCore/platform/network/mac/WebCoreURLResponse.mm221
-rw-r--r--WebCore/platform/network/qt/AuthenticationChallenge.h46
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.cpp435
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.h118
-rw-r--r--WebCore/platform/network/qt/ResourceError.h48
-rw-r--r--WebCore/platform/network/qt/ResourceHandleQt.cpp208
-rw-r--r--WebCore/platform/network/qt/ResourceRequest.h74
-rw-r--r--WebCore/platform/network/qt/ResourceRequestQt.cpp49
-rw-r--r--WebCore/platform/network/qt/ResourceResponse.h47
-rw-r--r--WebCore/platform/network/soup/AuthenticationChallenge.h46
-rw-r--r--WebCore/platform/network/soup/CookieJarSoup.cpp74
-rw-r--r--WebCore/platform/network/soup/DNSSoup.cpp38
-rw-r--r--WebCore/platform/network/soup/ResourceError.h48
-rw-r--r--WebCore/platform/network/soup/ResourceHandleSoup.cpp591
-rw-r--r--WebCore/platform/network/soup/ResourceRequest.h66
-rw-r--r--WebCore/platform/network/soup/ResourceResponse.h55
-rw-r--r--WebCore/platform/network/win/CookieJarCFNetWin.cpp106
-rw-r--r--WebCore/platform/network/win/CookieJarWin.cpp67
-rw-r--r--WebCore/platform/network/win/CookieStorageWin.cpp50
-rw-r--r--WebCore/platform/network/win/CookieStorageWin.h39
-rw-r--r--WebCore/platform/network/win/NetworkStateNotifierWin.cpp114
-rw-r--r--WebCore/platform/network/win/ResourceHandleWin.cpp457
-rw-r--r--WebCore/platform/network/win/ResourceHandleWin.h46
95 files changed, 12279 insertions, 0 deletions
diff --git a/WebCore/platform/network/AuthenticationChallengeBase.cpp b/WebCore/platform/network/AuthenticationChallengeBase.cpp
new file mode 100644
index 0000000..df80441
--- /dev/null
+++ b/WebCore/platform/network/AuthenticationChallengeBase.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "AuthenticationChallenge.h"
+
+#include "ResourceHandle.h"
+
+namespace WebCore {
+
+AuthenticationChallengeBase::AuthenticationChallengeBase()
+ : m_isNull(true)
+ , m_previousFailureCount(0)
+{
+}
+
+AuthenticationChallengeBase::AuthenticationChallengeBase(const ProtectionSpace& protectionSpace,
+ const Credential& proposedCredential,
+ unsigned previousFailureCount,
+ const ResourceResponse& response,
+ const ResourceError& error)
+ : m_isNull(false)
+ , m_protectionSpace(protectionSpace)
+ , m_proposedCredential(proposedCredential)
+ , m_previousFailureCount(previousFailureCount)
+ , m_failureResponse(response)
+ , m_error(error)
+{
+}
+
+unsigned AuthenticationChallengeBase::previousFailureCount() const
+{
+ return m_previousFailureCount;
+}
+
+const Credential& AuthenticationChallengeBase::proposedCredential() const
+{
+ return m_proposedCredential;
+}
+
+const ProtectionSpace& AuthenticationChallengeBase::protectionSpace() const
+{
+ return m_protectionSpace;
+}
+
+const ResourceResponse& AuthenticationChallengeBase::failureResponse() const
+{
+ return m_failureResponse;
+}
+
+const ResourceError& AuthenticationChallengeBase::error() const
+{
+ return m_error;
+}
+
+bool AuthenticationChallengeBase::isNull() const
+{
+ return m_isNull;
+}
+
+void AuthenticationChallengeBase::nullify()
+{
+ m_isNull = true;
+}
+
+bool AuthenticationChallengeBase::compare(const AuthenticationChallenge& a, const AuthenticationChallenge& b)
+{
+ if (a.isNull() && b.isNull())
+ return true;
+
+ if (a.isNull() || b.isNull())
+ return false;
+
+ if (a.protectionSpace() != b.protectionSpace())
+ return false;
+
+ if (a.proposedCredential() != b.proposedCredential())
+ return false;
+
+ if (a.previousFailureCount() != b.previousFailureCount())
+ return false;
+
+ if (a.failureResponse() != b.failureResponse())
+ return false;
+
+ if (a.error() != b.error())
+ return false;
+
+ return AuthenticationChallenge::platformCompare(a, b);
+}
+
+}
diff --git a/WebCore/platform/network/AuthenticationChallengeBase.h b/WebCore/platform/network/AuthenticationChallengeBase.h
new file mode 100644
index 0000000..5810a6d
--- /dev/null
+++ b/WebCore/platform/network/AuthenticationChallengeBase.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef AuthenticationChallengeBase_h
+#define AuthenticationChallengeBase_h
+
+#include "Credential.h"
+#include "ProtectionSpace.h"
+#include "ResourceResponse.h"
+#include "ResourceError.h"
+
+namespace WebCore {
+
+class AuthenticationChallenge;
+
+class AuthenticationChallengeBase {
+public:
+ AuthenticationChallengeBase();
+ AuthenticationChallengeBase(const ProtectionSpace& protectionSpace, const Credential& proposedCredential, unsigned previousFailureCount, const ResourceResponse& response, const ResourceError& error);
+
+ unsigned previousFailureCount() const;
+ const Credential& proposedCredential() const;
+ const ProtectionSpace& protectionSpace() const;
+ const ResourceResponse& failureResponse() const;
+ const ResourceError& error() const;
+
+ bool isNull() const;
+ void nullify();
+
+ static bool compare(const AuthenticationChallenge& a, const AuthenticationChallenge& b);
+
+protected:
+ // The AuthenticationChallenge subclass may "shadow" this method to compare platform specific fields
+ static bool platformCompare(const AuthenticationChallengeBase& a, const AuthenticationChallengeBase& b) { return true; }
+
+ bool m_isNull;
+ ProtectionSpace m_protectionSpace;
+ Credential m_proposedCredential;
+ unsigned m_previousFailureCount;
+ ResourceResponse m_failureResponse;
+ ResourceError m_error;
+};
+
+inline bool operator==(const AuthenticationChallenge& a, const AuthenticationChallenge& b) { return AuthenticationChallengeBase::compare(a, b); }
+inline bool operator!=(const AuthenticationChallenge& a, const AuthenticationChallenge& b) { return !(a == b); }
+
+}
+
+#endif
diff --git a/WebCore/platform/network/Credential.cpp b/WebCore/platform/network/Credential.cpp
new file mode 100644
index 0000000..4743959
--- /dev/null
+++ b/WebCore/platform/network/Credential.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "Credential.h"
+
+namespace WebCore {
+
+// Need to enforce empty, non-null strings due to the pickiness of the String == String operator
+// combined with the semantics of the String(NSString*) constructor
+Credential::Credential()
+ : m_user("")
+ , m_password("")
+{
+}
+
+// Need to enforce empty, non-null strings due to the pickiness of the String == String operator
+// combined with the semantics of the String(NSString*) constructor
+Credential::Credential(const String& user, const String& password, CredentialPersistence persistence)
+ : m_user(user.length() ? user : "")
+ , m_password(password.length() ? password : "")
+ , m_persistence(persistence)
+{
+}
+
+const String& Credential::user() const
+{
+ return m_user;
+}
+
+const String& Credential::password() const
+{
+ return m_password;
+}
+
+bool Credential::hasPassword() const
+{
+ return !m_password.isEmpty();
+}
+
+CredentialPersistence Credential::persistence() const
+{
+ return m_persistence;
+}
+
+bool operator==(const Credential& a, const Credential& b)
+{
+ if (a.user() != b.user())
+ return false;
+ if (a.password() != b.password())
+ return false;
+ if (a.persistence() != b.persistence())
+ return false;
+
+ return true;
+}
+
+}
+
diff --git a/WebCore/platform/network/Credential.h b/WebCore/platform/network/Credential.h
new file mode 100644
index 0000000..4d80490
--- /dev/null
+++ b/WebCore/platform/network/Credential.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef Credential_h
+#define Credential_h
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+enum CredentialPersistence {
+ CredentialPersistenceNone,
+ CredentialPersistenceForSession,
+ CredentialPersistencePermanent
+};
+
+class Credential {
+
+public:
+ Credential();
+ Credential(const String& user, const String& password, CredentialPersistence);
+
+ const String& user() const;
+ const String& password() const;
+ bool hasPassword() const;
+ CredentialPersistence persistence() const;
+
+private:
+ String m_user;
+ String m_password;
+ CredentialPersistence m_persistence;
+};
+
+bool operator==(const Credential& a, const Credential& b);
+inline bool operator!=(const Credential& a, const Credential& b) { return !(a == b); }
+
+};
+#endif
diff --git a/WebCore/platform/network/DNS.h b/WebCore/platform/network/DNS.h
new file mode 100644
index 0000000..c232272
--- /dev/null
+++ b/WebCore/platform/network/DNS.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 Collin Jackson <collinj@webkit.org>
+ *
+ * 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 AND ITS CONTRIBUTORS "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 COMPUTER, 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.
+ */
+
+#ifndef DNS_h
+#define DNS_h
+
+namespace WebCore {
+
+ class String;
+
+ void prefetchDNS(const String& hostname);
+}
+
+#endif
diff --git a/WebCore/platform/network/FormData.cpp b/WebCore/platform/network/FormData.cpp
new file mode 100644
index 0000000..0d31856
--- /dev/null
+++ b/WebCore/platform/network/FormData.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "FormData.h"
+
+#include "CString.h"
+#include "ChromeClient.h"
+#include "FileSystem.h"
+#include "TextEncoding.h"
+
+namespace WebCore {
+
+inline FormData::FormData()
+ : m_hasGeneratedFiles(false)
+ , m_alwaysStream(false)
+{
+}
+
+inline FormData::FormData(const FormData& data)
+ : RefCounted<FormData>()
+ , m_elements(data.m_elements)
+ , m_hasGeneratedFiles(false)
+ , m_alwaysStream(false)
+{
+ // We shouldn't be copying FormData that hasn't already removed its generated files
+ // but just in case, make sure the new FormData is ready to generate its own files.
+ if (data.m_hasGeneratedFiles) {
+ size_t n = m_elements.size();
+ for (size_t i = 0; i < n; ++i) {
+ FormDataElement& e = m_elements[i];
+ if (e.m_type == FormDataElement::encodedFile)
+ e.m_generatedFilename = String();
+ }
+ }
+}
+
+FormData::~FormData()
+{
+ // This cleanup should've happened when the form submission finished.
+ // Just in case, let's assert, and do the cleanup anyway in release builds.
+ ASSERT(!m_hasGeneratedFiles);
+ removeGeneratedFilesIfNeeded();
+}
+
+PassRefPtr<FormData> FormData::create()
+{
+ return adoptRef(new FormData);
+}
+
+PassRefPtr<FormData> FormData::create(const void* data, size_t size)
+{
+ RefPtr<FormData> result = create();
+ result->appendData(data, size);
+ return result.release();
+}
+
+PassRefPtr<FormData> FormData::create(const CString& string)
+{
+ RefPtr<FormData> result = create();
+ result->appendData(string.data(), string.length());
+ return result.release();
+}
+
+PassRefPtr<FormData> FormData::create(const Vector<char>& vector)
+{
+ RefPtr<FormData> result = create();
+ result->appendData(vector.data(), vector.size());
+ return result.release();
+}
+
+PassRefPtr<FormData> FormData::copy() const
+{
+ return adoptRef(new FormData(*this));
+}
+
+void FormData::appendData(const void* data, size_t size)
+{
+ if (m_elements.isEmpty() || m_elements.last().m_type != FormDataElement::data)
+ m_elements.append(FormDataElement());
+ FormDataElement& e = m_elements.last();
+ size_t oldSize = e.m_data.size();
+ e.m_data.grow(oldSize + size);
+ memcpy(e.m_data.data() + oldSize, data, size);
+}
+
+void FormData::appendFile(const String& filename, bool shouldGenerateFile)
+{
+ m_elements.append(FormDataElement(filename, shouldGenerateFile));
+}
+
+void FormData::flatten(Vector<char>& data) const
+{
+ // Concatenate all the byte arrays, but omit any files.
+ data.clear();
+ size_t n = m_elements.size();
+ for (size_t i = 0; i < n; ++i) {
+ const FormDataElement& e = m_elements[i];
+ if (e.m_type == FormDataElement::data) {
+ size_t oldSize = data.size();
+ size_t delta = e.m_data.size();
+ data.grow(oldSize + delta);
+ memcpy(data.data() + oldSize, e.m_data.data(), delta);
+ }
+ }
+}
+
+String FormData::flattenToString() const
+{
+ Vector<char> bytes;
+ flatten(bytes);
+ return Latin1Encoding().decode(bytes.data(), bytes.size());
+}
+
+void FormData::generateFiles(ChromeClient* client)
+{
+ ASSERT(!m_hasGeneratedFiles);
+
+ if (m_hasGeneratedFiles)
+ return;
+
+ size_t n = m_elements.size();
+ for (size_t i = 0; i < n; ++i) {
+ FormDataElement& e = m_elements[i];
+ if (e.m_type == FormDataElement::encodedFile && e.m_shouldGenerateFile) {
+ e.m_generatedFilename = client->generateReplacementFile(e.m_filename);
+ m_hasGeneratedFiles = true;
+ }
+ }
+}
+
+void FormData::removeGeneratedFilesIfNeeded()
+{
+ if (!m_hasGeneratedFiles)
+ return;
+
+ size_t n = m_elements.size();
+ for (size_t i = 0; i < n; ++i) {
+ FormDataElement& e = m_elements[i];
+ if (e.m_type == FormDataElement::encodedFile && !e.m_generatedFilename.isEmpty()) {
+ ASSERT(e.m_shouldGenerateFile);
+ String directory = directoryName(e.m_generatedFilename);
+ deleteFile(e.m_generatedFilename);
+ deleteEmptyDirectory(directory);
+ e.m_generatedFilename = String();
+ }
+ }
+ m_hasGeneratedFiles = false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/FormData.h b/WebCore/platform/network/FormData.h
new file mode 100644
index 0000000..cb91fab
--- /dev/null
+++ b/WebCore/platform/network/FormData.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FormData_h
+#define FormData_h
+
+#include "PlatformString.h"
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class ChromeClient;
+
+class FormDataElement {
+public:
+ FormDataElement() : m_type(data) { }
+ FormDataElement(const Vector<char>& array) : m_type(data), m_data(array) { }
+ FormDataElement(const String& filename, bool shouldGenerateFile) : m_type(encodedFile), m_filename(filename), m_shouldGenerateFile(shouldGenerateFile) { }
+
+ enum { data, encodedFile } m_type;
+ Vector<char> m_data;
+ String m_filename;
+ String m_generatedFilename;
+ bool m_shouldGenerateFile;
+};
+
+inline bool operator==(const FormDataElement& a, const FormDataElement& b)
+{
+ if (&a == &b)
+ return true;
+
+ if (a.m_type != b.m_type)
+ return false;
+ if (a.m_data != b.m_data)
+ return false;
+ if (a.m_filename != b.m_filename)
+ return false;
+
+ return true;
+}
+
+inline bool operator!=(const FormDataElement& a, const FormDataElement& b)
+{
+ return !(a == b);
+}
+
+class FormData : public RefCounted<FormData> {
+public:
+ static PassRefPtr<FormData> create();
+ static PassRefPtr<FormData> create(const void*, size_t);
+ static PassRefPtr<FormData> create(const CString&);
+ static PassRefPtr<FormData> create(const Vector<char>&);
+ PassRefPtr<FormData> copy() const;
+ ~FormData();
+
+ void appendData(const void* data, size_t);
+ void appendFile(const String& filename, bool shouldGenerateFile = false);
+
+ void flatten(Vector<char>&) const; // omits files
+ String flattenToString() const; // omits files
+
+ bool isEmpty() const { return m_elements.isEmpty(); }
+ const Vector<FormDataElement>& elements() const { return m_elements; }
+
+ void generateFiles(ChromeClient*);
+ void removeGeneratedFilesIfNeeded();
+
+ bool alwaysStream() const { return m_alwaysStream; }
+ void setAlwaysStream(bool alwaysStream) { m_alwaysStream = alwaysStream; }
+
+private:
+ FormData();
+ FormData(const FormData&);
+
+ Vector<FormDataElement> m_elements;
+ bool m_hasGeneratedFiles;
+ bool m_alwaysStream;
+};
+
+inline bool operator==(const FormData& a, const FormData& b)
+{
+ return a.elements() == b.elements();
+}
+
+inline bool operator!=(const FormData& a, const FormData& b)
+{
+ return a.elements() != b.elements();
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/network/HTTPHeaderMap.h b/WebCore/platform/network/HTTPHeaderMap.h
new file mode 100644
index 0000000..dc204cb
--- /dev/null
+++ b/WebCore/platform/network/HTTPHeaderMap.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef HTTPHeaderMap_h
+#define HTTPHeaderMap_h
+
+#include "StringHash.h"
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+ typedef HashMap<String, String, CaseFoldingHash> HTTPHeaderMap;
+
+} // namespace WebCore
+
+#endif // HTTPHeaderMap_h
diff --git a/WebCore/platform/network/HTTPParsers.cpp b/WebCore/platform/network/HTTPParsers.cpp
new file mode 100644
index 0000000..0858fc9
--- /dev/null
+++ b/WebCore/platform/network/HTTPParsers.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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"
+#include "HTTPParsers.h"
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+// true if there is more to parse
+static inline bool skipWhiteSpace(const String& str, int& pos, bool fromHttpEquivMeta)
+{
+ int len = str.length();
+
+ if (fromHttpEquivMeta)
+ while (pos != len && str[pos] <= ' ')
+ ++pos;
+ else
+ while (pos != len && (str[pos] == '\t' || str[pos] == ' '))
+ ++pos;
+
+ return pos != len;
+}
+
+bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& delay, String& url)
+{
+ int len = refresh.length();
+ int pos = 0;
+
+ if (!skipWhiteSpace(refresh, pos, fromHttpEquivMeta))
+ return false;
+
+ while (pos != len && refresh[pos] != ',' && refresh[pos] != ';')
+ ++pos;
+
+ if (pos == len) { // no URL
+ url = String();
+ bool ok;
+ delay = refresh.stripWhiteSpace().toDouble(&ok);
+ return ok;
+ } else {
+ bool ok;
+ delay = refresh.left(pos).stripWhiteSpace().toDouble(&ok);
+ if (!ok)
+ return false;
+
+ ++pos;
+ skipWhiteSpace(refresh, pos, fromHttpEquivMeta);
+ int urlStartPos = pos;
+ if (refresh.find("url", urlStartPos, false) == urlStartPos) {
+ urlStartPos += 3;
+ skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta);
+ if (refresh[urlStartPos] == '=') {
+ ++urlStartPos;
+ skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta);
+ } else
+ urlStartPos = pos; // e.g. "Refresh: 0; url.html"
+ }
+
+ int urlEndPos = len;
+
+ if (refresh[urlStartPos] == '"' || refresh[urlStartPos] == '\'') {
+ UChar quotationMark = refresh[urlStartPos];
+ urlStartPos++;
+ while (urlEndPos > urlStartPos) {
+ urlEndPos--;
+ if (refresh[urlEndPos] == quotationMark)
+ break;
+ }
+ }
+
+ url = refresh.substring(urlStartPos, urlEndPos - urlStartPos).stripWhiteSpace();
+ return true;
+ }
+}
+
+String filenameFromHTTPContentDisposition(const String& value)
+{
+ Vector<String> keyValuePairs;
+ value.split(';', keyValuePairs);
+
+ unsigned length = keyValuePairs.size();
+ for (unsigned i = 0; i < length; i++) {
+ int valueStartPos = keyValuePairs[i].find('=');
+ if (valueStartPos < 0)
+ continue;
+
+ String key = keyValuePairs[i].left(valueStartPos).stripWhiteSpace();
+
+ if (key.isEmpty() || key != "filename")
+ continue;
+
+ String value = keyValuePairs[i].substring(valueStartPos + 1).stripWhiteSpace();
+
+ // Remove quotes if there are any
+ if (value[0] == '\"')
+ value = value.substring(1, value.length() - 2);
+
+ return value;
+ }
+
+ return String();
+}
+
+String extractMIMETypeFromMediaType(const String& mediaType)
+{
+ String mimeType;
+ unsigned length = mediaType.length();
+ for (unsigned offset = 0; offset < length; offset++) {
+ UChar c = mediaType[offset];
+ if (c == ';')
+ break;
+ else if (isSpaceOrNewline(c)) // FIXME: This seems wrong, " " is an invalid MIME type character according to RFC 2045. bug 8644
+ continue;
+ // FIXME: This is a very slow way to build a string, given WebCore::String's implementation.
+ mimeType += String(&c, 1);
+ }
+ return mimeType;
+}
+
+String extractCharsetFromMediaType(const String& mediaType)
+{
+ int pos = 0;
+ int length = (int)mediaType.length();
+
+ while (pos < length) {
+ pos = mediaType.find("charset", pos, false);
+ if (pos <= 0)
+ return String();
+
+ // is what we found a beginning of a word?
+ if (mediaType[pos-1] > ' ' && mediaType[pos-1] != ';') {
+ pos += 7;
+ continue;
+ }
+
+ pos += 7;
+
+ // skip whitespace
+ while (pos != length && mediaType[pos] <= ' ')
+ ++pos;
+
+ if (mediaType[pos++] != '=') // this "charset" substring wasn't a parameter name, but there may be others
+ continue;
+
+ while (pos != length && (mediaType[pos] <= ' ' || mediaType[pos] == '"' || mediaType[pos] == '\''))
+ ++pos;
+
+ // we don't handle spaces within quoted parameter values, because charset names cannot have any
+ int endpos = pos;
+ while (pos != length && mediaType[endpos] > ' ' && mediaType[endpos] != '"' && mediaType[endpos] != '\'' && mediaType[endpos] != ';')
+ ++endpos;
+
+ return mediaType.substring(pos, endpos-pos);
+ }
+
+ return String();
+}
+}
diff --git a/WebCore/platform/network/HTTPParsers.h b/WebCore/platform/network/HTTPParsers.h
new file mode 100644
index 0000000..28a9ce9
--- /dev/null
+++ b/WebCore/platform/network/HTTPParsers.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#ifndef HTTPParsers_h
+#define HTTPParsers_h
+
+namespace WebCore {
+
+ class String;
+
+ bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& delay, String& url);
+ String filenameFromHTTPContentDisposition(const String&);
+ String extractMIMETypeFromMediaType(const String&);
+ String extractCharsetFromMediaType(const String&);
+}
+
+#endif
diff --git a/WebCore/platform/network/NetworkStateNotifier.cpp b/WebCore/platform/network/NetworkStateNotifier.cpp
new file mode 100644
index 0000000..d39fc30
--- /dev/null
+++ b/WebCore/platform/network/NetworkStateNotifier.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * 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"
+#include "NetworkStateNotifier.h"
+
+#include <wtf/Assertions.h>
+
+namespace WebCore {
+
+NetworkStateNotifier& networkStateNotifier()
+{
+ static NetworkStateNotifier networkStateNotifier;
+
+ return networkStateNotifier;
+}
+
+void NetworkStateNotifier::setNetworkStateChangedFunction(void(*function)())
+{
+ ASSERT(!m_networkStateChangedFunction);
+
+ m_networkStateChangedFunction = function;
+}
+
+}
diff --git a/WebCore/platform/network/NetworkStateNotifier.h b/WebCore/platform/network/NetworkStateNotifier.h
new file mode 100644
index 0000000..53ab4c8
--- /dev/null
+++ b/WebCore/platform/network/NetworkStateNotifier.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef NetworkStateNotifier_h
+#define NetworkStateNotifier_h
+
+#if PLATFORM(MAC)
+
+#include <wtf/RetainPtr.h>
+#include "Timer.h"
+
+typedef const struct __CFArray * CFArrayRef;
+typedef const struct __SCDynamicStore * SCDynamicStoreRef;
+
+#elif PLATFORM(CHROMIUM)
+
+#include "NetworkStateNotifierPrivate.h"
+
+#elif PLATFORM(WIN)
+
+#include <windows.h>
+
+#endif
+
+namespace WebCore {
+
+class NetworkStateNotifier {
+public:
+ NetworkStateNotifier();
+ void setNetworkStateChangedFunction(void (*)());
+
+ bool onLine() const { return m_isOnLine; }
+
+private:
+ bool m_isOnLine;
+ void (*m_networkStateChangedFunction)();
+
+ void updateState();
+
+#if PLATFORM(MAC)
+ void networkStateChangeTimerFired(Timer<NetworkStateNotifier>*);
+
+ static void dynamicStoreCallback(SCDynamicStoreRef, CFArrayRef changedKeys, void *info);
+
+ RetainPtr<SCDynamicStoreRef> m_store;
+ Timer<NetworkStateNotifier> m_networkStateChangeTimer;
+
+#elif PLATFORM(WIN)
+ static void CALLBACK addrChangeCallback(void*, BOOLEAN timedOut);
+ static void callAddressChanged(void*);
+ void addressChanged();
+
+ void registerForAddressChange();
+ HANDLE m_waitHandle;
+ OVERLAPPED m_overlapped;
+
+#elif PLATFORM(ANDROID)
+public:
+ void networkStateChange(bool online);
+
+#elif PLATFORM(CHROMIUM)
+ NetworkStateNotifierPrivate p;
+#endif
+};
+
+#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(CHROMIUM)
+
+inline NetworkStateNotifier::NetworkStateNotifier()
+ : m_isOnLine(true)
+{
+}
+
+inline void NetworkStateNotifier::updateState() { }
+
+#endif
+
+NetworkStateNotifier& networkStateNotifier();
+
+};
+
+#endif // NetworkStateNotifier_h
diff --git a/WebCore/platform/network/ProtectionSpace.cpp b/WebCore/platform/network/ProtectionSpace.cpp
new file mode 100644
index 0000000..bd73558
--- /dev/null
+++ b/WebCore/platform/network/ProtectionSpace.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "ProtectionSpace.h"
+
+#if USE(CFNETWORK) && !PLATFORM(MAC)
+#include "AuthenticationCF.h"
+#include <CFNetwork/CFURLProtectionSpacePriv.h>
+#include <wtf/RetainPtr.h>
+#endif
+
+namespace WebCore {
+
+// Need to enforce empty, non-null strings due to the pickiness of the String == String operator
+// combined with the semantics of the String(NSString*) constructor
+ProtectionSpace::ProtectionSpace()
+ : m_host("")
+ , m_realm("")
+{
+}
+
+// Need to enforce empty, non-null strings due to the pickiness of the String == String operator
+// combined with the semantics of the String(NSString*) constructor
+ProtectionSpace::ProtectionSpace(const String& host, int port, ProtectionSpaceServerType serverType, const String& realm, ProtectionSpaceAuthenticationScheme authenticationScheme)
+ : m_host(host.length() ? host : "")
+ , m_port(port)
+ , m_serverType(serverType)
+ , m_realm(realm.length() ? realm : "")
+ , m_authenticationScheme(authenticationScheme)
+{
+}
+
+const String& ProtectionSpace::host() const
+{
+ return m_host;
+}
+
+int ProtectionSpace::port() const
+{
+ return m_port;
+}
+
+ProtectionSpaceServerType ProtectionSpace::serverType() const
+{
+ return m_serverType;
+}
+
+bool ProtectionSpace::isProxy() const
+{
+ return (m_serverType == ProtectionSpaceProxyHTTP ||
+ m_serverType == ProtectionSpaceProxyHTTPS ||
+ m_serverType == ProtectionSpaceProxyFTP ||
+ m_serverType == ProtectionSpaceProxySOCKS);
+}
+
+const String& ProtectionSpace::realm() const
+{
+ return m_realm;
+}
+
+ProtectionSpaceAuthenticationScheme ProtectionSpace::authenticationScheme() const
+{
+ return m_authenticationScheme;
+}
+
+bool ProtectionSpace::receivesCredentialSecurely() const
+{
+#if USE(CFNETWORK) && !PLATFORM(MAC)
+ RetainPtr<CFURLProtectionSpaceRef> cfSpace(AdoptCF, createCF(*this));
+ return cfSpace && CFURLProtectionSpaceReceivesCredentialSecurely(cfSpace.get());
+#else
+ return (m_serverType == ProtectionSpaceServerHTTPS ||
+ m_serverType == ProtectionSpaceServerFTPS ||
+ m_serverType == ProtectionSpaceProxyHTTPS ||
+ m_authenticationScheme == ProtectionSpaceAuthenticationSchemeHTTPDigest);
+#endif
+}
+
+bool operator==(const ProtectionSpace& a, const ProtectionSpace& b)
+{
+ if (a.host() != b.host())
+ return false;
+ if (a.port() != b.port())
+ return false;
+ if (a.serverType() != b.serverType())
+ return false;
+ if (a.realm() != b.realm())
+ return false;
+ if (a.authenticationScheme() != b.authenticationScheme())
+ return false;
+
+ return true;
+}
+
+}
+
+
diff --git a/WebCore/platform/network/ProtectionSpace.h b/WebCore/platform/network/ProtectionSpace.h
new file mode 100644
index 0000000..9a73cff
--- /dev/null
+++ b/WebCore/platform/network/ProtectionSpace.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef ProtectionSpace_h
+#define ProtectionSpace_h
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+enum ProtectionSpaceServerType {
+ ProtectionSpaceServerHTTP = 1,
+ ProtectionSpaceServerHTTPS = 2,
+ ProtectionSpaceServerFTP = 3,
+ ProtectionSpaceServerFTPS = 4,
+ ProtectionSpaceProxyHTTP = 5,
+ ProtectionSpaceProxyHTTPS = 6,
+ ProtectionSpaceProxyFTP = 7,
+ ProtectionSpaceProxySOCKS = 8
+};
+
+enum ProtectionSpaceAuthenticationScheme {
+ ProtectionSpaceAuthenticationSchemeDefault = 1,
+ ProtectionSpaceAuthenticationSchemeHTTPBasic = 2,
+ ProtectionSpaceAuthenticationSchemeHTTPDigest = 3,
+ ProtectionSpaceAuthenticationSchemeHTMLForm = 4,
+ ProtectionSpaceAuthenticationSchemeNTLM = 5,
+ ProtectionSpaceAuthenticationSchemeNegotiate = 6,
+};
+
+class ProtectionSpace {
+
+public:
+ ProtectionSpace();
+ ProtectionSpace(const String& host, int port, ProtectionSpaceServerType, const String& realm, ProtectionSpaceAuthenticationScheme);
+
+ const String& host() const;
+ int port() const;
+ ProtectionSpaceServerType serverType() const;
+ bool isProxy() const;
+ const String& realm() const;
+ ProtectionSpaceAuthenticationScheme authenticationScheme() const;
+
+ bool receivesCredentialSecurely() const;
+
+private:
+ String m_host;
+ int m_port;
+ ProtectionSpaceServerType m_serverType;
+ String m_realm;
+ ProtectionSpaceAuthenticationScheme m_authenticationScheme;
+};
+
+bool operator==(const ProtectionSpace& a, const ProtectionSpace& b);
+inline bool operator!=(const ProtectionSpace& a, const ProtectionSpace& b) { return !(a == b); }
+
+}
+#endif
diff --git a/WebCore/platform/network/ResourceErrorBase.cpp b/WebCore/platform/network/ResourceErrorBase.cpp
new file mode 100644
index 0000000..1ea35b0
--- /dev/null
+++ b/WebCore/platform/network/ResourceErrorBase.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "ResourceError.h"
+
+namespace WebCore {
+
+void ResourceErrorBase::lazyInit() const
+{
+ const_cast<ResourceError*>(static_cast<const ResourceError*>(this))->platformLazyInit();
+}
+
+bool ResourceErrorBase::compare(const ResourceError& a, const ResourceError& b)
+{
+ if (a.isNull() && b.isNull())
+ return true;
+
+ if (a.isNull() || b.isNull())
+ return false;
+
+ if (a.domain() != b.domain())
+ return false;
+
+ if (a.errorCode() != b.errorCode())
+ return false;
+
+ if (a.failingURL() != b.failingURL())
+ return false;
+
+ if (a.localizedDescription() != b.localizedDescription())
+ return false;
+
+ if (a.isCancellation() != b.isCancellation())
+ return false;
+
+ return platformCompare(a, b);
+}
+
+}
diff --git a/WebCore/platform/network/ResourceErrorBase.h b/WebCore/platform/network/ResourceErrorBase.h
new file mode 100644
index 0000000..b2aac67
--- /dev/null
+++ b/WebCore/platform/network/ResourceErrorBase.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceErrorBase_h
+#define ResourceErrorBase_h
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class ResourceError;
+
+class ResourceErrorBase {
+public:
+ bool isNull() const { return m_isNull; }
+
+ const String& domain() const { lazyInit(); return m_domain; }
+ int errorCode() const { lazyInit(); return m_errorCode; }
+ const String& failingURL() const { lazyInit(); return m_failingURL; }
+ const String& localizedDescription() const { lazyInit(); return m_localizedDescription; }
+
+ void setIsCancellation(bool isCancellation) { m_isCancellation = isCancellation; }
+ bool isCancellation() const { return m_isCancellation; }
+
+ static bool compare(const ResourceError& a, const ResourceError& b);
+
+protected:
+ ResourceErrorBase()
+ : m_errorCode(0)
+ , m_isNull(true)
+ , m_isCancellation(false)
+ {
+ }
+
+ ResourceErrorBase(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription)
+ : m_domain(domain)
+ , m_errorCode(errorCode)
+ , m_failingURL(failingURL)
+ , m_localizedDescription(localizedDescription)
+ , m_isNull(false)
+ , m_isCancellation(false)
+ {
+ }
+
+ void lazyInit() const;
+
+ // The ResourceError subclass may "shadow" this method to lazily initialize platform specific fields
+ void platformLazyInit() {}
+
+ // The ResourceError subclass may "shadow" this method to compare platform specific fields
+ static bool platformCompare(const ResourceError& a, const ResourceError& b) { return true; }
+
+ String m_domain;
+ int m_errorCode;
+ String m_failingURL;
+ String m_localizedDescription;
+ bool m_isNull;
+ bool m_isCancellation;
+};
+
+inline bool operator==(const ResourceError& a, const ResourceError& b) { return ResourceErrorBase::compare(a, b); }
+inline bool operator!=(const ResourceError& a, const ResourceError& b) { return !(a == b); }
+
+} // namespace WebCore
+
+#endif // ResourceErrorBase_h_
diff --git a/WebCore/platform/network/ResourceHandle.cpp b/WebCore/platform/network/ResourceHandle.cpp
new file mode 100644
index 0000000..149411e
--- /dev/null
+++ b/WebCore/platform/network/ResourceHandle.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "ResourceHandle.h"
+#include "ResourceHandleInternal.h"
+
+#include "Logging.h"
+#include "ResourceHandleClient.h"
+#include "Timer.h"
+#include <algorithm>
+
+namespace WebCore {
+
+static bool portAllowed(const ResourceRequest&);
+
+ResourceHandle::ResourceHandle(const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading,
+ bool shouldContentSniff, bool mightDownloadFromHandle)
+ : d(new ResourceHandleInternal(this, request, client, defersLoading, shouldContentSniff, mightDownloadFromHandle))
+{
+}
+
+PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request, ResourceHandleClient* client,
+ Frame* frame, bool defersLoading, bool shouldContentSniff, bool mightDownloadFromHandle)
+{
+ RefPtr<ResourceHandle> newHandle(adoptRef(new ResourceHandle(request, client, defersLoading, shouldContentSniff, mightDownloadFromHandle)));
+
+ if (!request.url().isValid()) {
+ newHandle->scheduleFailure(InvalidURLFailure);
+ return newHandle.release();
+ }
+
+ if (!portAllowed(request)) {
+ newHandle->scheduleFailure(BlockedFailure);
+ return newHandle.release();
+ }
+
+ if (newHandle->start(frame))
+ return newHandle.release();
+
+ return 0;
+}
+
+void ResourceHandle::scheduleFailure(FailureType type)
+{
+ d->m_failureType = type;
+ d->m_failureTimer.startOneShot(0);
+}
+
+void ResourceHandle::fireFailure(Timer<ResourceHandle>*)
+{
+ if (!client())
+ return;
+
+ switch (d->m_failureType) {
+ case BlockedFailure:
+ client()->wasBlocked(this);
+ return;
+ case InvalidURLFailure:
+ client()->cannotShowURL(this);
+ return;
+ }
+
+ ASSERT_NOT_REACHED();
+}
+
+ResourceHandleClient* ResourceHandle::client() const
+{
+ return d->m_client;
+}
+
+void ResourceHandle::setClient(ResourceHandleClient* client)
+{
+ d->m_client = client;
+}
+
+const ResourceRequest& ResourceHandle::request() const
+{
+ return d->m_request;
+}
+
+void ResourceHandle::clearAuthentication()
+{
+#if PLATFORM(MAC)
+ d->m_currentMacChallenge = nil;
+#elif USE(CFNETWORK)
+ d->m_currentCFChallenge = 0;
+#endif
+ d->m_currentWebChallenge.nullify();
+}
+
+static bool portAllowed(const ResourceRequest& request)
+{
+ unsigned short port = request.url().port();
+
+ // Since most URLs don't have a port, return early for the "no port" case.
+ if (!port)
+ return true;
+
+ // This blocked port list matches the port blocking that Mozilla implements.
+ // See http://www.mozilla.org/projects/netlib/PortBanning.html for more information.
+ static const unsigned short blockedPortList[] = {
+ 1, // tcpmux
+ 7, // echo
+ 9, // discard
+ 11, // systat
+ 13, // daytime
+ 15, // netstat
+ 17, // qotd
+ 19, // chargen
+ 20, // FTP-data
+ 21, // FTP-control
+ 22, // SSH
+ 23, // telnet
+ 25, // SMTP
+ 37, // time
+ 42, // name
+ 43, // nicname
+ 53, // domain
+ 77, // priv-rjs
+ 79, // finger
+ 87, // ttylink
+ 95, // supdup
+ 101, // hostriame
+ 102, // iso-tsap
+ 103, // gppitnp
+ 104, // acr-nema
+ 109, // POP2
+ 110, // POP3
+ 111, // sunrpc
+ 113, // auth
+ 115, // SFTP
+ 117, // uucp-path
+ 119, // nntp
+ 123, // NTP
+ 135, // loc-srv / epmap
+ 139, // netbios
+ 143, // IMAP2
+ 179, // BGP
+ 389, // LDAP
+ 465, // SMTP+SSL
+ 512, // print / exec
+ 513, // login
+ 514, // shell
+ 515, // printer
+ 526, // tempo
+ 530, // courier
+ 531, // Chat
+ 532, // netnews
+ 540, // UUCP
+ 556, // remotefs
+ 563, // NNTP+SSL
+ 587, // ESMTP
+ 601, // syslog-conn
+ 636, // LDAP+SSL
+ 993, // IMAP+SSL
+ 995, // POP3+SSL
+ 2049, // NFS
+ 4045, // lockd
+ 6000, // X11
+ };
+ const unsigned short* const blockedPortListEnd = blockedPortList
+ + sizeof(blockedPortList) / sizeof(blockedPortList[0]);
+
+ // If the port is not in the blocked port list, allow it.
+ if (!std::binary_search(blockedPortList, blockedPortListEnd, port))
+ return true;
+
+ // Allow ports 21 and 22 for FTP URLs, as Mozilla does.
+ if ((port == 21 || port == 22) && request.url().protocolIs("ftp"))
+ return true;
+
+ // Allow any port number in a file URL, since the port number is ignored.
+ if (request.url().protocolIs("file"))
+ return true;
+
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/ResourceHandle.h b/WebCore/platform/network/ResourceHandle.h
new file mode 100644
index 0000000..304bdbe
--- /dev/null
+++ b/WebCore/platform/network/ResourceHandle.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceHandle_h
+#define ResourceHandle_h
+
+#include "AuthenticationChallenge.h"
+#include "HTTPHeaderMap.h"
+#include <wtf/OwnPtr.h>
+
+#if PLATFORM(CF)
+typedef const struct __CFData * CFDataRef;
+#endif
+
+#if PLATFORM(WIN)
+typedef unsigned long DWORD;
+typedef unsigned long DWORD_PTR;
+typedef void* LPVOID;
+typedef LPVOID HINTERNET;
+typedef unsigned WPARAM;
+typedef long LPARAM;
+typedef struct HWND__* HWND;
+typedef _W64 long LONG_PTR;
+typedef LONG_PTR LRESULT;
+#endif
+
+
+#if PLATFORM(MAC)
+#include <wtf/RetainPtr.h>
+#ifdef __OBJC__
+@class NSData;
+@class NSError;
+@class NSURLConnection;
+@class WebCoreResourceHandleAsDelegate;
+#else
+class NSData;
+class NSError;
+class NSURLConnection;
+class WebCoreResourceHandleAsDelegate;
+typedef struct objc_object *id;
+#endif
+#endif
+
+#if USE(CFNETWORK)
+typedef struct _CFURLConnection* CFURLConnectionRef;
+typedef int CFHTTPCookieStorageAcceptPolicy;
+typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef;
+#endif
+
+namespace WebCore {
+
+class AuthenticationChallenge;
+class Credential;
+class FormData;
+class Frame;
+class KURL;
+class ResourceError;
+class ResourceHandleClient;
+class ResourceHandleInternal;
+class ResourceRequest;
+class ResourceResponse;
+class SchedulePair;
+class SharedBuffer;
+class SubresourceLoader;
+class SubresourceLoaderClient;
+
+template <typename T> class Timer;
+
+class ResourceHandle : public RefCounted<ResourceHandle> {
+private:
+ ResourceHandle(const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff, bool mightDownloadFromHandle);
+
+ enum FailureType {
+ BlockedFailure,
+ InvalidURLFailure
+ };
+
+public:
+ // FIXME: should not need the Frame
+ static PassRefPtr<ResourceHandle> create(const ResourceRequest&, ResourceHandleClient*, Frame*, bool defersLoading, bool shouldContentSniff, bool mightDownloadFromHandle = false);
+
+ static void loadResourceSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data, Frame* frame);
+ static bool willLoadFromCache(ResourceRequest&);
+#if PLATFORM(MAC)
+ static bool didSendBodyDataDelegateExists();
+#endif
+
+ ~ResourceHandle();
+
+#if PLATFORM(MAC) || USE(CFNETWORK) || USE(CURL)
+ void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
+ void receivedCredential(const AuthenticationChallenge&, const Credential&);
+ void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&);
+ void receivedCancellation(const AuthenticationChallenge&);
+#endif
+
+#if PLATFORM(MAC)
+ void didCancelAuthenticationChallenge(const AuthenticationChallenge&);
+ NSURLConnection *connection() const;
+ WebCoreResourceHandleAsDelegate *delegate();
+ void releaseDelegate();
+ id releaseProxy();
+
+ void schedule(SchedulePair*);
+ void unschedule(SchedulePair*);
+#elif USE(CFNETWORK)
+ static CFRunLoopRef loaderRunLoop();
+ CFURLConnectionRef connection() const;
+ CFURLConnectionRef releaseConnectionForDownload();
+ static void setHostAllowsAnyHTTPSCertificate(const String&);
+ static void setClientCertificate(const String& host, CFDataRef);
+#endif
+
+#if PLATFORM(WIN) && USE(CURL)
+ static void setHostAllowsAnyHTTPSCertificate(const String&);
+#endif
+#if PLATFORM(WIN) && USE(CURL) && PLATFORM(CF)
+ static void setClientCertificate(const String& host, CFDataRef);
+#endif
+
+ PassRefPtr<SharedBuffer> bufferedData();
+ static bool supportsBufferedData();
+
+#if USE(WININET)
+ void setHasReceivedResponse(bool = true);
+ bool hasReceivedResponse() const;
+ void fileLoadTimer(Timer<ResourceHandle>*);
+ void onHandleCreated(LPARAM);
+ void onRequestRedirected(LPARAM);
+ void onRequestComplete(LPARAM);
+ friend void __stdcall transferJobStatusCallback(HINTERNET, DWORD_PTR, DWORD, LPVOID, DWORD);
+ friend LRESULT __stdcall ResourceHandleWndProc(HWND, unsigned message, WPARAM, LPARAM);
+#endif
+
+#if PLATFORM(QT) || USE(CURL) || USE(SOUP) || defined(ANDROID)
+ ResourceHandleInternal* getInternal() { return d.get(); }
+#endif
+
+ // Used to work around the fact that you don't get any more NSURLConnection callbacks until you return from the one you're in.
+ static bool loadsBlocked();
+
+ void clearAuthentication();
+ void cancel();
+
+ // The client may be 0, in which case no callbacks will be made.
+ ResourceHandleClient* client() const;
+ void setClient(ResourceHandleClient*);
+
+ void setDefersLoading(bool);
+
+ const ResourceRequest& request() const;
+
+ void fireFailure(Timer<ResourceHandle>*);
+
+private:
+#if USE(SOUP)
+ bool startData(String urlString);
+ bool startHttp(String urlString);
+ bool startGio(String urlString);
+#endif
+
+ void scheduleFailure(FailureType);
+
+ bool start(Frame*);
+
+ friend class ResourceHandleInternal;
+ OwnPtr<ResourceHandleInternal> d;
+};
+
+}
+
+#endif // ResourceHandle_h
diff --git a/WebCore/platform/network/ResourceHandleClient.h b/WebCore/platform/network/ResourceHandleClient.h
new file mode 100644
index 0000000..08e06a2
--- /dev/null
+++ b/WebCore/platform/network/ResourceHandleClient.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceHandleClient_h
+#define ResourceHandleClient_h
+
+#include <wtf/RefCounted.h>
+#include <wtf/Platform.h>
+#include <wtf/RefPtr.h>
+
+#if USE(CFNETWORK)
+#include <ConditionalMacros.h>
+#include <CFNetwork/CFURLResponsePriv.h>
+#endif
+
+#if PLATFORM(MAC)
+#ifdef __OBJC__
+@class NSCachedURLResponse;
+#else
+class NSCachedURLResponse;
+#endif
+#endif
+
+namespace WebCore {
+ class AuthenticationChallenge;
+ class Credential;
+ class KURL;
+ class ResourceHandle;
+ class ResourceError;
+ class ResourceRequest;
+ class ResourceResponse;
+
+ enum CacheStoragePolicy {
+ StorageAllowed,
+ StorageAllowedInMemoryOnly,
+ StorageNotAllowed,
+ };
+
+ class ResourceHandleClient {
+ public:
+ virtual ~ResourceHandleClient() { }
+
+ // request may be modified
+ virtual void willSendRequest(ResourceHandle*, ResourceRequest&, const ResourceResponse& redirectResponse) { }
+ virtual void didSendData(ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) { }
+
+ virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&) { }
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived) { }
+ virtual void didFinishLoading(ResourceHandle*) { }
+ virtual void didFail(ResourceHandle*, const ResourceError&) { }
+ virtual void wasBlocked(ResourceHandle*) { }
+ virtual void cannotShowURL(ResourceHandle*) { }
+
+ virtual void willCacheResponse(ResourceHandle*, CacheStoragePolicy&) { }
+
+ virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&) { }
+ virtual void didCancelAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&) { }
+ virtual void receivedCredential(ResourceHandle*, const AuthenticationChallenge&, const Credential&) { }
+ virtual void receivedRequestToContinueWithoutCredential(ResourceHandle*, const AuthenticationChallenge&) { }
+ virtual void receivedCancellation(ResourceHandle*, const AuthenticationChallenge&) { }
+
+#if PLATFORM(MAC)
+ virtual NSCachedURLResponse* willCacheResponse(ResourceHandle*, NSCachedURLResponse* response) { return response; }
+ virtual void willStopBufferingData(ResourceHandle*, const char*, int) { }
+#endif
+ };
+
+}
+
+#endif
diff --git a/WebCore/platform/network/ResourceHandleInternal.h b/WebCore/platform/network/ResourceHandleInternal.h
new file mode 100644
index 0000000..0bfa9da
--- /dev/null
+++ b/WebCore/platform/network/ResourceHandleInternal.h
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceHandleInternal_h
+#define ResourceHandleInternal_h
+
+#include "ResourceHandle.h"
+#include "ResourceRequest.h"
+#include "AuthenticationChallenge.h"
+#include "Timer.h"
+
+#if USE(CFNETWORK)
+#include <CFNetwork/CFURLConnectionPriv.h>
+#endif
+
+#if USE(WININET)
+#include <winsock2.h>
+#include <windows.h>
+#endif
+
+#if USE(CURL)
+#include <curl/curl.h>
+#include "FormDataStreamCurl.h"
+#endif
+
+#if USE(SOUP)
+#include <libsoup/soup.h>
+#endif
+
+#if PLATFORM(QT)
+class QWebFrame;
+class QWebNetworkJob;
+namespace WebCore {
+class QNetworkReplyHandler;
+}
+#endif
+
+#if PLATFORM(MAC)
+#ifdef __OBJC__
+@class NSURLAuthenticationChallenge;
+@class NSURLConnection;
+#else
+class NSURLAuthenticationChallenge;
+class NSURLConnection;
+#endif
+#endif
+
+#if PLATFORM(ANDROID)
+namespace android {
+ class WebCoreResourceLoader;
+}
+#endif
+
+// The allocations and releases in ResourceHandleInternal are
+// Cocoa-exception-free (either simple Foundation classes or
+// WebCoreResourceLoaderImp which avoids doing work in dealloc).
+
+namespace WebCore {
+ class ResourceHandleClient;
+
+ class ResourceHandleInternal : Noncopyable {
+ public:
+ ResourceHandleInternal(ResourceHandle* loader, const ResourceRequest& request, ResourceHandleClient* c, bool defersLoading, bool shouldContentSniff, bool mightDownloadFromHandle)
+ : m_client(c)
+ , m_request(request)
+ , status(0)
+ , m_defersLoading(defersLoading)
+ , m_shouldContentSniff(shouldContentSniff)
+ , m_mightDownloadFromHandle(mightDownloadFromHandle)
+#if USE(CFNETWORK)
+ , m_connection(0)
+#endif
+#if USE(WININET)
+ , m_fileHandle(INVALID_HANDLE_VALUE)
+ , m_fileLoadTimer(loader, &ResourceHandle::fileLoadTimer)
+ , m_resourceHandle(0)
+ , m_secondaryHandle(0)
+ , m_jobId(0)
+ , m_threadId(0)
+ , m_writing(false)
+ , m_formDataString(0)
+ , m_formDataLength(0)
+ , m_bytesRemainingToWrite(0)
+ , m_hasReceivedResponse(false)
+ , m_resend(false)
+#endif
+#if USE(CURL)
+ , m_handle(0)
+ , m_url(0)
+ , m_customHeaders(0)
+ , m_cancelled(false)
+ , m_formDataStream(loader)
+#endif
+#if USE(SOUP)
+ , m_msg(0)
+ , m_cancelled(false)
+ , m_gfile(0)
+ , m_input_stream(0)
+ , m_cancellable(0)
+ , m_buffer(0)
+ , m_bufsize(0)
+ , m_total(0)
+#endif
+#if PLATFORM(QT)
+ , m_job(0)
+ , m_frame(0)
+#endif
+#if PLATFORM(MAC)
+ , m_startWhenScheduled(false)
+ , m_currentMacChallenge(nil)
+#elif USE(CFNETWORK)
+ , m_currentCFChallenge(0)
+#endif
+#if PLATFORM(ANDROID)
+ , m_loader(0)
+#endif
+ , m_failureTimer(loader, &ResourceHandle::fireFailure)
+ {
+ }
+
+ ~ResourceHandleInternal();
+
+ ResourceHandleClient* client() { return m_client; }
+ ResourceHandleClient* m_client;
+
+ ResourceRequest m_request;
+
+ int status;
+
+ bool m_defersLoading;
+ bool m_shouldContentSniff;
+ bool m_mightDownloadFromHandle;
+#if USE(CFNETWORK)
+ RetainPtr<CFURLConnectionRef> m_connection;
+#elif PLATFORM(MAC)
+ RetainPtr<NSURLConnection> m_connection;
+ RetainPtr<WebCoreResourceHandleAsDelegate> m_delegate;
+ RetainPtr<id> m_proxy;
+ bool m_startWhenScheduled;
+#endif
+#if USE(WININET)
+ HANDLE m_fileHandle;
+ Timer<ResourceHandle> m_fileLoadTimer;
+ HINTERNET m_resourceHandle;
+ HINTERNET m_secondaryHandle;
+ unsigned m_jobId;
+ DWORD m_threadId;
+ bool m_writing;
+ char* m_formDataString;
+ int m_formDataLength;
+ int m_bytesRemainingToWrite;
+ String m_postReferrer;
+ bool m_hasReceivedResponse;
+ bool m_resend;
+#endif
+#if USE(CURL)
+ CURL* m_handle;
+ char* m_url;
+ struct curl_slist* m_customHeaders;
+ ResourceResponse m_response;
+ bool m_cancelled;
+
+ FormDataStream m_formDataStream;
+ Vector<char> m_postBytes;
+#endif
+#if USE(SOUP)
+ SoupMessage* m_msg;
+ ResourceResponse m_response;
+ bool m_cancelled;
+ GFile* m_gfile;
+ GInputStream* m_input_stream;
+ GCancellable* m_cancellable;
+ char* m_buffer;
+ gsize m_bufsize, m_total;
+#endif
+#if PLATFORM(QT)
+#if QT_VERSION < 0x040400
+ QWebNetworkJob* m_job;
+#else
+ QNetworkReplyHandler* m_job;
+#endif
+ QWebFrame* m_frame;
+#endif
+#if PLATFORM(MAC)
+ NSURLAuthenticationChallenge *m_currentMacChallenge;
+#endif
+#if USE(CFNETWORK)
+ CFURLAuthChallengeRef m_currentCFChallenge;
+#endif
+#if PLATFORM(ANDROID)
+ android::WebCoreResourceLoader* m_loader;
+#endif
+ AuthenticationChallenge m_currentWebChallenge;
+
+ ResourceHandle::FailureType m_failureType;
+ Timer<ResourceHandle> m_failureTimer;
+ };
+
+} // namespace WebCore
+
+#endif // ResourceHandleInternal_h
diff --git a/WebCore/platform/network/ResourceRequestBase.cpp b/WebCore/platform/network/ResourceRequestBase.cpp
new file mode 100644
index 0000000..4784bbe
--- /dev/null
+++ b/WebCore/platform/network/ResourceRequestBase.cpp
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "ResourceRequestBase.h"
+#include "ResourceRequest.h"
+
+namespace WebCore {
+
+inline const ResourceRequest& ResourceRequestBase::asResourceRequest() const
+{
+ return *static_cast<const ResourceRequest*>(this);
+}
+
+bool ResourceRequestBase::isEmpty() const
+{
+ updateResourceRequest();
+
+ return m_url.isEmpty();
+}
+
+bool ResourceRequestBase::isNull() const
+{
+ updateResourceRequest();
+
+ return m_url.isNull();
+}
+
+const KURL& ResourceRequestBase::url() const
+{
+ updateResourceRequest();
+
+ return m_url;
+}
+
+void ResourceRequestBase::setURL(const KURL& url)
+{
+ updateResourceRequest();
+
+ m_url = url;
+
+ m_platformRequestUpdated = false;
+}
+
+ResourceRequestCachePolicy ResourceRequestBase::cachePolicy() const
+{
+ updateResourceRequest();
+
+ return m_cachePolicy;
+}
+
+void ResourceRequestBase::setCachePolicy(ResourceRequestCachePolicy cachePolicy)
+{
+ updateResourceRequest();
+
+ m_cachePolicy = cachePolicy;
+
+ m_platformRequestUpdated = false;
+}
+
+double ResourceRequestBase::timeoutInterval() const
+{
+ updateResourceRequest();
+
+ return m_timeoutInterval;
+}
+
+void ResourceRequestBase::setTimeoutInterval(double timeoutInterval)
+{
+ updateResourceRequest();
+
+ m_timeoutInterval = timeoutInterval;
+
+ m_platformRequestUpdated = false;
+}
+
+const KURL& ResourceRequestBase::mainDocumentURL() const
+{
+ updateResourceRequest();
+
+ return m_mainDocumentURL;
+}
+
+void ResourceRequestBase::setMainDocumentURL(const KURL& mainDocumentURL)
+{
+ updateResourceRequest();
+
+ m_mainDocumentURL = mainDocumentURL;
+
+ m_platformRequestUpdated = false;
+}
+
+const String& ResourceRequestBase::httpMethod() const
+{
+ updateResourceRequest();
+
+ return m_httpMethod;
+}
+
+void ResourceRequestBase::setHTTPMethod(const String& httpMethod)
+{
+ updateResourceRequest();
+
+ m_httpMethod = httpMethod;
+
+ m_platformRequestUpdated = false;
+}
+
+const HTTPHeaderMap& ResourceRequestBase::httpHeaderFields() const
+{
+ updateResourceRequest();
+
+ return m_httpHeaderFields;
+}
+
+String ResourceRequestBase::httpHeaderField(const String& name) const
+{
+ updateResourceRequest();
+
+ return m_httpHeaderFields.get(name);
+}
+
+void ResourceRequestBase::setHTTPHeaderField(const String& name, const String& value)
+{
+ updateResourceRequest();
+
+ m_httpHeaderFields.set(name, value);
+
+ m_platformRequestUpdated = false;
+}
+
+FormData* ResourceRequestBase::httpBody() const
+{
+ updateResourceRequest();
+
+ return m_httpBody.get();
+}
+
+void ResourceRequestBase::setHTTPBody(PassRefPtr<FormData> httpBody)
+{
+ updateResourceRequest();
+
+ m_httpBody = httpBody;
+
+ m_platformRequestUpdated = false;
+}
+
+bool ResourceRequestBase::allowHTTPCookies() const
+{
+ updateResourceRequest();
+
+ return m_allowHTTPCookies;
+}
+
+void ResourceRequestBase::setAllowHTTPCookies(bool allowHTTPCookies)
+{
+ updateResourceRequest();
+
+ m_allowHTTPCookies = allowHTTPCookies;
+
+ m_platformRequestUpdated = false;
+}
+
+void ResourceRequestBase::addHTTPHeaderField(const String& name, const String& value)
+{
+ updateResourceRequest();
+ pair<HTTPHeaderMap::iterator, bool> result = m_httpHeaderFields.add(name, value);
+ if (!result.second)
+ result.first->second += "," + value;
+}
+
+void ResourceRequestBase::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
+{
+ HTTPHeaderMap::const_iterator end = headerFields.end();
+ for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it)
+ addHTTPHeaderField(it->first, it->second);
+}
+
+bool equalIgnoringHeaderFields(const ResourceRequestBase& a, const ResourceRequestBase& b)
+{
+ if (a.url() != b.url())
+ return false;
+
+ if (a.cachePolicy() != b.cachePolicy())
+ return false;
+
+ if (a.timeoutInterval() != b.timeoutInterval())
+ return false;
+
+ if (a.mainDocumentURL() != b.mainDocumentURL())
+ return false;
+
+ if (a.httpMethod() != b.httpMethod())
+ return false;
+
+ if (a.allowHTTPCookies() != b.allowHTTPCookies())
+ return false;
+
+ FormData* formDataA = a.httpBody();
+ FormData* formDataB = b.httpBody();
+
+ if (!formDataA)
+ return !formDataB;
+ if (!formDataB)
+ return !formDataA;
+
+ if (*formDataA != *formDataB)
+ return false;
+
+ return true;
+}
+
+bool operator==(const ResourceRequestBase& a, const ResourceRequestBase& b)
+{
+ if (!equalIgnoringHeaderFields(a, b))
+ return false;
+
+ if (a.httpHeaderFields() != b.httpHeaderFields())
+ return false;
+
+ return true;
+}
+
+bool ResourceRequestBase::isConditional() const
+{
+ return (m_httpHeaderFields.contains("If-Match") ||
+ m_httpHeaderFields.contains("If-Modified-Since") ||
+ m_httpHeaderFields.contains("If-None-Match") ||
+ m_httpHeaderFields.contains("If-Range") ||
+ m_httpHeaderFields.contains("If-Unmodified-Since"));
+}
+
+void ResourceRequestBase::updatePlatformRequest() const
+{
+ if (m_platformRequestUpdated)
+ return;
+
+ const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest();
+ m_platformRequestUpdated = true;
+}
+
+void ResourceRequestBase::updateResourceRequest() const
+{
+ if (m_resourceRequestUpdated)
+ return;
+
+ const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceRequest();
+ m_resourceRequestUpdated = true;
+}
+
+}
diff --git a/WebCore/platform/network/ResourceRequestBase.h b/WebCore/platform/network/ResourceRequestBase.h
new file mode 100644
index 0000000..32a3384
--- /dev/null
+++ b/WebCore/platform/network/ResourceRequestBase.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceRequestBase_h
+#define ResourceRequestBase_h
+
+#include "FormData.h"
+#include "KURL.h"
+#include "HTTPHeaderMap.h"
+
+namespace WebCore {
+
+ enum ResourceRequestCachePolicy {
+ UseProtocolCachePolicy, // normal load
+ ReloadIgnoringCacheData, // reload
+ ReturnCacheDataElseLoad, // back/forward or encoding change - allow stale data
+ ReturnCacheDataDontLoad, // results of a post - allow stale data and only use cache
+ };
+
+ const int unspecifiedTimeoutInterval = INT_MAX;
+
+ class ResourceRequest;
+
+ // Do not use this type directly. Use ResourceRequest instead.
+ class ResourceRequestBase {
+ public:
+ bool isNull() const;
+ bool isEmpty() const;
+
+ const KURL& url() const;
+ void setURL(const KURL& url);
+
+ ResourceRequestCachePolicy cachePolicy() const;
+ void setCachePolicy(ResourceRequestCachePolicy cachePolicy);
+
+ double timeoutInterval() const;
+ void setTimeoutInterval(double timeoutInterval);
+
+ const KURL& mainDocumentURL() const;
+ void setMainDocumentURL(const KURL& mainDocumentURL);
+
+ const String& httpMethod() const;
+ void setHTTPMethod(const String& httpMethod);
+
+ const HTTPHeaderMap& httpHeaderFields() const;
+ String httpHeaderField(const String& name) const;
+ void setHTTPHeaderField(const String& name, const String& value);
+ void addHTTPHeaderField(const String& name, const String& value);
+ void addHTTPHeaderFields(const HTTPHeaderMap& headerFields);
+
+ String httpContentType() const { return httpHeaderField("Content-Type"); }
+ void setHTTPContentType(const String& httpContentType) { setHTTPHeaderField("Content-Type", httpContentType); }
+
+ String httpReferrer() const { return httpHeaderField("Referer"); }
+ void setHTTPReferrer(const String& httpReferrer) { setHTTPHeaderField("Referer", httpReferrer); }
+ void clearHTTPReferrer() { m_httpHeaderFields.remove("Referer"); }
+
+ String httpOrigin() const { return httpHeaderField("Origin"); }
+ void setHTTPOrigin(const String& httpOrigin) { setHTTPHeaderField("Origin", httpOrigin); }
+ void clearHTTPOrigin() { m_httpHeaderFields.remove("Origin"); }
+
+ String httpUserAgent() const { return httpHeaderField("User-Agent"); }
+ void setHTTPUserAgent(const String& httpUserAgent) { setHTTPHeaderField("User-Agent", httpUserAgent); }
+
+ String httpAccept() const { return httpHeaderField("Accept"); }
+ void setHTTPAccept(const String& httpAccept) { setHTTPHeaderField("Accept", httpAccept); }
+
+ FormData* httpBody() const;
+ void setHTTPBody(PassRefPtr<FormData> httpBody);
+
+ bool allowHTTPCookies() const;
+ void setAllowHTTPCookies(bool allowHTTPCookies);
+
+ bool isConditional() const;
+
+ protected:
+ // Used when ResourceRequest is initialized from a platform representation of the request
+ ResourceRequestBase()
+ : m_resourceRequestUpdated(false)
+ , m_platformRequestUpdated(true)
+ {
+ }
+
+ ResourceRequestBase(const KURL& url, ResourceRequestCachePolicy policy)
+ : m_url(url)
+ , m_cachePolicy(policy)
+ , m_timeoutInterval(unspecifiedTimeoutInterval)
+ , m_httpMethod("GET")
+ , m_allowHTTPCookies(true)
+ , m_resourceRequestUpdated(true)
+ , m_platformRequestUpdated(false)
+ {
+ }
+
+ void updatePlatformRequest() const;
+ void updateResourceRequest() const;
+
+ KURL m_url;
+
+ ResourceRequestCachePolicy m_cachePolicy;
+ double m_timeoutInterval;
+ KURL m_mainDocumentURL;
+ String m_httpMethod;
+ HTTPHeaderMap m_httpHeaderFields;
+ RefPtr<FormData> m_httpBody;
+ bool m_allowHTTPCookies;
+ mutable bool m_resourceRequestUpdated;
+ mutable bool m_platformRequestUpdated;
+
+ private:
+ const ResourceRequest& asResourceRequest() const;
+ };
+
+ bool equalIgnoringHeaderFields(const ResourceRequestBase&, const ResourceRequestBase&);
+
+ bool operator==(const ResourceRequestBase&, const ResourceRequestBase&);
+ inline bool operator!=(ResourceRequestBase& a, const ResourceRequestBase& b) { return !(a == b); }
+
+} // namespace WebCore
+
+#endif // ResourceRequestBase_h
diff --git a/WebCore/platform/network/ResourceResponseBase.cpp b/WebCore/platform/network/ResourceResponseBase.cpp
new file mode 100644
index 0000000..a9ddc30
--- /dev/null
+++ b/WebCore/platform/network/ResourceResponseBase.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "ResourceResponseBase.h"
+#include "ResourceResponse.h"
+
+namespace WebCore {
+
+bool ResourceResponseBase::isHTTP() const
+{
+ lazyInit();
+
+ String protocol = m_url.protocol();
+
+ return equalIgnoringCase(protocol, "http") || equalIgnoringCase(protocol, "https");
+}
+
+const KURL& ResourceResponseBase::url() const
+{
+ lazyInit();
+
+ return m_url;
+}
+
+void ResourceResponseBase::setUrl(const KURL& url)
+{
+ lazyInit();
+ m_isNull = false;
+
+ m_url = url;
+}
+
+const String& ResourceResponseBase::mimeType() const
+{
+ lazyInit();
+
+ return m_mimeType;
+}
+
+void ResourceResponseBase::setMimeType(const String& mimeType)
+{
+ lazyInit();
+ m_isNull = false;
+
+ m_mimeType = mimeType;
+}
+
+long long ResourceResponseBase::expectedContentLength() const
+{
+ lazyInit();
+
+ return m_expectedContentLength;
+}
+
+void ResourceResponseBase::setExpectedContentLength(long long expectedContentLength)
+{
+ lazyInit();
+ m_isNull = false;
+
+ m_expectedContentLength = expectedContentLength;
+}
+
+const String& ResourceResponseBase::textEncodingName() const
+{
+ lazyInit();
+
+ return m_textEncodingName;
+}
+
+void ResourceResponseBase::setTextEncodingName(const String& encodingName)
+{
+ lazyInit();
+ m_isNull = false;
+
+ m_textEncodingName = encodingName;
+}
+
+// FIXME should compute this on the fly
+const String& ResourceResponseBase::suggestedFilename() const
+{
+ lazyInit();
+
+ return m_suggestedFilename;
+}
+
+void ResourceResponseBase::setSuggestedFilename(const String& suggestedName)
+{
+ lazyInit();
+ m_isNull = false;
+
+ m_suggestedFilename = suggestedName;
+}
+
+int ResourceResponseBase::httpStatusCode() const
+{
+ lazyInit();
+
+ return m_httpStatusCode;
+}
+
+void ResourceResponseBase::setHTTPStatusCode(int statusCode)
+{
+ lazyInit();
+
+ m_httpStatusCode = statusCode;
+}
+
+const String& ResourceResponseBase::httpStatusText() const
+{
+ lazyInit();
+
+ return m_httpStatusText;
+}
+
+void ResourceResponseBase::setHTTPStatusText(const String& statusText)
+{
+ lazyInit();
+
+ m_httpStatusText = statusText;
+}
+
+String ResourceResponseBase::httpHeaderField(const String& name) const
+{
+ lazyInit();
+
+ return m_httpHeaderFields.get(name);
+}
+
+void ResourceResponseBase::setHTTPHeaderField(const String& name, const String& value)
+{
+ lazyInit();
+
+ m_httpHeaderFields.set(name, value);
+}
+
+const HTTPHeaderMap& ResourceResponseBase::httpHeaderFields() const
+{
+ lazyInit();
+
+ return m_httpHeaderFields;
+}
+
+bool ResourceResponseBase::isAttachment() const
+{
+ lazyInit();
+
+ String value = m_httpHeaderFields.get("Content-Disposition");
+ int loc = value.find(';');
+ if (loc != -1)
+ value = value.left(loc);
+ value = value.stripWhiteSpace();
+ return equalIgnoringCase(value, "attachment");
+}
+
+void ResourceResponseBase::setExpirationDate(time_t expirationDate)
+{
+ lazyInit();
+
+ m_expirationDate = expirationDate;
+}
+
+time_t ResourceResponseBase::expirationDate() const
+{
+ lazyInit();
+
+ return m_expirationDate;
+}
+
+void ResourceResponseBase::setLastModifiedDate(time_t lastModifiedDate)
+{
+ lazyInit();
+
+ m_lastModifiedDate = lastModifiedDate;
+}
+
+time_t ResourceResponseBase::lastModifiedDate() const
+{
+ lazyInit();
+
+ return m_lastModifiedDate;
+}
+
+void ResourceResponseBase::lazyInit() const
+{
+ const_cast<ResourceResponse*>(static_cast<const ResourceResponse*>(this))->platformLazyInit();
+}
+
+bool ResourceResponseBase::compare(const ResourceResponse& a, const ResourceResponse& b)
+{
+ if (a.isNull() != b.isNull())
+ return false;
+ if (a.url() != b.url())
+ return false;
+ if (a.mimeType() != b.mimeType())
+ return false;
+ if (a.expectedContentLength() != b.expectedContentLength())
+ return false;
+ if (a.textEncodingName() != b.textEncodingName())
+ return false;
+ if (a.suggestedFilename() != b.suggestedFilename())
+ return false;
+ if (a.httpStatusCode() != b.httpStatusCode())
+ return false;
+ if (a.httpStatusText() != b.httpStatusText())
+ return false;
+ if (a.httpHeaderFields() != b.httpHeaderFields())
+ return false;
+ if (a.expirationDate() != b.expirationDate())
+ return false;
+ return ResourceResponse::platformCompare(a, b);
+}
+
+}
diff --git a/WebCore/platform/network/ResourceResponseBase.h b/WebCore/platform/network/ResourceResponseBase.h
new file mode 100644
index 0000000..06b0499
--- /dev/null
+++ b/WebCore/platform/network/ResourceResponseBase.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceResponseBase_h
+#define ResourceResponseBase_h
+
+#include "HTTPHeaderMap.h"
+#include "KURL.h"
+
+namespace WebCore {
+
+class ResourceResponse;
+
+// Do not use this class directly, use the class ResponseResponse instead
+class ResourceResponseBase {
+ public:
+
+ bool isNull() const { return m_isNull; }
+ bool isHTTP() const;
+
+ const KURL& url() const;
+ void setUrl(const KURL& url);
+
+ const String& mimeType() const;
+ void setMimeType(const String& mimeType);
+
+ long long expectedContentLength() const;
+ void setExpectedContentLength(long long expectedContentLength);
+
+ const String& textEncodingName() const;
+ void setTextEncodingName(const String& name);
+
+ // FIXME should compute this on the fly
+ const String& suggestedFilename() const;
+ void setSuggestedFilename(const String&);
+
+ int httpStatusCode() const;
+ void setHTTPStatusCode(int);
+
+ const String& httpStatusText() const;
+ void setHTTPStatusText(const String&);
+
+ String httpHeaderField(const String& name) const;
+ void setHTTPHeaderField(const String& name, const String& value);
+ const HTTPHeaderMap& httpHeaderFields() const;
+
+ bool isMultipart() const { return mimeType() == "multipart/x-mixed-replace"; }
+
+ bool isAttachment() const;
+
+ void setExpirationDate(time_t);
+ time_t expirationDate() const;
+
+ void setLastModifiedDate(time_t);
+ time_t lastModifiedDate() const;
+
+ static bool compare(const ResourceResponse& a, const ResourceResponse& b);
+
+ protected:
+ ResourceResponseBase()
+ : m_expectedContentLength(0)
+ , m_httpStatusCode(0)
+ , m_expirationDate(0)
+ , m_lastModifiedDate(0)
+ , m_isNull(true)
+ {
+ }
+
+ ResourceResponseBase(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename)
+ : m_url(url)
+ , m_mimeType(mimeType)
+ , m_expectedContentLength(expectedLength)
+ , m_textEncodingName(textEncodingName)
+ , m_suggestedFilename(filename)
+ , m_httpStatusCode(0)
+ , m_expirationDate(0)
+ , m_lastModifiedDate(0)
+ , m_isNull(false)
+ {
+ }
+
+ void lazyInit() const;
+
+ // The ResourceResponse subclass may "shadow" this method to lazily initialize platform specific fields
+ void platformLazyInit() {}
+
+ // The ResourceResponse subclass may "shadow" this method to compare platform specific fields
+ static bool platformCompare(const ResourceResponse& a, const ResourceResponse& b) { return true; }
+
+ KURL m_url;
+ String m_mimeType;
+ long long m_expectedContentLength;
+ String m_textEncodingName;
+ String m_suggestedFilename;
+ int m_httpStatusCode;
+ String m_httpStatusText;
+ HTTPHeaderMap m_httpHeaderFields;
+ time_t m_expirationDate;
+ time_t m_lastModifiedDate;
+ bool m_isNull;
+
+};
+
+inline bool operator==(const ResourceResponse& a, const ResourceResponse& b) { return ResourceResponseBase::compare(a, b); }
+inline bool operator!=(const ResourceResponse& a, const ResourceResponse& b) { return !(a == b); }
+
+} // namespace WebCore
+
+#endif // ResourceResponseBase_h
diff --git a/WebCore/platform/network/android/AuthenticationChallenge.h b/WebCore/platform/network/android/AuthenticationChallenge.h
new file mode 100644
index 0000000..971bf97
--- /dev/null
+++ b/WebCore/platform/network/android/AuthenticationChallenge.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef AuthenticationChallenge_h
+#define AuthenticationChallenge_h
+
+#include "AuthenticationChallengeBase.h"
+#include "ResourceHandle.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class ResourceHandle;
+
+class AuthenticationChallenge : public AuthenticationChallengeBase {
+public:
+ AuthenticationChallenge()
+ {
+ }
+
+ AuthenticationChallenge(const ProtectionSpace& protectionSpace, const Credential& proposedCredential, unsigned previousFailureCount, const ResourceResponse& response, const ResourceError& error)
+ : AuthenticationChallengeBase(protectionSpace, proposedCredential, previousFailureCount, response, error)
+ {
+ }
+
+ ResourceHandle* sourceHandle() const { return m_sourceHandle.get(); }
+
+ RefPtr<ResourceHandle> m_sourceHandle;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/network/android/Cookie.cpp b/WebCore/platform/network/android/Cookie.cpp
new file mode 100644
index 0000000..0b7aa45
--- /dev/null
+++ b/WebCore/platform/network/android/Cookie.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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.
+ */
+#define LOG_TAG "Cookies"
+
+#include "config.h"
+#include "JavaSharedClient.h"
+#include "CookieClient.h"
+
+using namespace android;
+
+namespace WebCore {
+
+ class Document;
+
+ void setCookies(Document* , const KURL& url, const KURL& policyBaseURL, const String& value)
+ {
+ if (JavaSharedClient::GetCookieClient())
+ JavaSharedClient::GetCookieClient()->setCookies(url, policyBaseURL, value);
+ }
+
+ String cookies(const Document* , const KURL& url)
+ {
+ if (JavaSharedClient::GetCookieClient())
+ return JavaSharedClient::GetCookieClient()->cookies(url);
+ return String();
+ }
+
+ bool cookiesEnabled(const Document* )
+ {
+ if (JavaSharedClient::GetCookieClient())
+ return JavaSharedClient::GetCookieClient()->cookiesEnabled();
+ return false;
+ }
+
+}
+
diff --git a/WebCore/platform/network/android/CookieClient.h b/WebCore/platform/network/android/CookieClient.h
new file mode 100644
index 0000000..4b6ffef
--- /dev/null
+++ b/WebCore/platform/network/android/CookieClient.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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.
+ */
+
+#ifndef COOKIE_CLIENT_H
+#define COOKIE_CLIENT_H
+
+#include "KURL.h"
+#include "PlatformString.h"
+
+using namespace WebCore;
+
+namespace android {
+
+ class CookieClient
+ {
+ public:
+ virtual ~CookieClient() {}
+ virtual void setCookies(const KURL& url, const KURL& docURL, const String& value) = 0;
+ virtual String cookies(const KURL& url) = 0;
+ virtual bool cookiesEnabled() = 0;
+ };
+
+}
+#endif
+
diff --git a/WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp b/WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp
new file mode 100644
index 0000000..3e49fff
--- /dev/null
+++ b/WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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"
+#include "NetworkStateNotifier.h"
+
+namespace WebCore {
+
+void NetworkStateNotifier::networkStateChange(bool online)
+{
+ if (m_isOnLine == online)
+ return;
+
+ m_isOnLine = online;
+
+ if (m_networkStateChangedFunction)
+ m_networkStateChangedFunction();
+}
+
+}
diff --git a/WebCore/platform/network/android/ResourceError.h b/WebCore/platform/network/android/ResourceError.h
new file mode 100644
index 0000000..12a6323
--- /dev/null
+++ b/WebCore/platform/network/android/ResourceError.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceError_h
+#define ResourceError_h
+
+#include "ResourceErrorBase.h"
+
+namespace WebCore {
+
+class ResourceError : public ResourceErrorBase
+{
+public:
+ ResourceError()
+ {
+ }
+
+ ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription)
+ : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription)
+ {
+ }
+};
+
+}
+
+#endif // ResourceError_h_
diff --git a/WebCore/platform/network/android/ResourceHandleAndroid.cpp b/WebCore/platform/network/android/ResourceHandleAndroid.cpp
new file mode 100644
index 0000000..4d9199a
--- /dev/null
+++ b/WebCore/platform/network/android/ResourceHandleAndroid.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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.
+ */
+#define LOG_TAG "WebCore"
+
+#include "config.h"
+#include "ResourceHandle.h"
+
+#include "DocLoader.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameLoaderClientAndroid.h"
+#include "NotImplemented.h"
+#include "ResourceHandleClient.h"
+#include "ResourceHandleInternal.h"
+#include "WebCoreFrameBridge.h"
+#include "WebCoreResourceLoader.h"
+#include "CString.h"
+
+using namespace android;
+
+namespace WebCore {
+
+ResourceHandleInternal::~ResourceHandleInternal()
+{
+ Release(m_loader);
+}
+
+ResourceHandle::~ResourceHandle()
+{
+}
+
+bool ResourceHandle::start(Frame* frame)
+{
+ WebCoreResourceLoader* loader;
+ bool highPriority = true;
+ CachedResource* r = d->m_request.getCachedResource();
+ if (r) {
+ CachedResource::Type t = r->type();
+ highPriority = !(t == CachedResource::ImageResource ||
+ t == CachedResource::FontResource);
+ }
+ FrameLoaderClientAndroid* client = static_cast<FrameLoaderClientAndroid*> (frame->loader()->client());
+ loader = client->webFrame()->startLoadingResource(this, d->m_request, highPriority, false);
+
+ if (loader) {
+ Release(d->m_loader);
+ d->m_loader = loader;
+ }
+
+ return loader != NULL;
+}
+
+void ResourceHandle::cancel()
+{
+ if (d->m_loader)
+ d->m_loader->cancel();
+}
+
+PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
+{
+ return 0;
+}
+
+bool ResourceHandle::supportsBufferedData()
+{
+ // We don't support buffering data on the native side.
+ return false;
+}
+
+void ResourceHandle::setDefersLoading(bool defers)
+{
+ notImplemented();
+}
+
+/*
+* This static method is called to check to see if a POST response is in
+* the cache. The JNI call through to the HTTP cache stored on the Java
+* side may be slow, but is only used during a navigation to
+* a POST response.
+*/
+bool ResourceHandle::willLoadFromCache(ResourceRequest& request)
+{
+ // set the cache policy correctly, copied from
+ // network/mac/ResourceHandleMac.mm
+ request.setCachePolicy(ReturnCacheDataDontLoad);
+ return WebCoreResourceLoader::willLoadFromCache(request.url());
+}
+
+bool ResourceHandle::loadsBlocked()
+{
+ // FIXME, need to check whether connection pipe is blocked.
+ // return false for now
+ return false;
+}
+
+// Class to handle synchronized loading of resources.
+class SyncLoader : public ResourceHandleClient {
+public:
+ SyncLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data) {
+ m_error = &error;
+ m_response = &response;
+ m_data = &data;
+ }
+ ~SyncLoader() {}
+
+ virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse& response) {
+ *m_response = response;
+ }
+
+ virtual void didReceiveData(ResourceHandle*, const char* data, int len, int lengthReceived) {
+ m_data->append(data, len);
+ }
+
+ virtual void didFail(ResourceHandle*, const ResourceError& error) {
+ *m_error = error;
+ }
+
+private:
+ ResourceError* m_error;
+ ResourceResponse* m_response;
+ Vector<char>* m_data;
+};
+
+void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request,
+ ResourceError& error, ResourceResponse& response, Vector<char>& data,
+ Frame* frame)
+{
+ SyncLoader s(error, response, data);
+ ResourceHandle h(request, &s, false, false, false);
+ // This blocks until the load is finished.
+ FrameLoaderClientAndroid* client = static_cast<FrameLoaderClientAndroid*> (frame->loader()->client());
+ client->webFrame()->startLoadingResource(&h, request, true, true);
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/android/ResourceRequest.h b/WebCore/platform/network/android/ResourceRequest.h
new file mode 100644
index 0000000..bc12600
--- /dev/null
+++ b/WebCore/platform/network/android/ResourceRequest.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceRequest_h
+#define ResourceRequest_h
+
+#include "CachedResource.h"
+#include "ResourceRequestBase.h"
+
+namespace WebCore {
+
+ struct ResourceRequest : ResourceRequestBase {
+
+ ResourceRequest(const String& url)
+ : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ , m_cachedResource(0)
+#ifdef ANDROID_USER_GESTURE
+ , m_wasUserGesture(true)
+#endif
+ {
+ }
+
+ ResourceRequest(const KURL& url)
+ : ResourceRequestBase(url, UseProtocolCachePolicy)
+ , m_cachedResource(0)
+#ifdef ANDROID_USER_GESTURE
+ , m_wasUserGesture(true)
+#endif
+ {
+ }
+
+ ResourceRequest(const KURL& url, const String& referrer, ResourceRequestCachePolicy policy = UseProtocolCachePolicy)
+ : ResourceRequestBase(url, policy)
+ , m_cachedResource(0)
+#ifdef ANDROID_USER_GESTURE
+ , m_wasUserGesture(true)
+#endif
+ {
+ setHTTPReferrer(referrer);
+ }
+
+ ResourceRequest()
+ : ResourceRequestBase(KURL(), UseProtocolCachePolicy)
+ , m_cachedResource(0)
+#ifdef ANDROID_USER_GESTURE
+ , m_wasUserGesture(true)
+#endif
+ {
+ }
+
+ void doUpdatePlatformRequest() {}
+ void doUpdateResourceRequest() {}
+ void setCachedResource(CachedResource* r) { m_cachedResource = r; }
+ CachedResource* getCachedResource() const { return m_cachedResource; }
+#ifdef ANDROID_USER_GESTURE
+ void setUserGesture(bool userGesture) { m_wasUserGesture = userGesture; }
+ bool userGesture() const { return m_wasUserGesture; }
+#endif
+ private:
+ friend class ResourceRequestBase;
+ CachedResource* m_cachedResource;
+#ifdef ANDROID_USER_GESTURE
+ bool m_wasUserGesture;
+#endif
+ };
+
+} // namespace WebCore
+
+#endif // ResourceRequest_h
diff --git a/WebCore/platform/network/android/ResourceResponse.h b/WebCore/platform/network/android/ResourceResponse.h
new file mode 100644
index 0000000..5249636
--- /dev/null
+++ b/WebCore/platform/network/android/ResourceResponse.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceResponse_h
+#define ResourceResponse_h
+
+#include "ResourceResponseBase.h"
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+class ResourceResponse : public ResourceResponseBase {
+public:
+ ResourceResponse()
+ : ResourceResponseBase()
+ {
+ }
+
+ ResourceResponse(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename)
+ : ResourceResponseBase(url, mimeType, expectedLength, textEncodingName, filename)
+ {
+ }
+
+private:
+ friend class ResourceResponseBase;
+
+ void doUpdateResourceResponse()
+ {
+ notImplemented();
+ }
+
+};
+
+} // namespace WebCore
+
+#endif // ResourceResponse_h
diff --git a/WebCore/platform/network/cf/AuthenticationCF.cpp b/WebCore/platform/network/cf/AuthenticationCF.cpp
new file mode 100644
index 0000000..bb05a39
--- /dev/null
+++ b/WebCore/platform/network/cf/AuthenticationCF.cpp
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "AuthenticationCF.h"
+
+#include "AuthenticationChallenge.h"
+#include "Credential.h"
+#include "ProtectionSpace.h"
+#include "ResourceHandle.h"
+
+#include <CFNetwork/CFURLAuthChallengePriv.h>
+#include <CFNetwork/CFURLCredentialPriv.h>
+#include <CFNetwork/CFURLProtectionSpacePriv.h>
+
+namespace WebCore {
+
+AuthenticationChallenge::AuthenticationChallenge(const ProtectionSpace& protectionSpace,
+ const Credential& proposedCredential,
+ unsigned previousFailureCount,
+ const ResourceResponse& response,
+ const ResourceError& error)
+ : AuthenticationChallengeBase(protectionSpace,
+ proposedCredential,
+ previousFailureCount,
+ response,
+ error)
+{
+}
+
+AuthenticationChallenge::AuthenticationChallenge(CFURLAuthChallengeRef cfChallenge,
+ ResourceHandle* sourceHandle)
+ : AuthenticationChallengeBase(core(CFURLAuthChallengeGetProtectionSpace(cfChallenge)),
+ core(CFURLAuthChallengeGetProposedCredential(cfChallenge)),
+ CFURLAuthChallengeGetPreviousFailureCount(cfChallenge),
+ (CFURLResponseRef)CFURLAuthChallengeGetFailureResponse(cfChallenge),
+ CFURLAuthChallengeGetError(cfChallenge))
+ , m_sourceHandle(sourceHandle)
+ , m_cfChallenge(cfChallenge)
+{
+}
+
+bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b)
+{
+ if (a.sourceHandle() != b.sourceHandle())
+ return false;
+
+ if (a.cfURLAuthChallengeRef() != b.cfURLAuthChallengeRef())
+ return false;
+
+ return true;
+}
+
+CFURLAuthChallengeRef createCF(const AuthenticationChallenge& coreChallenge)
+{
+ CFURLProtectionSpaceRef protectionSpace = createCF(coreChallenge.protectionSpace());
+ CFURLCredentialRef credential = createCF(coreChallenge.proposedCredential());
+
+ CFURLAuthChallengeRef result = CFURLAuthChallengeCreate(0, protectionSpace, credential,
+ coreChallenge.previousFailureCount(),
+ coreChallenge.failureResponse().cfURLResponse(),
+ coreChallenge.error());
+ CFRelease(protectionSpace);
+ CFRelease(credential);
+ return result;
+}
+
+CFURLCredentialRef createCF(const Credential& coreCredential)
+{
+ CFURLCredentialPersistence persistence = kCFURLCredentialPersistenceNone;
+ switch (coreCredential.persistence()) {
+ case CredentialPersistenceNone:
+ break;
+ case CredentialPersistenceForSession:
+ persistence = kCFURLCredentialPersistenceForSession;
+ break;
+ case CredentialPersistencePermanent:
+ persistence = kCFURLCredentialPersistencePermanent;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ CFStringRef user = coreCredential.user().createCFString();
+ CFStringRef password = coreCredential.password().createCFString();
+ CFURLCredentialRef result = CFURLCredentialCreate(0, user, password, 0, persistence);
+ CFRelease(user);
+ CFRelease(password);
+
+ return result;
+}
+
+CFURLProtectionSpaceRef createCF(const ProtectionSpace& coreSpace)
+{
+ CFURLProtectionSpaceServerType serverType = kCFURLProtectionSpaceServerHTTP;
+ switch (coreSpace.serverType()) {
+ case ProtectionSpaceServerHTTP:
+ serverType = kCFURLProtectionSpaceServerHTTP;
+ break;
+ case ProtectionSpaceServerHTTPS:
+ serverType = kCFURLProtectionSpaceServerHTTPS;
+ break;
+ case ProtectionSpaceServerFTP:
+ serverType = kCFURLProtectionSpaceServerFTP;
+ break;
+ case ProtectionSpaceServerFTPS:
+ serverType = kCFURLProtectionSpaceServerFTPS;
+ break;
+ case ProtectionSpaceProxyHTTP:
+ serverType = kCFURLProtectionSpaceProxyHTTP;
+ break;
+ case ProtectionSpaceProxyHTTPS:
+ serverType = kCFURLProtectionSpaceProxyHTTPS;
+ break;
+ case ProtectionSpaceProxyFTP:
+ serverType = kCFURLProtectionSpaceProxyFTP;
+ break;
+ case ProtectionSpaceProxySOCKS:
+ serverType = kCFURLProtectionSpaceProxySOCKS;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ CFURLProtectionSpaceAuthenticationScheme scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault;
+ switch (coreSpace.authenticationScheme()) {
+ case ProtectionSpaceAuthenticationSchemeDefault:
+ scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault;
+ break;
+ case ProtectionSpaceAuthenticationSchemeHTTPBasic:
+ scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic;
+ break;
+ case ProtectionSpaceAuthenticationSchemeHTTPDigest:
+ scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest;
+ break;
+ case ProtectionSpaceAuthenticationSchemeHTMLForm:
+ scheme = kCFURLProtectionSpaceAuthenticationSchemeHTMLForm;
+ break;
+ case ProtectionSpaceAuthenticationSchemeNTLM:
+ scheme = kCFURLProtectionSpaceAuthenticationSchemeNTLM;
+ break;
+ case ProtectionSpaceAuthenticationSchemeNegotiate:
+ scheme = kCFURLProtectionSpaceAuthenticationSchemeNegotiate;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ CFStringRef host = coreSpace.host().createCFString();
+ CFStringRef realm = coreSpace.realm().createCFString();
+ CFURLProtectionSpaceRef result = CFURLProtectionSpaceCreate(0, host, coreSpace.port(), serverType, realm, scheme);
+ CFRelease(host);
+ CFRelease(realm);
+
+ return result;
+}
+
+Credential core(CFURLCredentialRef cfCredential)
+{
+ if (!cfCredential)
+ return Credential();
+
+ CredentialPersistence persistence = CredentialPersistenceNone;
+ switch (CFURLCredentialGetPersistence(cfCredential)) {
+ case kCFURLCredentialPersistenceNone:
+ break;
+ case kCFURLCredentialPersistenceForSession:
+ persistence = CredentialPersistenceForSession;
+ break;
+ case kCFURLCredentialPersistencePermanent:
+ persistence = CredentialPersistencePermanent;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return Credential(CFURLCredentialGetUsername(cfCredential), CFURLCredentialCopyPassword(cfCredential), persistence);
+}
+
+ProtectionSpace core(CFURLProtectionSpaceRef cfSpace)
+{
+ ProtectionSpaceServerType serverType = ProtectionSpaceServerHTTP;
+
+ switch (CFURLProtectionSpaceGetServerType(cfSpace)) {
+ case kCFURLProtectionSpaceServerHTTP:
+ break;
+ case kCFURLProtectionSpaceServerHTTPS:
+ serverType = ProtectionSpaceServerHTTPS;
+ break;
+ case kCFURLProtectionSpaceServerFTP:
+ serverType = ProtectionSpaceServerFTP;
+ break;
+ case kCFURLProtectionSpaceServerFTPS:
+ serverType = ProtectionSpaceServerFTPS;
+ break;
+ case kCFURLProtectionSpaceProxyHTTP:
+ serverType = ProtectionSpaceProxyHTTP;
+ break;
+ case kCFURLProtectionSpaceProxyHTTPS:
+ serverType = ProtectionSpaceProxyHTTPS;
+ break;
+ case kCFURLProtectionSpaceProxyFTP:
+ serverType = ProtectionSpaceProxyFTP;
+ break;
+ case kCFURLProtectionSpaceProxySOCKS:
+ serverType = ProtectionSpaceProxySOCKS;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ ProtectionSpaceAuthenticationScheme scheme = ProtectionSpaceAuthenticationSchemeDefault;
+
+ switch (CFURLProtectionSpaceGetAuthenticationScheme(cfSpace)) {
+ case kCFURLProtectionSpaceAuthenticationSchemeDefault:
+ scheme = ProtectionSpaceAuthenticationSchemeDefault;
+ break;
+ case kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic:
+ scheme = ProtectionSpaceAuthenticationSchemeHTTPBasic;
+ break;
+ case kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest:
+ scheme = ProtectionSpaceAuthenticationSchemeHTTPDigest;
+ break;
+ case kCFURLProtectionSpaceAuthenticationSchemeHTMLForm:
+ scheme = ProtectionSpaceAuthenticationSchemeHTMLForm;
+ break;
+ case kCFURLProtectionSpaceAuthenticationSchemeNTLM:
+ scheme = ProtectionSpaceAuthenticationSchemeNTLM;
+ break;
+ case kCFURLProtectionSpaceAuthenticationSchemeNegotiate:
+ scheme = ProtectionSpaceAuthenticationSchemeNegotiate;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return ProtectionSpace(CFURLProtectionSpaceGetHost(cfSpace),
+ CFURLProtectionSpaceGetPort(cfSpace),
+ serverType,
+ CFURLProtectionSpaceGetRealm(cfSpace),
+ scheme);
+}
+
+};
diff --git a/WebCore/platform/network/cf/AuthenticationCF.h b/WebCore/platform/network/cf/AuthenticationCF.h
new file mode 100644
index 0000000..681e71f
--- /dev/null
+++ b/WebCore/platform/network/cf/AuthenticationCF.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef AuthenticationCF_h
+#define AuthenticationCF_h
+
+typedef struct _CFURLAuthChallenge* CFURLAuthChallengeRef;
+typedef struct _CFURLCredential* CFURLCredentialRef;
+typedef struct _CFURLProtectionSpace* CFURLProtectionSpaceRef;
+
+namespace WebCore {
+
+class AuthenticationChallenge;
+class Credential;
+class ProtectionSpace;
+
+CFURLAuthChallengeRef createCF(const AuthenticationChallenge&);
+CFURLCredentialRef createCF(const Credential&);
+CFURLProtectionSpaceRef createCF(const ProtectionSpace&);
+
+Credential core(CFURLCredentialRef);
+ProtectionSpace core(CFURLProtectionSpaceRef);
+
+
+}
+
+#endif
diff --git a/WebCore/platform/network/cf/AuthenticationChallenge.h b/WebCore/platform/network/cf/AuthenticationChallenge.h
new file mode 100644
index 0000000..9697d7e
--- /dev/null
+++ b/WebCore/platform/network/cf/AuthenticationChallenge.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef AuthenticationChallenge_h
+#define AuthenticationChallenge_h
+
+#include "AuthenticationChallengeBase.h"
+#include "ResourceHandle.h"
+#include <wtf/RefPtr.h>
+
+typedef struct _CFURLAuthChallenge* CFURLAuthChallengeRef;
+
+namespace WebCore {
+
+class ResourceHandle;
+
+class AuthenticationChallenge : public AuthenticationChallengeBase {
+public:
+ AuthenticationChallenge() {}
+ AuthenticationChallenge(const ProtectionSpace& protectionSpace, const Credential& proposedCredential, unsigned previousFailureCount, const ResourceResponse& response, const ResourceError& error);
+ AuthenticationChallenge(CFURLAuthChallengeRef, ResourceHandle* sourceHandle);
+
+ ResourceHandle* sourceHandle() const { return m_sourceHandle.get(); }
+ CFURLAuthChallengeRef cfURLAuthChallengeRef() const { return m_cfChallenge.get(); }
+
+private:
+ friend class AuthenticationChallengeBase;
+ static bool platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b);
+
+ RefPtr<ResourceHandle> m_sourceHandle;
+ RetainPtr<CFURLAuthChallengeRef> m_cfChallenge;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/network/cf/DNSCFNet.cpp b/WebCore/platform/network/cf/DNSCFNet.cpp
new file mode 100644
index 0000000..e571494
--- /dev/null
+++ b/WebCore/platform/network/cf/DNSCFNet.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 Collin Jackson <collinj@webkit.org>
+ *
+ * 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 AND ITS CONTRIBUTORS "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 COMPUTER, 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"
+#include "DNS.h"
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+void prefetchDNS(const String& hostname)
+{
+ notImplemented();
+}
+
+}
diff --git a/WebCore/platform/network/cf/FormDataStreamCFNet.cpp b/WebCore/platform/network/cf/FormDataStreamCFNet.cpp
new file mode 100644
index 0000000..71fbfe7
--- /dev/null
+++ b/WebCore/platform/network/cf/FormDataStreamCFNet.cpp
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+/* originally written by Becky Willrich, additional code by Darin Adler */
+
+#include "config.h"
+#include "FormDataStreamCFNet.h"
+
+#include "CString.h"
+#include "FileSystem.h"
+#include "FormData.h"
+#include <CFNetwork/CFURLRequestPriv.h>
+#include <CoreFoundation/CFStreamAbstract.h>
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
+#include <sys/types.h>
+#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+#include <wtf/RetainPtr.h>
+
+#define USE_V1_CFSTREAM_CALLBACKS
+#ifdef USE_V1_CFSTREAM_CALLBACKS
+typedef CFReadStreamCallBacksV1 WCReadStreamCallBacks;
+#else
+typedef CFReadStreamCallBacks WCReadStreamCallBacks;
+#endif
+
+namespace WebCore {
+
+static HashMap<CFReadStreamRef, RefPtr<FormData> >& getStreamFormDatas()
+{
+ static HashMap<CFReadStreamRef, RefPtr<FormData> > streamFormDatas;
+ return streamFormDatas;
+}
+
+static void formEventCallback(CFReadStreamRef stream, CFStreamEventType type, void* context);
+
+struct FormStreamFields {
+ CFMutableSetRef scheduledRunLoopPairs;
+ Vector<FormDataElement> remainingElements; // in reverse order
+ CFReadStreamRef currentStream;
+ char* currentData;
+ CFReadStreamRef formStream;
+};
+
+struct SchedulePair {
+ CFRunLoopRef runLoop;
+ CFStringRef mode;
+};
+
+static const void* pairRetain(CFAllocatorRef alloc, const void* value)
+{
+ const SchedulePair* pair = static_cast<const SchedulePair*>(value);
+
+ SchedulePair* result = new SchedulePair;
+ CFRetain(pair->runLoop);
+ result->runLoop = pair->runLoop;
+ result->mode = CFStringCreateCopy(alloc, pair->mode);
+ return result;
+}
+
+static void pairRelease(CFAllocatorRef alloc, const void* value)
+{
+ const SchedulePair* pair = static_cast<const SchedulePair*>(value);
+
+ CFRelease(pair->runLoop);
+ CFRelease(pair->mode);
+ delete pair;
+}
+
+static Boolean pairEqual(const void* a, const void* b)
+{
+ const SchedulePair* pairA = static_cast<const SchedulePair*>(a);
+ const SchedulePair* pairB = static_cast<const SchedulePair*>(b);
+
+ return pairA->runLoop == pairB->runLoop && CFEqual(pairA->mode, pairB->mode);
+}
+
+static CFHashCode pairHash(const void* value)
+{
+ const SchedulePair* pair = static_cast<const SchedulePair*>(value);
+
+ return (CFHashCode)pair->runLoop ^ CFHash(pair->mode);
+}
+
+static void closeCurrentStream(FormStreamFields *form)
+{
+ if (form->currentStream) {
+ CFReadStreamClose(form->currentStream);
+ CFReadStreamSetClient(form->currentStream, kCFStreamEventNone, NULL, NULL);
+ CFRelease(form->currentStream);
+ form->currentStream = NULL;
+ }
+ if (form->currentData) {
+ fastFree(form->currentData);
+ form->currentData = 0;
+ }
+}
+
+static void scheduleWithPair(const void* value, void* context)
+{
+ const SchedulePair* pair = static_cast<const SchedulePair*>(value);
+ CFReadStreamRef stream = (CFReadStreamRef)context;
+
+ CFReadStreamScheduleWithRunLoop(stream, pair->runLoop, pair->mode);
+}
+
+static void advanceCurrentStream(FormStreamFields *form)
+{
+ closeCurrentStream(form);
+
+ if (form->remainingElements.isEmpty())
+ return;
+
+ // Create the new stream.
+ FormDataElement& nextInput = form->remainingElements.last();
+ if (nextInput.m_type == FormDataElement::data) {
+ size_t size = nextInput.m_data.size();
+ char* data = nextInput.m_data.releaseBuffer();
+ form->currentStream = CFReadStreamCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data), size, kCFAllocatorNull);
+ form->currentData = data;
+ } else {
+ CFStringRef filename = nextInput.m_filename.createCFString();
+#if PLATFORM(WIN)
+ CFURLRef fileURL = CFURLCreateWithFileSystemPath(0, filename, kCFURLWindowsPathStyle, FALSE);
+#else
+ CFURLRef fileURL = CFURLCreateWithFileSystemPath(0, filename, kCFURLPOSIXPathStyle, FALSE);
+#endif
+ CFRelease(filename);
+ form->currentStream = CFReadStreamCreateWithFile(0, fileURL);
+ CFRelease(fileURL);
+ }
+ form->remainingElements.removeLast();
+
+ // Set up the callback.
+ CFStreamClientContext context = { 0, form, NULL, NULL, NULL };
+ CFReadStreamSetClient(form->currentStream, kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
+ formEventCallback, &context);
+
+ // Schedule with the current set of run loops.
+ CFSetApplyFunction(form->scheduledRunLoopPairs, scheduleWithPair, form->currentStream);
+}
+
+static void openNextStream(FormStreamFields* form)
+{
+ // Skip over any streams we can't open.
+ // For some purposes we might want to return an error, but the current CFURLConnection
+ // can't really do anything useful with an error at this point, so this is better.
+ advanceCurrentStream(form);
+ while (form->currentStream && !CFReadStreamOpen(form->currentStream))
+ advanceCurrentStream(form);
+}
+
+static void* formCreate(CFReadStreamRef stream, void* context)
+{
+ FormData* formData = static_cast<FormData*>(context);
+
+ CFSetCallBacks runLoopAndModeCallBacks = { 0, pairRetain, pairRelease, NULL, pairEqual, pairHash };
+
+ FormStreamFields* newInfo = new FormStreamFields;
+ newInfo->scheduledRunLoopPairs = CFSetCreateMutable(0, 0, &runLoopAndModeCallBacks);
+ newInfo->currentStream = NULL;
+ newInfo->currentData = 0;
+ newInfo->formStream = stream; // Don't retain. That would create a reference cycle.
+
+ // Append in reverse order since we remove elements from the end.
+ size_t size = formData->elements().size();
+ newInfo->remainingElements.reserveCapacity(size);
+ for (size_t i = 0; i < size; ++i)
+ newInfo->remainingElements.append(formData->elements()[size - i - 1]);
+
+ getStreamFormDatas().set(stream, adoptRef(formData));
+
+ return newInfo;
+}
+
+static void formFinalize(CFReadStreamRef stream, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ getStreamFormDatas().remove(stream);
+
+ closeCurrentStream(form);
+ CFRelease(form->scheduledRunLoopPairs);
+ delete form;
+}
+
+static Boolean formOpen(CFReadStreamRef stream, CFStreamError* error, Boolean* openComplete, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ openNextStream(form);
+
+ *openComplete = TRUE;
+ error->error = 0;
+ return TRUE;
+}
+
+static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLength, CFStreamError* error, Boolean* atEOF, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ while (form->currentStream) {
+ CFIndex bytesRead = CFReadStreamRead(form->currentStream, buffer, bufferLength);
+ if (bytesRead < 0) {
+ *error = CFReadStreamGetError(form->currentStream);
+ return -1;
+ }
+ if (bytesRead > 0) {
+ error->error = 0;
+ *atEOF = FALSE;
+ return bytesRead;
+ }
+ openNextStream(form);
+ }
+
+ error->error = 0;
+ *atEOF = TRUE;
+ return 0;
+}
+
+static Boolean formCanRead(CFReadStreamRef stream, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ while (form->currentStream && CFReadStreamGetStatus(form->currentStream) == kCFStreamStatusAtEnd) {
+ openNextStream(form);
+ }
+ if (!form->currentStream) {
+ CFReadStreamSignalEvent(stream, kCFStreamEventEndEncountered, 0);
+ return FALSE;
+ }
+ return CFReadStreamHasBytesAvailable(form->currentStream);
+}
+
+static void formClose(CFReadStreamRef stream, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ closeCurrentStream(form);
+}
+
+static void formSchedule(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ if (form->currentStream)
+ CFReadStreamScheduleWithRunLoop(form->currentStream, runLoop, runLoopMode);
+ SchedulePair pair = { runLoop, runLoopMode };
+ CFSetAddValue(form->scheduledRunLoopPairs, &pair);
+}
+
+static void formUnschedule(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ if (form->currentStream)
+ CFReadStreamUnscheduleFromRunLoop(form->currentStream, runLoop, runLoopMode);
+ SchedulePair pair = { runLoop, runLoopMode };
+ CFSetRemoveValue(form->scheduledRunLoopPairs, &pair);
+}
+
+static void formEventCallback(CFReadStreamRef stream, CFStreamEventType type, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ switch (type) {
+ case kCFStreamEventHasBytesAvailable:
+ CFReadStreamSignalEvent(form->formStream, kCFStreamEventHasBytesAvailable, 0);
+ break;
+ case kCFStreamEventErrorOccurred: {
+ CFStreamError readStreamError = CFReadStreamGetError(stream);
+ CFReadStreamSignalEvent(form->formStream, kCFStreamEventErrorOccurred, &readStreamError);
+ break;
+ }
+ case kCFStreamEventEndEncountered:
+ openNextStream(form);
+ if (!form->currentStream)
+ CFReadStreamSignalEvent(form->formStream, kCFStreamEventEndEncountered, 0);
+ break;
+ case kCFStreamEventNone:
+ LOG_ERROR("unexpected kCFStreamEventNone");
+ break;
+ case kCFStreamEventOpenCompleted:
+ LOG_ERROR("unexpected kCFStreamEventOpenCompleted");
+ break;
+ case kCFStreamEventCanAcceptBytes:
+ LOG_ERROR("unexpected kCFStreamEventCanAcceptBytes");
+ break;
+ }
+}
+
+void setHTTPBody(CFMutableURLRequestRef request, PassRefPtr<FormData> formData)
+{
+ if (!formData) {
+ if (wkCanAccessCFURLRequestHTTPBodyParts())
+ wkCFURLRequestSetHTTPRequestBodyParts(request, 0);
+ return;
+ }
+
+ size_t count = formData->elements().size();
+
+ if (count == 0)
+ return;
+
+ // Handle the common special case of one piece of form data, with no files.
+ if (count == 1) {
+ const FormDataElement& element = formData->elements()[0];
+ if (element.m_type == FormDataElement::data) {
+ CFDataRef data = CFDataCreate(0, reinterpret_cast<const UInt8 *>(element.m_data.data()), element.m_data.size());
+ CFURLRequestSetHTTPRequestBody(request, data);
+ CFRelease(data);
+ return;
+ }
+ }
+
+ if (wkCanAccessCFURLRequestHTTPBodyParts()) {
+ RetainPtr<CFMutableArrayRef> array(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks));
+
+ for (size_t i = 0; i < count; ++i) {
+ const FormDataElement& element = formData->elements()[i];
+ if (element.m_type == FormDataElement::data) {
+ RetainPtr<CFDataRef> data(AdoptCF, CFDataCreate(0, reinterpret_cast<const UInt8*>(element.m_data.data()), element.m_data.size()));
+ CFArrayAppendValue(array.get(), data.get());
+ } else {
+ RetainPtr<CFStringRef> filename(AdoptCF, element.m_filename.createCFString());
+ CFArrayAppendValue(array.get(), filename.get());
+ }
+ }
+
+ wkCFURLRequestSetHTTPRequestBodyParts(request, array.get());
+ return;
+ }
+
+ // Precompute the content length so CFURLConnection doesn't use chunked mode.
+ bool haveLength = true;
+ long long length = 0;
+ for (size_t i = 0; i < count; ++i) {
+ const FormDataElement& element = formData->elements()[i];
+ if (element.m_type == FormDataElement::data)
+ length += element.m_data.size();
+ else {
+ long long size;
+ if (getFileSize(element.m_filename, size))
+ length += size;
+ else
+ haveLength = false;
+ }
+ }
+
+ if (haveLength) {
+ CFStringRef lengthStr = CFStringCreateWithFormat(0, 0, CFSTR("%lld"), length);
+ CFURLRequestSetHTTPHeaderFieldValue(request, CFSTR("Content-Length"), lengthStr);
+ CFRelease(lengthStr);
+ }
+
+ static WCReadStreamCallBacks formDataStreamCallbacks =
+ { 1, formCreate, formFinalize, 0, formOpen, 0, formRead, 0, formCanRead, formClose, 0, 0, 0, formSchedule, formUnschedule };
+
+ CFReadStreamRef stream = CFReadStreamCreate(0, (CFReadStreamCallBacks *)&formDataStreamCallbacks, formData.releaseRef());
+ CFURLRequestSetHTTPRequestBodyStream(request, stream);
+ CFRelease(stream);
+}
+
+PassRefPtr<FormData> httpBodyFromRequest(CFURLRequestRef request)
+{
+ if (RetainPtr<CFDataRef> bodyData = CFURLRequestCopyHTTPRequestBody(request))
+ return FormData::create(CFDataGetBytePtr(bodyData.get()), CFDataGetLength(bodyData.get()));
+
+ if (wkCanAccessCFURLRequestHTTPBodyParts()) {
+ if (RetainPtr<CFArrayRef> bodyParts = wkCFURLRequestCopyHTTPRequestBodyParts(request)) {
+ RefPtr<FormData> formData = FormData::create();
+
+ CFIndex count = CFArrayGetCount(bodyParts.get());
+ for (CFIndex i = 0; i < count; i++) {
+ CFTypeRef bodyPart = CFArrayGetValueAtIndex(bodyParts.get(), i);
+ CFTypeID typeID = CFGetTypeID(bodyPart);
+ if (typeID == CFStringGetTypeID()) {
+ String filename = (CFStringRef)bodyPart;
+ formData->appendFile(filename);
+ } else if (typeID == CFDataGetTypeID()) {
+ CFDataRef data = (CFDataRef)bodyPart;
+ formData->appendData(CFDataGetBytePtr(data), CFDataGetLength(data));
+ } else
+ ASSERT_NOT_REACHED();
+ }
+ return formData.release();
+ }
+ } else {
+ if (RetainPtr<CFReadStreamRef> bodyStream = CFURLRequestCopyHTTPRequestBodyStream(request))
+ return getStreamFormDatas().get(bodyStream.get());
+ }
+
+ // FIXME: what to do about arbitrary body streams?
+ return 0;
+}
+
+}
diff --git a/WebCore/platform/network/cf/FormDataStreamCFNet.h b/WebCore/platform/network/cf/FormDataStreamCFNet.h
new file mode 100644
index 0000000..254a2cd
--- /dev/null
+++ b/WebCore/platform/network/cf/FormDataStreamCFNet.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#ifndef FormDataStreamCFNet_h_
+#define FormDataStreamCFNet_h_
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <wtf/Forward.h>
+
+typedef struct _CFURLRequest* CFMutableURLRequestRef;
+typedef const struct _CFURLRequest* CFURLRequestRef;
+
+namespace WebCore {
+ class FormData;
+ void setHTTPBody(CFMutableURLRequestRef, PassRefPtr<FormData>);
+ PassRefPtr<FormData> httpBodyFromRequest(CFURLRequestRef);
+}
+
+#endif FormDataStreamCFNet_h_
diff --git a/WebCore/platform/network/cf/ResourceError.h b/WebCore/platform/network/cf/ResourceError.h
new file mode 100644
index 0000000..10f1208
--- /dev/null
+++ b/WebCore/platform/network/cf/ResourceError.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceError_h
+#define ResourceError_h
+
+#include "ResourceErrorBase.h"
+
+#include <wtf/RetainPtr.h>
+#include <CoreFoundation/CFStream.h>
+
+namespace WebCore {
+
+class ResourceError : public ResourceErrorBase {
+public:
+ ResourceError()
+ : m_dataIsUpToDate(true)
+ {
+ }
+
+ ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription)
+ : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription)
+ , m_dataIsUpToDate(true)
+ {
+ }
+
+ ResourceError(CFStreamError error);
+
+ ResourceError(CFErrorRef error)
+ : m_dataIsUpToDate(false)
+ , m_platformError(error)
+ {
+ m_isNull = !error;
+ }
+
+ operator CFErrorRef() const;
+ operator CFStreamError() const;
+
+private:
+ friend class ResourceErrorBase;
+
+ void platformLazyInit();
+ static bool platformCompare(const ResourceError& a, const ResourceError& b);
+
+ bool m_dataIsUpToDate;
+ mutable RetainPtr<CFErrorRef> m_platformError;
+};
+
+} // namespace WebCore
+
+#endif // ResourceError_h_
diff --git a/WebCore/platform/network/cf/ResourceErrorCF.cpp b/WebCore/platform/network/cf/ResourceErrorCF.cpp
new file mode 100644
index 0000000..8e82cd5
--- /dev/null
+++ b/WebCore/platform/network/cf/ResourceErrorCF.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "KURL.h"
+#include "ResourceError.h"
+
+#if USE(CFNETWORK)
+
+// FIXME: Once <rdar://problem/5050881> is fixed in open source we
+// can remove this extern "C"
+extern "C" {
+#include <CFNetwork/CFNetworkErrors.h>
+}
+
+#include <CoreFoundation/CFError.h>
+#include <WTF/RetainPtr.h>
+
+namespace WebCore {
+
+const CFStringRef failingURLStringKey = CFSTR("NSErrorFailingURLStringKey");
+const CFStringRef failingURLKey = CFSTR("NSErrorFailingURLKey");
+
+// FIXME: Once <rdar://problem/5050841> is fixed we can remove this constructor.
+ResourceError::ResourceError(CFStreamError error)
+ : m_dataIsUpToDate(true)
+{
+ m_isNull = false;
+ m_errorCode = error.error;
+
+ switch(error.domain) {
+ case kCFStreamErrorDomainCustom:
+ m_domain ="NSCustomErrorDomain";
+ break;
+ case kCFStreamErrorDomainPOSIX:
+ m_domain = "NSPOSIXErrorDomain";
+ break;
+ case kCFStreamErrorDomainMacOSStatus:
+ m_domain = "NSOSStatusErrorDomain";
+ break;
+ }
+}
+
+void ResourceError::platformLazyInit()
+{
+ if (m_dataIsUpToDate)
+ return;
+
+ if (!m_platformError)
+ return;
+
+ CFStringRef domain = CFErrorGetDomain(m_platformError.get());
+ if (domain == kCFErrorDomainMach || domain == kCFErrorDomainCocoa)
+ m_domain ="NSCustomErrorDomain";
+ else if (domain == kCFErrorDomainCFNetwork)
+ m_domain = "CFURLErrorDomain";
+ else if (domain == kCFErrorDomainPOSIX)
+ m_domain = "NSPOSIXErrorDomain";
+ else if (domain == kCFErrorDomainOSStatus)
+ m_domain = "NSOSStatusErrorDomain";
+ else if (domain == kCFErrorDomainWinSock)
+ m_domain = "kCFErrorDomainWinSock";
+
+ m_errorCode = CFErrorGetCode(m_platformError.get());
+
+ RetainPtr<CFDictionaryRef> userInfo(AdoptCF, CFErrorCopyUserInfo(m_platformError.get()));
+ if (userInfo.get()) {
+ CFStringRef failingURLString = (CFStringRef) CFDictionaryGetValue(userInfo.get(), failingURLStringKey);
+ if (failingURLString)
+ m_failingURL = String(failingURLString);
+ else {
+ CFURLRef failingURL = (CFURLRef) CFDictionaryGetValue(userInfo.get(), failingURLKey);
+ if (failingURL) {
+ RetainPtr<CFURLRef> absoluteURLRef(AdoptCF, CFURLCopyAbsoluteURL(failingURL));
+ if (absoluteURLRef.get()) {
+ failingURLString = CFURLGetString(absoluteURLRef.get());
+ m_failingURL = String(failingURLString);
+ }
+ }
+ }
+ m_localizedDescription = (CFStringRef) CFDictionaryGetValue(userInfo.get(), kCFErrorLocalizedDescriptionKey);
+ }
+
+ m_dataIsUpToDate = true;
+}
+
+bool ResourceError::platformCompare(const ResourceError& a, const ResourceError& b)
+{
+ return (CFErrorRef)a == (CFErrorRef)b;
+}
+
+ResourceError::operator CFErrorRef() const
+{
+ if (m_isNull) {
+ ASSERT(!m_platformError);
+ return nil;
+ }
+
+ if (!m_platformError) {
+ RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+ if (!m_localizedDescription.isEmpty()) {
+ RetainPtr<CFStringRef> localizedDescriptionString(AdoptCF, m_localizedDescription.createCFString());
+ CFDictionarySetValue(userInfo.get(), kCFErrorLocalizedDescriptionKey, localizedDescriptionString.get());
+ }
+
+ if (!m_failingURL.isEmpty()) {
+ RetainPtr<CFStringRef> failingURLString(AdoptCF, m_failingURL.createCFString());
+ CFDictionarySetValue(userInfo.get(), failingURLStringKey, failingURLString.get());
+ RetainPtr<CFURLRef> url(AdoptCF, KURL(m_failingURL).createCFURL());
+ CFDictionarySetValue(userInfo.get(), failingURLKey, url.get());
+ }
+
+ RetainPtr<CFStringRef> domainString(AdoptCF, m_domain.createCFString());
+ m_platformError.adoptCF(CFErrorCreate(0, domainString.get(), m_errorCode, userInfo.get()));
+ }
+
+ return m_platformError.get();
+}
+
+ResourceError::operator CFStreamError() const
+{
+ lazyInit();
+
+ CFStreamError result;
+ result.error = m_errorCode;
+
+ if (m_domain == "NSCustomErrorDomain")
+ result.domain = kCFStreamErrorDomainCustom;
+ else if (m_domain == "NSPOSIXErrorDomain")
+ result.domain = kCFStreamErrorDomainPOSIX;
+ else if (m_domain == "NSOSStatusErrorDomain")
+ result.domain = kCFStreamErrorDomainMacOSStatus;
+ else
+ ASSERT_NOT_REACHED();
+
+ return result;
+}
+
+} // namespace WebCore
+
+#endif // USE(CFNETWORK)
diff --git a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
new file mode 100644
index 0000000..fa7947f
--- /dev/null
+++ b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+
+#include "ResourceHandle.h"
+#include "ResourceHandleClient.h"
+#include "ResourceHandleInternal.h"
+
+#include "AuthenticationCF.h"
+#include "AuthenticationChallenge.h"
+#include "CookieStorageWin.h"
+#include "CString.h"
+#include "DocLoader.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "Logging.h"
+#include "NotImplemented.h"
+#include "ResourceError.h"
+#include "ResourceResponse.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/Threading.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <process.h> // for _beginthread()
+
+#include <CFNetwork/CFNetwork.h>
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
+
+namespace WebCore {
+
+static HashSet<String>& allowsAnyHTTPSCertificateHosts()
+{
+ static HashSet<String> hosts;
+
+ return hosts;
+}
+
+static HashMap<String, RetainPtr<CFDataRef> >& clientCerts()
+{
+ static HashMap<String, RetainPtr<CFDataRef> > certs;
+ return certs;
+}
+
+CFURLRequestRef willSendRequest(CFURLConnectionRef conn, CFURLRequestRef cfRequest, CFURLResponseRef cfRedirectResponse, const void* clientInfo)
+{
+ ResourceHandle* handle = (ResourceHandle*)clientInfo;
+
+ if (!cfRedirectResponse) {
+ CFRetain(cfRequest);
+ return cfRequest;
+ }
+
+ LOG(Network, "CFNet - willSendRequest(conn=%p, handle=%p) (%s)", conn, handle, handle->request().url().string().utf8().data());
+
+ ResourceRequest request(cfRequest);
+ if (handle->client())
+ handle->client()->willSendRequest(handle, request, cfRedirectResponse);
+
+ cfRequest = request.cfURLRequest();
+
+ CFRetain(cfRequest);
+ return cfRequest;
+}
+
+void didReceiveResponse(CFURLConnectionRef conn, CFURLResponseRef cfResponse, const void* clientInfo)
+{
+ ResourceHandle* handle = (ResourceHandle*)clientInfo;
+
+ LOG(Network, "CFNet - didReceiveResponse(conn=%p, handle=%p) (%s)", conn, handle, handle->request().url().string().utf8().data());
+
+ if (handle->client())
+ handle->client()->didReceiveResponse(handle, cfResponse);
+}
+
+void didReceiveData(CFURLConnectionRef conn, CFDataRef data, CFIndex originalLength, const void* clientInfo)
+{
+ ResourceHandle* handle = (ResourceHandle*)clientInfo;
+ const UInt8* bytes = CFDataGetBytePtr(data);
+ CFIndex length = CFDataGetLength(data);
+
+ LOG(Network, "CFNet - didReceiveData(conn=%p, handle=%p, bytes=%d) (%s)", conn, handle, length, handle->request().url().string().utf8().data());
+
+ if (handle->client())
+ handle->client()->didReceiveData(handle, (const char*)bytes, length, originalLength);
+}
+
+void didFinishLoading(CFURLConnectionRef conn, const void* clientInfo)
+{
+ ResourceHandle* handle = (ResourceHandle*)clientInfo;
+
+ LOG(Network, "CFNet - didFinishLoading(conn=%p, handle=%p) (%s)", conn, handle, handle->request().url().string().utf8().data());
+
+ if (handle->client())
+ handle->client()->didFinishLoading(handle);
+}
+
+void didFail(CFURLConnectionRef conn, CFErrorRef error, const void* clientInfo)
+{
+ ResourceHandle* handle = (ResourceHandle*)clientInfo;
+
+ LOG(Network, "CFNet - didFail(conn=%p, handle=%p, error = %p) (%s)", conn, handle, error, handle->request().url().string().utf8().data());
+
+ if (handle->client())
+ handle->client()->didFail(handle, ResourceError(error));
+}
+
+CFCachedURLResponseRef willCacheResponse(CFURLConnectionRef conn, CFCachedURLResponseRef cachedResponse, const void* clientInfo)
+{
+ ResourceHandle* handle = (ResourceHandle*)clientInfo;
+
+ CacheStoragePolicy policy = static_cast<CacheStoragePolicy>(CFCachedURLResponseGetStoragePolicy(cachedResponse));
+
+ if (handle->client())
+ handle->client()->willCacheResponse(handle, policy);
+
+ if (static_cast<CFURLCacheStoragePolicy>(policy) != CFCachedURLResponseGetStoragePolicy(cachedResponse))
+ cachedResponse = CFCachedURLResponseCreateWithUserInfo(kCFAllocatorDefault,
+ CFCachedURLResponseGetWrappedResponse(cachedResponse),
+ CFCachedURLResponseGetReceiverData(cachedResponse),
+ CFCachedURLResponseGetUserInfo(cachedResponse),
+ static_cast<CFURLCacheStoragePolicy>(policy));
+ CFRetain(cachedResponse);
+
+ return cachedResponse;
+}
+
+void didReceiveChallenge(CFURLConnectionRef conn, CFURLAuthChallengeRef challenge, const void* clientInfo)
+{
+ ResourceHandle* handle = (ResourceHandle*)clientInfo;
+ ASSERT(handle);
+ LOG(Network, "CFNet - didReceiveChallenge(conn=%p, handle=%p (%s)", conn, handle, handle->request().url().string().utf8().data());
+
+ handle->didReceiveAuthenticationChallenge(AuthenticationChallenge(challenge, handle));
+}
+
+void addHeadersFromHashMap(CFMutableURLRequestRef request, const HTTPHeaderMap& requestHeaders)
+{
+ if (!requestHeaders.size())
+ return;
+
+ HTTPHeaderMap::const_iterator end = requestHeaders.end();
+ for (HTTPHeaderMap::const_iterator it = requestHeaders.begin(); it != end; ++it) {
+ CFStringRef key = it->first.createCFString();
+ CFStringRef value = it->second.createCFString();
+ CFURLRequestSetHTTPHeaderFieldValue(request, key, value);
+ CFRelease(key);
+ CFRelease(value);
+ }
+}
+
+ResourceHandleInternal::~ResourceHandleInternal()
+{
+ if (m_connection) {
+ LOG(Network, "CFNet - Cancelling connection %p (%s)", m_connection, m_request.url().string().utf8().data());
+ CFURLConnectionCancel(m_connection.get());
+ }
+}
+
+ResourceHandle::~ResourceHandle()
+{
+ LOG(Network, "CFNet - Destroying job %p (%s)", this, d->m_request.url().string().utf8().data());
+}
+
+CFArrayRef arrayFromFormData(const FormData& d)
+{
+ size_t size = d.elements().size();
+ CFMutableArrayRef a = CFArrayCreateMutable(0, d.elements().size(), &kCFTypeArrayCallBacks);
+ for (size_t i = 0; i < size; ++i) {
+ const FormDataElement& e = d.elements()[i];
+ if (e.m_type == FormDataElement::data) {
+ CFDataRef data = CFDataCreate(0, (const UInt8*)e.m_data.data(), e.m_data.size());
+ CFArrayAppendValue(a, data);
+ CFRelease(data);
+ } else {
+ ASSERT(e.m_type == FormDataElement::encodedFile);
+ CFStringRef filename = e.m_filename.createCFString();
+ CFArrayAppendValue(a, filename);
+ CFRelease(filename);
+ }
+ }
+ return a;
+}
+
+void emptyPerform(void* unused)
+{
+}
+
+static CFRunLoopRef loaderRL = 0;
+void* runLoaderThread(void *unused)
+{
+ loaderRL = CFRunLoopGetCurrent();
+
+ // Must add a source to the run loop to prevent CFRunLoopRun() from exiting
+ CFRunLoopSourceContext ctxt = {0, (void *)1 /*must be non-NULL*/, 0, 0, 0, 0, 0, 0, 0, emptyPerform};
+ CFRunLoopSourceRef bogusSource = CFRunLoopSourceCreate(0, 0, &ctxt);
+ CFRunLoopAddSource(loaderRL, bogusSource,kCFRunLoopDefaultMode);
+
+ CFRunLoopRun();
+
+ return 0;
+}
+
+CFRunLoopRef ResourceHandle::loaderRunLoop()
+{
+ if (!loaderRL) {
+ createThread(runLoaderThread, 0, "CFNetwork::Loader");
+ while (loaderRL == 0) {
+ // FIXME: sleep 10? that can't be right...
+ Sleep(10);
+ }
+ }
+ return loaderRL;
+}
+
+static CFURLRequestRef makeFinalRequest(const ResourceRequest& request, bool shouldContentSniff)
+{
+ CFMutableURLRequestRef newRequest = CFURLRequestCreateMutableCopy(kCFAllocatorDefault, request.cfURLRequest());
+
+ if (!shouldContentSniff)
+ wkSetCFURLRequestShouldContentSniff(newRequest, false);
+
+ RetainPtr<CFMutableDictionaryRef> sslProps;
+
+ if (allowsAnyHTTPSCertificateHosts().contains(request.url().host().lower())) {
+ sslProps.adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ CFDictionaryAddValue(sslProps.get(), kCFStreamSSLAllowsAnyRoot, kCFBooleanTrue);
+ CFDictionaryAddValue(sslProps.get(), kCFStreamSSLAllowsExpiredRoots, kCFBooleanTrue);
+ }
+
+ HashMap<String, RetainPtr<CFDataRef> >::iterator clientCert = clientCerts().find(request.url().host().lower());
+ if (clientCert != clientCerts().end()) {
+ if (!sslProps)
+ sslProps.adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ wkSetClientCertificateInSSLProperties(sslProps.get(), (clientCert->second).get());
+ }
+
+ if (sslProps)
+ CFURLRequestSetSSLProperties(newRequest, sslProps.get());
+
+ if (CFHTTPCookieStorageRef cookieStorage = currentCookieStorage()) {
+ CFURLRequestSetHTTPCookieStorage(newRequest, cookieStorage);
+ CFURLRequestSetHTTPCookieStorageAcceptPolicy(newRequest, CFHTTPCookieStorageGetCookieAcceptPolicy(cookieStorage));
+ }
+
+ return newRequest;
+}
+
+bool ResourceHandle::start(Frame* frame)
+{
+ // If we are no longer attached to a Page, this must be an attempted load from an
+ // onUnload handler, so let's just block it.
+ if (!frame->page())
+ return false;
+
+ RetainPtr<CFURLRequestRef> request(AdoptCF, makeFinalRequest(d->m_request, d->m_shouldContentSniff));
+
+ // CFURLConnection Callback API currently at version 1
+ const int CFURLConnectionClientVersion = 1;
+ CFURLConnectionClient client = {CFURLConnectionClientVersion, this, 0, 0, 0, willSendRequest, didReceiveResponse, didReceiveData, NULL, didFinishLoading, didFail, willCacheResponse, didReceiveChallenge};
+
+ d->m_connection.adoptCF(CFURLConnectionCreate(0, request.get(), &client));
+
+ CFURLConnectionScheduleWithCurrentMessageQueue(d->m_connection.get());
+ CFURLConnectionScheduleDownloadWithRunLoop(d->m_connection.get(), loaderRunLoop(), kCFRunLoopDefaultMode);
+ CFURLConnectionStart(d->m_connection.get());
+
+ LOG(Network, "CFNet - Starting URL %s (handle=%p, conn=%p)", d->m_request.url().string().utf8().data(), this, d->m_connection);
+
+ return true;
+}
+
+void ResourceHandle::cancel()
+{
+ if (d->m_connection) {
+ CFURLConnectionCancel(d->m_connection.get());
+ d->m_connection = 0;
+ }
+}
+
+PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+bool ResourceHandle::supportsBufferedData()
+{
+ return false;
+}
+
+void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge)
+{
+ LOG(Network, "CFNet - didReceiveAuthenticationChallenge()");
+ ASSERT(!d->m_currentCFChallenge);
+ ASSERT(d->m_currentWebChallenge.isNull());
+ // Since CFURLConnection networking relies on keeping a reference to the original CFURLAuthChallengeRef,
+ // we make sure that is actually present
+ ASSERT(challenge.cfURLAuthChallengeRef());
+
+ d->m_currentCFChallenge = challenge.cfURLAuthChallengeRef();
+ d->m_currentWebChallenge = AuthenticationChallenge(d->m_currentCFChallenge, this);
+
+ if (client())
+ client()->didReceiveAuthenticationChallenge(this, d->m_currentWebChallenge);
+}
+
+void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge, const Credential& credential)
+{
+ LOG(Network, "CFNet - receivedCredential()");
+ ASSERT(!challenge.isNull());
+ ASSERT(challenge.cfURLAuthChallengeRef());
+ if (challenge != d->m_currentWebChallenge)
+ return;
+
+ CFURLCredentialRef cfCredential = createCF(credential);
+ CFURLConnectionUseCredential(d->m_connection.get(), cfCredential, challenge.cfURLAuthChallengeRef());
+ CFRelease(cfCredential);
+
+ clearAuthentication();
+}
+
+void ResourceHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& challenge)
+{
+ LOG(Network, "CFNet - receivedRequestToContinueWithoutCredential()");
+ ASSERT(!challenge.isNull());
+ ASSERT(challenge.cfURLAuthChallengeRef());
+ if (challenge != d->m_currentWebChallenge)
+ return;
+
+ CFURLConnectionUseCredential(d->m_connection.get(), 0, challenge.cfURLAuthChallengeRef());
+
+ clearAuthentication();
+}
+
+void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challenge)
+{
+ LOG(Network, "CFNet - receivedCancellation()");
+ if (challenge != d->m_currentWebChallenge)
+ return;
+
+ if (client())
+ client()->receivedCancellation(this, challenge);
+}
+
+CFURLConnectionRef ResourceHandle::connection() const
+{
+ return d->m_connection.get();
+}
+
+CFURLConnectionRef ResourceHandle::releaseConnectionForDownload()
+{
+ LOG(Network, "CFNet - Job %p releasing connection %p for download", this, d->m_connection.get());
+ return d->m_connection.releaseRef();
+}
+
+void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& vector, Frame*)
+{
+ ASSERT(!request.isEmpty());
+ CFURLResponseRef cfResponse = 0;
+ CFErrorRef cfError = 0;
+ RetainPtr<CFURLRequestRef> cfRequest(AdoptCF, makeFinalRequest(request, true));
+
+ CFDataRef data = CFURLConnectionSendSynchronousRequest(cfRequest.get(), &cfResponse, &cfError, request.timeoutInterval());
+
+ if (cfError) {
+ error = cfError;
+ CFRelease(cfError);
+
+ response = ResourceResponse(request.url(), String(), 0, String(), String());
+ response.setHTTPStatusCode(404);
+ } else {
+ response = cfResponse;
+ if (cfResponse)
+ CFRelease(cfResponse);
+ }
+
+ if (data) {
+ ASSERT(vector.isEmpty());
+ vector.append(CFDataGetBytePtr(data), CFDataGetLength(data));
+ CFRelease(data);
+ }
+}
+
+void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host)
+{
+ allowsAnyHTTPSCertificateHosts().add(host.lower());
+}
+
+void ResourceHandle::setClientCertificate(const String& host, CFDataRef cert)
+{
+ clientCerts().set(host.lower(), cert);
+}
+
+void ResourceHandle::setDefersLoading(bool defers)
+{
+ if (!d->m_connection)
+ return;
+
+ if (defers)
+ CFURLConnectionHalt(d->m_connection.get());
+ else
+ CFURLConnectionResume(d->m_connection.get());
+}
+
+bool ResourceHandle::loadsBlocked()
+{
+ return false;
+}
+
+bool ResourceHandle::willLoadFromCache(ResourceRequest&)
+{
+ // Not having this function means that we'll ask the user about re-posting a form
+ // even when we go back to a page that's still in the cache.
+ notImplemented();
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/cf/ResourceRequest.h b/WebCore/platform/network/cf/ResourceRequest.h
new file mode 100644
index 0000000..a4e9749
--- /dev/null
+++ b/WebCore/platform/network/cf/ResourceRequest.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceRequest_h
+#define ResourceRequest_h
+
+#include "ResourceRequestBase.h"
+
+#include <wtf/RetainPtr.h>
+typedef const struct _CFURLRequest* CFURLRequestRef;
+
+namespace WebCore {
+
+ struct ResourceRequest : ResourceRequestBase {
+
+ ResourceRequest(const String& url)
+ : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(const KURL& url)
+ : ResourceRequestBase(url, UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(const KURL& url, const String& referrer, ResourceRequestCachePolicy policy = UseProtocolCachePolicy)
+ : ResourceRequestBase(url, policy)
+ {
+ setHTTPReferrer(referrer);
+ }
+
+ ResourceRequest()
+ : ResourceRequestBase(KURL(), UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(CFURLRequestRef cfRequest)
+ : ResourceRequestBase()
+ , m_cfRequest(cfRequest) { }
+
+ CFURLRequestRef cfURLRequest() const;
+
+ private:
+ friend struct ResourceRequestBase;
+
+ void doUpdatePlatformRequest();
+ void doUpdateResourceRequest();
+
+ RetainPtr<CFURLRequestRef> m_cfRequest;
+ };
+
+} // namespace WebCore
+
+#endif // ResourceRequest_h
diff --git a/WebCore/platform/network/cf/ResourceRequestCFNet.cpp b/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
new file mode 100644
index 0000000..b73df13
--- /dev/null
+++ b/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "ResourceRequestCFNet.h"
+
+#include "FormDataStreamCFNet.h"
+#include "ResourceRequest.h"
+
+#include <CFNetwork/CFURLRequestPriv.h>
+
+namespace WebCore {
+
+CFURLRequestRef ResourceRequest::cfURLRequest() const
+{
+ updatePlatformRequest();
+
+ return m_cfRequest.get();
+}
+
+static inline void addHeadersFromHashMap(CFMutableURLRequestRef request, const HTTPHeaderMap& requestHeaders)
+{
+ if (!requestHeaders.size())
+ return;
+
+ HTTPHeaderMap::const_iterator end = requestHeaders.end();
+ for (HTTPHeaderMap::const_iterator it = requestHeaders.begin(); it != end; ++it) {
+ CFStringRef key = it->first.createCFString();
+ CFStringRef value = it->second.createCFString();
+ CFURLRequestSetHTTPHeaderFieldValue(request, key, value);
+ CFRelease(key);
+ CFRelease(value);
+ }
+}
+
+void ResourceRequest::doUpdatePlatformRequest()
+{
+ CFMutableURLRequestRef cfRequest;
+
+ RetainPtr<CFURLRef> url(AdoptCF, ResourceRequest::url().createCFURL());
+ RetainPtr<CFURLRef> mainDocumentURL(AdoptCF, ResourceRequest::mainDocumentURL().createCFURL());
+ if (m_cfRequest) {
+ cfRequest = CFURLRequestCreateMutableCopy(0, m_cfRequest.get());
+ CFURLRequestSetURL(cfRequest, url.get());
+ CFURLRequestSetMainDocumentURL(cfRequest, mainDocumentURL.get());
+ } else {
+ cfRequest = CFURLRequestCreateMutable(0, url.get(), (CFURLRequestCachePolicy)cachePolicy(), timeoutInterval(), mainDocumentURL.get());
+ }
+
+ RetainPtr<CFStringRef> requestMethod(AdoptCF, httpMethod().createCFString());
+ CFURLRequestSetHTTPRequestMethod(cfRequest, requestMethod.get());
+
+ addHeadersFromHashMap(cfRequest, httpHeaderFields());
+ WebCore::setHTTPBody(cfRequest, httpBody());
+ CFURLRequestSetShouldHandleHTTPCookies(cfRequest, allowHTTPCookies());
+
+ if (m_cfRequest) {
+ RetainPtr<CFHTTPCookieStorageRef> cookieStorage(AdoptCF, CFURLRequestCopyHTTPCookieStorage(m_cfRequest.get()));
+ if (cookieStorage)
+ CFURLRequestSetHTTPCookieStorage(cfRequest, cookieStorage.get());
+ CFURLRequestSetHTTPCookieStorageAcceptPolicy(cfRequest, CFURLRequestGetHTTPCookieStorageAcceptPolicy(m_cfRequest.get()));
+ CFURLRequestSetSSLProperties(cfRequest, CFURLRequestGetSSLProperties(m_cfRequest.get()));
+ }
+
+ m_cfRequest.adoptCF(cfRequest);
+}
+
+void ResourceRequest::doUpdateResourceRequest()
+{
+ m_url = CFURLRequestGetURL(m_cfRequest.get());
+
+ m_cachePolicy = (ResourceRequestCachePolicy)CFURLRequestGetCachePolicy(m_cfRequest.get());
+ m_timeoutInterval = CFURLRequestGetTimeoutInterval(m_cfRequest.get());
+ m_mainDocumentURL = CFURLRequestGetMainDocumentURL(m_cfRequest.get());
+ if (CFStringRef method = CFURLRequestCopyHTTPRequestMethod(m_cfRequest.get())) {
+ m_httpMethod = method;
+ CFRelease(method);
+ }
+ m_allowHTTPCookies = CFURLRequestShouldHandleHTTPCookies(m_cfRequest.get());
+
+ if (CFDictionaryRef headers = CFURLRequestCopyAllHTTPHeaderFields(m_cfRequest.get())) {
+ CFIndex headerCount = CFDictionaryGetCount(headers);
+ Vector<const void*, 128> keys(headerCount);
+ Vector<const void*, 128> values(headerCount);
+ CFDictionaryGetKeysAndValues(headers, keys.data(), values.data());
+ for (int i = 0; i < headerCount; ++i)
+ m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]);
+ CFRelease(headers);
+ }
+
+ m_httpBody = httpBodyFromRequest(m_cfRequest.get());
+}
+
+}
diff --git a/WebCore/platform/network/cf/ResourceRequestCFNet.h b/WebCore/platform/network/cf/ResourceRequestCFNet.h
new file mode 100644
index 0000000..e9ebe76
--- /dev/null
+++ b/WebCore/platform/network/cf/ResourceRequestCFNet.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceRequestCFNet_h
+#define ResourceRequestCFNet_h
+
+typedef const struct _CFURLRequest* CFURLRequestRef;
+
+namespace WebCore {
+
+ class ResourceRequest;
+
+ void getResourceRequest(ResourceRequest&, CFURLRequestRef);
+ CFURLRequestRef cfURLRequest(const ResourceRequest&);
+}
+
+#endif // ResourceRequestCFNet_h
diff --git a/WebCore/platform/network/cf/ResourceResponse.h b/WebCore/platform/network/cf/ResourceResponse.h
new file mode 100644
index 0000000..e14c79e
--- /dev/null
+++ b/WebCore/platform/network/cf/ResourceResponse.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef ResourceResponse_h
+#define ResourceResponse_h
+
+#include "ResourceResponseBase.h"
+#include <wtf/RetainPtr.h>
+
+typedef struct _CFURLResponse* CFURLResponseRef;
+
+namespace WebCore {
+
+class ResourceResponse : public ResourceResponseBase {
+public:
+ ResourceResponse()
+ : m_isUpToDate(true)
+ {
+ }
+
+ ResourceResponse(CFURLResponseRef cfResponse)
+ : m_cfResponse(cfResponse)
+ , m_isUpToDate(false)
+ {
+ m_isNull = !cfResponse;
+ }
+
+ ResourceResponse(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename)
+ : ResourceResponseBase(url, mimeType, expectedLength, textEncodingName, filename)
+ , m_isUpToDate(true)
+ {
+ }
+
+ CFURLResponseRef cfURLResponse() const;
+
+private:
+ friend class ResourceResponseBase;
+
+ void platformLazyInit();
+ static bool platformCompare(const ResourceResponse& a, const ResourceResponse& b);
+
+ RetainPtr<CFURLResponseRef> m_cfResponse;
+ bool m_isUpToDate;
+};
+
+} // namespace WebCore
+
+#endif // ResourceResponse_h
diff --git a/WebCore/platform/network/cf/ResourceResponseCFNet.cpp b/WebCore/platform/network/cf/ResourceResponseCFNet.cpp
new file mode 100644
index 0000000..79efe89
--- /dev/null
+++ b/WebCore/platform/network/cf/ResourceResponseCFNet.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "ResourceResponseCFNet.h"
+
+#include "HTTPParsers.h"
+#include "MIMETypeRegistry.h"
+#include "ResourceResponse.h"
+#include <CFNetwork/CFURLResponsePriv.h>
+#include <wtf/RetainPtr.h>
+
+using namespace std;
+
+// We would like a better value for a maximum time_t,
+// but there is no way to do that in C with any certainty.
+// INT_MAX should work well enough for our purposes.
+#define MAX_TIME_T ((time_t)INT_MAX)
+
+namespace WebCore {
+
+CFURLResponseRef ResourceResponse::cfURLResponse() const
+{
+ return m_cfResponse.get();
+}
+
+static inline bool filenameHasSaneExtension(const String& filename)
+{
+ int dot = filename.find('.');
+
+ // The dot can't be the first or last character in the filename.
+ int length = filename.length();
+ return dot > 0 && dot < length - 1;
+}
+
+static time_t toTimeT(CFAbsoluteTime time)
+{
+ static const double maxTimeAsDouble = std::numeric_limits<time_t>::max();
+ static const double minTimeAsDouble = std::numeric_limits<time_t>::min();
+ return min(max(minTimeAsDouble, time + kCFAbsoluteTimeIntervalSince1970), maxTimeAsDouble);
+}
+
+void ResourceResponse::platformLazyInit()
+{
+ if (m_isUpToDate)
+ return;
+ m_isUpToDate = true;
+
+ if (m_isNull) {
+ ASSERT(!m_cfResponse.get());
+ return;
+ }
+
+ // FIXME: We may need to do MIME type sniffing here (unless that is done in CFURLResponseGetMIMEType).
+
+ m_url = CFURLResponseGetURL(m_cfResponse.get());
+ m_mimeType = CFURLResponseGetMIMEType(m_cfResponse.get());
+ m_expectedContentLength = CFURLResponseGetExpectedContentLength(m_cfResponse.get());
+ m_textEncodingName = CFURLResponseGetTextEncodingName(m_cfResponse.get());
+
+ m_expirationDate = toTimeT(CFURLResponseGetExpirationTime(m_cfResponse.get()));
+ m_lastModifiedDate = toTimeT(CFURLResponseGetLastModifiedDate(m_cfResponse.get()));
+
+ RetainPtr<CFStringRef> suggestedFilename(AdoptCF, CFURLResponseCopySuggestedFilename(m_cfResponse.get()));
+ m_suggestedFilename = suggestedFilename.get();
+
+ CFHTTPMessageRef httpResponse = CFURLResponseGetHTTPResponse(m_cfResponse.get());
+ if (httpResponse) {
+ m_httpStatusCode = CFHTTPMessageGetResponseStatusCode(httpResponse);
+
+ RetainPtr<CFStringRef> statusLine(AdoptCF, CFHTTPMessageCopyResponseStatusLine(httpResponse));
+ String statusText(statusLine.get());
+ int spacePos = statusText.find(" ");
+ if (spacePos != -1)
+ statusText = statusText.substring(spacePos + 1);
+ m_httpStatusText = statusText;
+
+ RetainPtr<CFDictionaryRef> headers(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpResponse));
+ CFIndex headerCount = CFDictionaryGetCount(headers.get());
+ Vector<const void*, 128> keys(headerCount);
+ Vector<const void*, 128> values(headerCount);
+ CFDictionaryGetKeysAndValues(headers.get(), keys.data(), values.data());
+ for (int i = 0; i < headerCount; ++i)
+ m_httpHeaderFields.set((CFStringRef)keys[i], (CFStringRef)values[i]);
+ } else
+ m_httpStatusCode = 0;
+}
+
+bool ResourceResponse::platformCompare(const ResourceResponse& a, const ResourceResponse& b)
+{
+ return CFEqual(a.cfURLResponse(), b.cfURLResponse());
+}
+
+
+}
diff --git a/WebCore/platform/network/cf/ResourceResponseCFNet.h b/WebCore/platform/network/cf/ResourceResponseCFNet.h
new file mode 100644
index 0000000..27144c6
--- /dev/null
+++ b/WebCore/platform/network/cf/ResourceResponseCFNet.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceResponseCFNet_h
+#define ResourceResponseCFNet_h
+
+typedef struct _CFURLResponse* CFURLResponseRef;
+
+namespace WebCore {
+
+ class ResourceResponse;
+
+ void getResourceResponse(ResourceResponse& response, CFURLResponseRef cfResponse);
+
+}
+
+#endif // ResourceResponseCFNet_h
diff --git a/WebCore/platform/network/curl/AuthenticationChallenge.h b/WebCore/platform/network/curl/AuthenticationChallenge.h
new file mode 100644
index 0000000..a64d575
--- /dev/null
+++ b/WebCore/platform/network/curl/AuthenticationChallenge.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef AuthenticationChallenge_h
+#define AuthenticationChallenge_h
+
+#include "AuthenticationChallengeBase.h"
+#include "ResourceHandle.h"
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class ResourceHandle;
+
+class AuthenticationChallenge : public AuthenticationChallengeBase {
+public:
+ AuthenticationChallenge()
+ {
+ }
+
+ AuthenticationChallenge(const ProtectionSpace& protectionSpace, const Credential& proposedCredential, unsigned previousFailureCount, const ResourceResponse& response, const ResourceError& error)
+ : AuthenticationChallengeBase(protectionSpace, proposedCredential, previousFailureCount, response, error)
+ {
+ }
+
+ ResourceHandle* sourceHandle() const { return m_sourceHandle.get(); }
+
+ RefPtr<ResourceHandle> m_sourceHandle;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/network/curl/CookieJarCurl.cpp b/WebCore/platform/network/curl/CookieJarCurl.cpp
new file mode 100644
index 0000000..2f76ebc
--- /dev/null
+++ b/WebCore/platform/network/curl/CookieJarCurl.cpp
@@ -0,0 +1,45 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "CookieJar.h"
+
+#include "KURL.h"
+#include "PlatformString.h"
+#include "StringHash.h"
+
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+static HashMap<String, String> cookieJar;
+
+void setCookies(Document* /*document*/, const KURL& url, const KURL& /*policyURL*/, const String& value)
+{
+ cookieJar.set(url.string(), value);
+}
+
+String cookies(const Document* /*document*/, const KURL& url)
+{
+ return cookieJar.get(url.string());
+}
+
+bool cookiesEnabled(const Document* /*document*/)
+{
+ return true;
+}
+
+}
diff --git a/WebCore/platform/network/curl/DNSCurl.cpp b/WebCore/platform/network/curl/DNSCurl.cpp
new file mode 100644
index 0000000..1ffe1a0
--- /dev/null
+++ b/WebCore/platform/network/curl/DNSCurl.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 AND ITS CONTRIBUTORS "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 COMPUTER, 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"
+#include "DNS.h"
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+void prefetchDNS(const String& hostname)
+{
+ notImplemented();
+}
+
+}
diff --git a/WebCore/platform/network/curl/FormDataStreamCurl.cpp b/WebCore/platform/network/curl/FormDataStreamCurl.cpp
new file mode 100644
index 0000000..639a741
--- /dev/null
+++ b/WebCore/platform/network/curl/FormDataStreamCurl.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
+ * Copyright (C) 2007 Alp Toker <alp.toker@collabora.co.uk>
+ * Copyright (C) 2007 Holger Hans Peter Freyther
+ * Copyright (C) 2008 Collabora Ltd.
+ * All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "FormDataStreamCurl.h"
+
+#include "CString.h"
+#include "FormData.h"
+#include "ResourceRequest.h"
+
+namespace WebCore {
+
+FormDataStream::~FormDataStream()
+{
+ if (m_file)
+ fclose(m_file);
+}
+
+size_t FormDataStream::read(void* ptr, size_t blockSize, size_t numberOfBlocks)
+{
+ // Check for overflow.
+ if (!numberOfBlocks || blockSize > std::numeric_limits<size_t>::max() / numberOfBlocks)
+ return 0;
+
+ Vector<FormDataElement> elements;
+ if (m_resourceHandle->request().httpBody())
+ elements = m_resourceHandle->request().httpBody()->elements();
+
+ if (m_formDataElementIndex >= elements.size())
+ return 0;
+
+ FormDataElement element = elements[m_formDataElementIndex];
+
+ size_t toSend = blockSize * numberOfBlocks;
+ size_t sent;
+
+ if (element.m_type == FormDataElement::encodedFile) {
+ if (!m_file)
+ m_file = fopen(element.m_filename.utf8().data(), "rb");
+
+ if (!m_file) {
+ // FIXME: show a user error?
+#ifndef NDEBUG
+ printf("Failed while trying to open %s for upload\n", element.m_filename.utf8().data());
+#endif
+ return 0;
+ }
+
+ sent = fread(ptr, blockSize, numberOfBlocks, m_file);
+ if (!blockSize && ferror(m_file)) {
+ // FIXME: show a user error?
+#ifndef NDEBUG
+ printf("Failed while trying to read %s for upload\n", element.m_filename.utf8().data());
+#endif
+ return 0;
+ }
+ if (feof(m_file)) {
+ fclose(m_file);
+ m_file = 0;
+ m_formDataElementIndex++;
+ }
+ } else {
+ size_t elementSize = element.m_data.size() - m_formDataElementDataOffset;
+ sent = elementSize > toSend ? toSend : elementSize;
+ memcpy(ptr, element.m_data.data() + m_formDataElementDataOffset, sent);
+ if (elementSize > sent)
+ m_formDataElementDataOffset += sent;
+ else {
+ m_formDataElementDataOffset = 0;
+ m_formDataElementIndex++;
+ }
+ }
+
+ return sent;
+}
+
+bool FormDataStream::hasMoreElements() const
+{
+ Vector<FormDataElement> elements;
+ if (m_resourceHandle->request().httpBody())
+ elements = m_resourceHandle->request().httpBody()->elements();
+
+ return m_formDataElementIndex < elements.size();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/curl/FormDataStreamCurl.h b/WebCore/platform/network/curl/FormDataStreamCurl.h
new file mode 100644
index 0000000..85ca8b0
--- /dev/null
+++ b/WebCore/platform/network/curl/FormDataStreamCurl.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef FormatDataStreamCurl_h
+#define FormatDataStreamCurl_h
+
+#include "config.h"
+
+#include "FileSystem.h"
+#include "ResourceHandle.h"
+#include <stdio.h>
+
+namespace WebCore {
+
+class FormDataStream {
+public:
+ FormDataStream(ResourceHandle* handle)
+ : m_resourceHandle(handle)
+ , m_file(0)
+ , m_formDataElementIndex(0)
+ , m_formDataElementDataOffset(0)
+ {
+ }
+
+ ~FormDataStream();
+
+ size_t read(void* ptr, size_t blockSize, size_t numberOfBlocks);
+ bool hasMoreElements() const;
+
+private:
+ // We can hold a weak reference to our ResourceHandle as it holds a strong reference
+ // to us through its ResourceHandleInternal.
+ ResourceHandle* m_resourceHandle;
+
+ FILE* m_file;
+ size_t m_formDataElementIndex;
+ size_t m_formDataElementDataOffset;
+};
+
+} // namespace WebCore
+
+#endif // FormDataStreamCurl_h
diff --git a/WebCore/platform/network/curl/ResourceError.h b/WebCore/platform/network/curl/ResourceError.h
new file mode 100644
index 0000000..ca8d36b
--- /dev/null
+++ b/WebCore/platform/network/curl/ResourceError.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceError_h
+#define ResourceError_h
+
+#include "ResourceErrorBase.h"
+
+namespace WebCore {
+
+class ResourceError : public ResourceErrorBase
+{
+public:
+ ResourceError()
+ {
+ }
+
+ ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription)
+ : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription)
+ {
+ }
+};
+
+}
+
+#endif // ResourceError_h_
diff --git a/WebCore/platform/network/curl/ResourceHandleCurl.cpp b/WebCore/platform/network/curl/ResourceHandleCurl.cpp
new file mode 100644
index 0000000..bbc31d4
--- /dev/null
+++ b/WebCore/platform/network/curl/ResourceHandleCurl.cpp
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2005, 2006 Michael Emmel mike.emmel@gmail.com
+ * All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "ResourceHandle.h"
+
+#include "DocLoader.h"
+#include "NotImplemented.h"
+#include "ResourceHandleInternal.h"
+#include "ResourceHandleManager.h"
+
+#if PLATFORM(WIN) && PLATFORM(CF)
+#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 lengthReceived);
+ virtual void didFinishLoading(ResourceHandle*);
+ 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*)
+{
+}
+
+void WebCoreSynchronousLoader::didFail(ResourceHandle*, const ResourceError& error)
+{
+ m_error = error;
+}
+
+
+static HashSet<String>& allowsAnyHTTPSCertificateHosts()
+{
+ static HashSet<String> hosts;
+
+ return hosts;
+}
+
+ResourceHandleInternal::~ResourceHandleInternal()
+{
+ free(m_url);
+ if (m_customHeaders)
+ curl_slist_free_all(m_customHeaders);
+}
+
+ResourceHandle::~ResourceHandle()
+{
+ cancel();
+}
+
+bool ResourceHandle::start(Frame* frame)
+{
+ ASSERT(frame);
+ ref();
+ ResourceHandleManager::sharedInstance()->add(this);
+ return true;
+}
+
+void ResourceHandle::cancel()
+{
+ ResourceHandleManager::sharedInstance()->cancel(this);
+}
+
+PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
+{
+ return 0;
+}
+
+bool ResourceHandle::supportsBufferedData()
+{
+ return false;
+}
+
+#if PLATFORM(WIN) && PLATFORM(CF)
+void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host)
+{
+ allowsAnyHTTPSCertificateHosts().add(host.lower());
+}
+#endif
+
+#if PLATFORM(WIN) && PLATFORM(CF)
+// FIXME: The CFDataRef will need to be something else when
+// building without
+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::setDefersLoading(bool defers)
+{
+ if (d->m_defersLoading == defers)
+ return;
+
+#if LIBCURL_VERSION_NUM > 0x071200
+ if (!d->m_handle)
+ d->m_defersLoading = defers;
+ else if (defers) {
+ CURLcode error = curl_easy_pause(d->m_handle, CURLPAUSE_ALL);
+ // If we could not defer the handle, so don't do it.
+ if (error != CURLE_OK)
+ return;
+
+ d->m_defersLoading = defers;
+ } else {
+ // We need to set defersLoading before restarting a connection
+ // or libcURL will call the callbacks in curl_easy_pause and
+ // we would ASSERT.
+ d->m_defersLoading = defers;
+
+ CURLcode error = curl_easy_pause(d->m_handle, CURLPAUSE_CONT);
+ if (error != CURLE_OK)
+ // Restarting the handle has failed so just cancel it.
+ cancel();
+ }
+#else
+ d->m_defersLoading = defers;
+#ifndef NDEBUG
+ printf("Deferred loading is implemented if libcURL version is above 7.18.0");
+#endif
+#endif
+}
+
+bool ResourceHandle::willLoadFromCache(ResourceRequest&)
+{
+ notImplemented();
+ return false;
+}
+
+bool ResourceHandle::loadsBlocked()
+{
+ notImplemented();
+ return false;
+}
+
+void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame*)
+{
+ WebCoreSynchronousLoader syncLoader;
+ ResourceHandle handle(request, &syncLoader, true, false, true);
+
+ ResourceHandleManager* manager = ResourceHandleManager::sharedInstance();
+
+ manager->dispatchSynchronousJob(&handle);
+
+ error = syncLoader.resourceError();
+ data = syncLoader.data();
+ response = syncLoader.resourceResponse();
+}
+
+//stubs needed for windows version
+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();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/curl/ResourceHandleManager.cpp b/WebCore/platform/network/curl/ResourceHandleManager.cpp
new file mode 100644
index 0000000..b022913
--- /dev/null
+++ b/WebCore/platform/network/curl/ResourceHandleManager.cpp
@@ -0,0 +1,700 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2007 Holger Hans Peter Freyther
+ * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2008 Nuanti Ltd.
+ * All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "ResourceHandleManager.h"
+
+#include "Base64.h"
+#include "CString.h"
+#include "HTTPParsers.h"
+#include "MIMETypeRegistry.h"
+#include "NotImplemented.h"
+#include "ResourceError.h"
+#include "ResourceHandle.h"
+#include "ResourceHandleInternal.h"
+#include "TextEncoding.h"
+
+#include <errno.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(GTK)
+ #if GLIB_CHECK_VERSION(2,12,0)
+ #define USE_GLIB_BASE64
+ #endif
+#endif
+
+namespace WebCore {
+
+const int selectTimeoutMS = 5;
+const double pollTimeSeconds = 0.05;
+const int maxRunningJobs = 5;
+
+static const bool ignoreSSLErrors = getenv("WEBKIT_IGNORE_SSL_ERRORS");
+
+ResourceHandleManager::ResourceHandleManager()
+ : m_downloadTimer(this, &ResourceHandleManager::downloadTimerCallback)
+ , m_cookieJarFileName(0)
+ , m_runningJobs(0)
+{
+ 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);
+}
+
+ResourceHandleManager::~ResourceHandleManager()
+{
+ curl_multi_cleanup(m_curlMultiHandle);
+ curl_share_cleanup(m_curlShareHandle);
+ if (m_cookieJarFileName)
+ free(m_cookieJarFileName);
+ curl_global_cleanup();
+}
+
+void ResourceHandleManager::setCookieJarFileName(const char* cookieJarFileName)
+{
+ m_cookieJarFileName = strdup(cookieJarFileName);
+}
+
+ResourceHandleManager* ResourceHandleManager::sharedInstance()
+{
+ static ResourceHandleManager* sharedInstance = 0;
+ if (!sharedInstance)
+ sharedInstance = new ResourceHandleManager();
+ return sharedInstance;
+}
+
+// called with data after all headers have been processed via headerCallback
+static size_t writeCallback(void* ptr, size_t size, size_t nmemb, void* data)
+{
+ ResourceHandle* job = static_cast<ResourceHandle*>(data);
+ ResourceHandleInternal* d = job->getInternal();
+ if (d->m_cancelled)
+ return 0;
+
+#if LIBCURL_VERSION_NUM > 0x071200
+ // We should never be called when deferred loading is activated.
+ ASSERT(!d->m_defersLoading);
+#endif
+
+ size_t totalSize = size * nmemb;
+
+ // this shouldn't be necessary but apparently is. CURL writes the data
+ // of html page even if it is a redirect that was handled internally
+ // can be observed e.g. on gmail.com
+ CURL* h = d->m_handle;
+ long httpCode = 0;
+ CURLcode err = curl_easy_getinfo(h, CURLINFO_RESPONSE_CODE, &httpCode);
+ if (CURLE_OK == err && httpCode >= 300 && httpCode < 400)
+ return totalSize;
+
+ // since the code in headerCallback will not have run for local files
+ // the code to set the URL and fire didReceiveResponse is never run,
+ // 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.
+ if (!d->m_response.responseFired()) {
+ const char* hdr;
+ err = curl_easy_getinfo(h, CURLINFO_EFFECTIVE_URL, &hdr);
+ d->m_response.setUrl(KURL(hdr));
+ if (d->client())
+ d->client()->didReceiveResponse(job, d->m_response);
+ d->m_response.setResponseFired(true);
+ }
+
+ if (d->client())
+ d->client()->didReceiveData(job, static_cast<char*>(ptr), totalSize, 0);
+ return totalSize;
+}
+
+/*
+ * This is being called for each HTTP header in the response. This includes '\r\n'
+ * for the last line of the header.
+ *
+ * We will add each HTTP Header to the ResourceResponse and on the termination
+ * of the header (\r\n) we will parse Content-Type and Content-Disposition and
+ * update the ResourceResponse and then send it away.
+ *
+ */
+static size_t headerCallback(char* ptr, size_t size, size_t nmemb, void* data)
+{
+ ResourceHandle* job = static_cast<ResourceHandle*>(data);
+ ResourceHandleInternal* d = job->getInternal();
+ if (d->m_cancelled)
+ return 0;
+
+#if LIBCURL_VERSION_NUM > 0x071200
+ // We should never be called when deferred loading is activated.
+ ASSERT(!d->m_defersLoading);
+#endif
+
+ size_t totalSize = size * nmemb;
+ ResourceHandleClient* client = d->client();
+
+ String header(static_cast<const char*>(ptr), totalSize);
+
+ /*
+ * a) We can finish and send the ResourceResponse
+ * b) We will add the current header to the HTTPHeaderMap of the ResourceResponse
+ *
+ * The HTTP standard requires to use \r\n but for compatibility it recommends to
+ * accept also \n.
+ */
+ if (header == String("\r\n") || header == String("\n")) {
+ CURL* h = d->m_handle;
+ CURLcode err;
+
+ double contentLength = 0;
+ err = curl_easy_getinfo(h, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength);
+ d->m_response.setExpectedContentLength(static_cast<long long int>(contentLength));
+
+ const char* hdr;
+ err = curl_easy_getinfo(h, CURLINFO_EFFECTIVE_URL, &hdr);
+ d->m_response.setUrl(KURL(hdr));
+
+ long httpCode = 0;
+ err = curl_easy_getinfo(h, CURLINFO_RESPONSE_CODE, &httpCode);
+ d->m_response.setHTTPStatusCode(httpCode);
+
+ d->m_response.setMimeType(extractMIMETypeFromMediaType(d->m_response.httpHeaderField("Content-Type")));
+ d->m_response.setTextEncodingName(extractCharsetFromMediaType(d->m_response.httpHeaderField("Content-Type")));
+ d->m_response.setSuggestedFilename(filenameFromHTTPContentDisposition(d->m_response.httpHeaderField("Content-Disposition")));
+
+ // HTTP redirection
+ if (httpCode >= 300 && httpCode < 400) {
+ String location = d->m_response.httpHeaderField("location");
+ if (!location.isEmpty()) {
+ KURL newURL = KURL(job->request().url(), location);
+
+ ResourceRequest redirectedRequest = job->request();
+ redirectedRequest.setURL(newURL);
+ if (client)
+ client->willSendRequest(job, redirectedRequest, d->m_response);
+
+ d->m_request.setURL(newURL);
+
+ return totalSize;
+ }
+ }
+
+ if (client)
+ client->didReceiveResponse(job, d->m_response);
+ d->m_response.setResponseFired(true);
+
+ } else {
+ int splitPos = header.find(":");
+ if (splitPos != -1)
+ d->m_response.setHTTPHeaderField(header.left(splitPos), header.substring(splitPos+1).stripWhiteSpace());
+ }
+
+ return totalSize;
+}
+
+/* This is called to obtain HTTP POST or PUT data.
+ Iterate through FormData elements and upload files.
+ Carefully respect the given buffer size and fill the rest of the data at the next calls.
+*/
+size_t readCallback(void* ptr, size_t size, size_t nmemb, void* data)
+{
+ ResourceHandle* job = static_cast<ResourceHandle*>(data);
+ ResourceHandleInternal* d = job->getInternal();
+ if (d->m_cancelled)
+ return 0;
+
+#if LIBCURL_VERSION_NUM > 0x071200
+ // We should never be called when deferred loading is activated.
+ ASSERT(!d->m_defersLoading);
+#endif
+
+ if (!size || !nmemb)
+ return 0;
+
+ if (!d->m_formDataStream.hasMoreElements())
+ return 0;
+
+ size_t sent = d->m_formDataStream.read(ptr, size, nmemb);
+
+ // Something went wrong so cancel the job.
+ if (!sent)
+ job->cancel();
+
+ return sent;
+}
+
+void ResourceHandleManager::downloadTimerCallback(Timer<ResourceHandleManager>* timer)
+{
+ startScheduledJobs();
+
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = 0;
+
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = selectTimeoutMS * 1000; // select waits microseconds
+
+ // Temporarily disable timers since signals may interrupt select(), raising EINTR errors on some platforms
+ setDeferringTimers(true);
+ int rc = 0;
+ do {
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+ curl_multi_fdset(m_curlMultiHandle, &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);
+ setDeferringTimers(false);
+
+ if (-1 == rc) {
+#ifndef NDEBUG
+ perror("bad: select() returned -1: ");
+#endif
+ return;
+ }
+
+ int runningHandles = 0;
+ while (curl_multi_perform(m_curlMultiHandle, &runningHandles) == CURLM_CALL_MULTI_PERFORM) { }
+
+ // check the curl messages indicating completed transfers
+ // and free their resources
+ while (true) {
+ int messagesInQueue;
+ CURLMsg* msg = curl_multi_info_read(m_curlMultiHandle, &messagesInQueue);
+ if (!msg)
+ break;
+
+ // find the node which has same d->m_handle as completed transfer
+ CURL* handle = msg->easy_handle;
+ ASSERT(handle);
+ ResourceHandle* job = 0;
+ CURLcode err = curl_easy_getinfo(handle, CURLINFO_PRIVATE, &job);
+ ASSERT(CURLE_OK == err);
+ ASSERT(job);
+ if (!job)
+ continue;
+ ResourceHandleInternal* d = job->getInternal();
+ ASSERT(d->m_handle == handle);
+
+ if (d->m_cancelled) {
+ removeFromCurl(job);
+ continue;
+ }
+
+ if (CURLMSG_DONE != msg->msg)
+ continue;
+
+ if (CURLE_OK == msg->data.result) {
+ if (d->client())
+ d->client()->didFinishLoading(job);
+ } else {
+#ifndef NDEBUG
+ char* url = 0;
+ curl_easy_getinfo(d->m_handle, CURLINFO_EFFECTIVE_URL, &url);
+ printf("Curl ERROR for url='%s', error: '%s'\n", url, curl_easy_strerror(msg->data.result));
+#endif
+ if (d->client())
+ d->client()->didFail(job, ResourceError());
+ }
+
+ removeFromCurl(job);
+ }
+
+ bool started = startScheduledJobs(); // new jobs might have been added in the meantime
+
+ if (!m_downloadTimer.isActive() && (started || (runningHandles > 0)))
+ m_downloadTimer.startOneShot(pollTimeSeconds);
+}
+
+void ResourceHandleManager::removeFromCurl(ResourceHandle* job)
+{
+ ResourceHandleInternal* d = job->getInternal();
+ ASSERT(d->m_handle);
+ if (!d->m_handle)
+ return;
+ m_runningJobs--;
+ curl_multi_remove_handle(m_curlMultiHandle, d->m_handle);
+ curl_easy_cleanup(d->m_handle);
+ d->m_handle = 0;
+}
+
+void ResourceHandleManager::setupPUT(ResourceHandle*, struct curl_slist**)
+{
+ notImplemented();
+}
+
+/* Calculate the length of the POST.
+ Force chunked data transfer if size of files can't be obtained.
+ */
+void ResourceHandleManager::setupPOST(ResourceHandle* job, struct curl_slist** headers)
+{
+ ResourceHandleInternal* d = job->getInternal();
+ Vector<FormDataElement> elements;
+ // Fix crash when httpBody is null (see bug #16906).
+ if (job->request().httpBody())
+ elements = job->request().httpBody()->elements();
+ size_t numElements = elements.size();
+
+ if (!numElements)
+ return;
+
+ // Do not stream for simple POST data
+ if (numElements == 1) {
+ job->request().httpBody()->flatten(d->m_postBytes);
+ if (d->m_postBytes.size() != 0) {
+ curl_easy_setopt(d->m_handle, CURLOPT_POST, TRUE);
+ curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDSIZE, d->m_postBytes.size());
+ curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDS, d->m_postBytes.data());
+ }
+ return;
+ }
+
+ // Obtain the total size of the POST
+ // The size of a curl_off_t could be different in WebKit and in cURL depending on
+ // compilation flags of both. For CURLOPT_POSTFIELDSIZE_LARGE we have to pass the
+ // right size or random data will be used as the size.
+ static int expectedSizeOfCurlOffT = 0;
+ if (!expectedSizeOfCurlOffT) {
+ curl_version_info_data *infoData = curl_version_info(CURLVERSION_NOW);
+ if (infoData->features & CURL_VERSION_LARGEFILE)
+ expectedSizeOfCurlOffT = sizeof(long long);
+ else
+ expectedSizeOfCurlOffT = sizeof(int);
+ }
+
+#if COMPILER(MSVC)
+ // work around compiler error in Visual Studio 2005. It can't properly
+ // handle math with 64-bit constant declarations.
+#pragma warning(disable: 4307)
+#endif
+ static const long long maxCurlOffT = (1LL << (expectedSizeOfCurlOffT * 8 - 1)) - 1;
+ curl_off_t size = 0;
+ bool chunkedTransfer = false;
+ for (size_t i = 0; i < numElements; i++) {
+ FormDataElement element = elements[i];
+ if (element.m_type == FormDataElement::encodedFile) {
+ long long fileSizeResult;
+ if (getFileSize(element.m_filename, fileSizeResult)) {
+ if (fileSizeResult > maxCurlOffT) {
+ // File size is too big for specifying it to cURL
+ chunkedTransfer = true;
+ break;
+ }
+ size += fileSizeResult;
+ } else {
+ chunkedTransfer = true;
+ break;
+ }
+ } else
+ size += elements[i].m_data.size();
+ }
+
+ curl_easy_setopt(d->m_handle, CURLOPT_POST, TRUE);
+
+ // cURL guesses that we want chunked encoding as long as we specify the header
+ if (chunkedTransfer)
+ *headers = curl_slist_append(*headers, "Transfer-Encoding: chunked");
+ else {
+ if (sizeof(long long) == expectedSizeOfCurlOffT)
+ curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDSIZE_LARGE, (long long)size);
+ else
+ curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDSIZE_LARGE, (int)size);
+ }
+
+ curl_easy_setopt(d->m_handle, CURLOPT_READFUNCTION, readCallback);
+ curl_easy_setopt(d->m_handle, CURLOPT_READDATA, job);
+}
+
+void ResourceHandleManager::add(ResourceHandle* job)
+{
+ // we can be called from within curl, so to avoid re-entrancy issues
+ // schedule this job to be added the next time we enter curl download loop
+ m_resourceHandleList.append(job);
+ if (!m_downloadTimer.isActive())
+ m_downloadTimer.startOneShot(pollTimeSeconds);
+}
+
+bool ResourceHandleManager::removeScheduledJob(ResourceHandle* job)
+{
+ int size = m_resourceHandleList.size();
+ for (int i = 0; i < size; i++) {
+ if (job == m_resourceHandleList[i]) {
+ m_resourceHandleList.remove(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ResourceHandleManager::startScheduledJobs()
+{
+ // TODO: Create a separate stack of jobs for each domain.
+
+ bool started = false;
+ while (!m_resourceHandleList.isEmpty() && m_runningJobs < maxRunningJobs) {
+ ResourceHandle* job = m_resourceHandleList[0];
+ m_resourceHandleList.remove(0);
+ startJob(job);
+ started = true;
+ }
+ return started;
+}
+
+static void parseDataUrl(ResourceHandle* handle)
+{
+ ResourceHandleClient* client = handle->client();
+
+ ASSERT(client);
+ if (!client)
+ return;
+
+ String url = handle->request().url().string();
+ ASSERT(url.startsWith("data:", false));
+
+ int index = url.find(',');
+ if (index == -1) {
+ client->cannotShowURL(handle);
+ return;
+ }
+
+ String mediaType = url.substring(5, index - 5);
+ String data = url.substring(index + 1);
+
+ bool base64 = mediaType.endsWith(";base64", false);
+ if (base64)
+ mediaType = mediaType.left(mediaType.length() - 7);
+
+ if (mediaType.isEmpty())
+ mediaType = "text/plain;charset=US-ASCII";
+
+ String mimeType = extractMIMETypeFromMediaType(mediaType);
+ String charset = extractCharsetFromMediaType(mediaType);
+
+ ResourceResponse response;
+ response.setMimeType(mimeType);
+
+ if (base64) {
+ data = decodeURLEscapeSequences(data);
+ response.setTextEncodingName(charset);
+ client->didReceiveResponse(handle, response);
+
+ // Use the GLib Base64 if available, since WebCore's decoder isn't
+ // general-purpose and fails on Acid3 test 97 (whitespace).
+#ifdef USE_GLIB_BASE64
+ size_t outLength = 0;
+ char* outData = 0;
+ outData = reinterpret_cast<char*>(g_base64_decode(data.utf8().data(), &outLength));
+ if (outData && outLength > 0)
+ client->didReceiveData(handle, outData, outLength, 0);
+ g_free(outData);
+#else
+ Vector<char> out;
+ if (base64Decode(data.latin1().data(), data.latin1().length(), out) && out.size() > 0)
+ client->didReceiveData(handle, out.data(), out.size(), 0);
+#endif
+ } else {
+ // We have to convert to UTF-16 early due to limitations in KURL
+ data = decodeURLEscapeSequences(data, TextEncoding(charset));
+ response.setTextEncodingName("UTF-16");
+ client->didReceiveResponse(handle, response);
+ if (data.length() > 0)
+ client->didReceiveData(handle, reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0);
+ }
+
+ client->didFinishLoading(handle);
+}
+
+void ResourceHandleManager::dispatchSynchronousJob(ResourceHandle* job)
+{
+ KURL kurl = job->request().url();
+
+ if (kurl.protocolIs("data")) {
+ parseDataUrl(job);
+ return;
+ }
+
+ ResourceHandleInternal* handle = job->getInternal();
+
+#if LIBCURL_VERSION_NUM > 0x071200
+ // If defersLoading is true and we call curl_easy_perform
+ // on a paused handle, libcURL would do the transfert anyway
+ // and we would assert so force defersLoading to be false.
+ handle->m_defersLoading = false;
+#endif
+
+ initializeHandle(job);
+
+ // curl_easy_perform blocks until the transfert is finished.
+ CURLcode ret = curl_easy_perform(handle->m_handle);
+
+ if (ret != 0) {
+ ResourceError error(String(handle->m_url), ret, String(handle->m_url), String(curl_easy_strerror(ret)));
+ handle->client()->didFail(job, error);
+ }
+
+ curl_easy_cleanup(handle->m_handle);
+}
+
+void ResourceHandleManager::startJob(ResourceHandle* job)
+{
+ KURL kurl = job->request().url();
+
+ if (kurl.protocolIs("data")) {
+ parseDataUrl(job);
+ return;
+ }
+
+ initializeHandle(job);
+
+ m_runningJobs++;
+ CURLMcode ret = curl_multi_add_handle(m_curlMultiHandle, job->getInternal()->m_handle);
+ // don't call perform, because events must be async
+ // timeout will occur and do curl_multi_perform
+ if (ret && ret != CURLM_CALL_MULTI_PERFORM) {
+#ifndef NDEBUG
+ printf("Error %d starting job %s\n", ret, encodeWithURLEscapeSequences(job->request().url().string()).latin1().data());
+#endif
+ job->cancel();
+ return;
+ }
+}
+
+void ResourceHandleManager::initializeHandle(ResourceHandle* job)
+{
+ KURL kurl = job->request().url();
+
+ // Remove any fragment part, otherwise curl will send it as part of the request.
+ kurl.removeRef();
+
+ ResourceHandleInternal* d = job->getInternal();
+ String url = kurl.string();
+
+ if (kurl.isLocalFile()) {
+ String query = kurl.query();
+ // Remove any query part sent to a local file.
+ if (!query.isEmpty())
+ url = url.left(url.find(query));
+ // Determine the MIME type based on the path.
+ d->m_response.setMimeType(MIMETypeRegistry::getMIMETypeForPath(url));
+ }
+
+ d->m_handle = curl_easy_init();
+
+#if LIBCURL_VERSION_NUM > 0x071200
+ if (d->m_defersLoading) {
+ CURLcode error = curl_easy_pause(d->m_handle, CURLPAUSE_ALL);
+ // If we did not pause the handle, we would ASSERT in the
+ // header callback. So just assert here.
+ ASSERT(error == CURLE_OK);
+ }
+#endif
+#ifndef NDEBUG
+ if (getenv("DEBUG_CURL"))
+ curl_easy_setopt(d->m_handle, CURLOPT_VERBOSE, 1);
+#endif
+ curl_easy_setopt(d->m_handle, CURLOPT_PRIVATE, job);
+ curl_easy_setopt(d->m_handle, CURLOPT_ERRORBUFFER, m_curlErrorBuffer);
+ curl_easy_setopt(d->m_handle, CURLOPT_WRITEFUNCTION, writeCallback);
+ curl_easy_setopt(d->m_handle, CURLOPT_WRITEDATA, job);
+ curl_easy_setopt(d->m_handle, CURLOPT_HEADERFUNCTION, headerCallback);
+ curl_easy_setopt(d->m_handle, CURLOPT_WRITEHEADER, job);
+ curl_easy_setopt(d->m_handle, CURLOPT_AUTOREFERER, 1);
+ 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_DNS_CACHE_TIMEOUT, 60 * 5); // 5 minutes
+ // FIXME: Enable SSL verification when we have a way of shipping certs
+ // and/or reporting SSL errors to the user.
+ if (ignoreSSLErrors)
+ curl_easy_setopt(d->m_handle, CURLOPT_SSL_VERIFYPEER, false);
+ // enable gzip and deflate through Accept-Encoding:
+ curl_easy_setopt(d->m_handle, CURLOPT_ENCODING, "");
+
+ // url must remain valid through the request
+ ASSERT(!d->m_url);
+
+ // url is in ASCII so latin1() will only convert it to char* without character translation.
+ d->m_url = strdup(url.latin1().data());
+ curl_easy_setopt(d->m_handle, CURLOPT_URL, d->m_url);
+
+ if (m_cookieJarFileName) {
+ curl_easy_setopt(d->m_handle, CURLOPT_COOKIEFILE, m_cookieJarFileName);
+ curl_easy_setopt(d->m_handle, CURLOPT_COOKIEJAR, m_cookieJarFileName);
+ }
+
+ struct curl_slist* headers = 0;
+ if (job->request().httpHeaderFields().size() > 0) {
+ HTTPHeaderMap customHeaders = job->request().httpHeaderFields();
+ HTTPHeaderMap::const_iterator end = customHeaders.end();
+ for (HTTPHeaderMap::const_iterator it = customHeaders.begin(); it != end; ++it) {
+ String key = it->first;
+ String value = it->second;
+ String headerString(key);
+ headerString.append(": ");
+ headerString.append(value);
+ CString headerLatin1 = headerString.latin1();
+ headers = curl_slist_append(headers, headerLatin1.data());
+ }
+ }
+
+ if ("GET" == job->request().httpMethod())
+ curl_easy_setopt(d->m_handle, CURLOPT_HTTPGET, TRUE);
+ else if ("POST" == job->request().httpMethod())
+ setupPOST(job, &headers);
+ else if ("PUT" == job->request().httpMethod())
+ setupPUT(job, &headers);
+ else if ("HEAD" == job->request().httpMethod())
+ curl_easy_setopt(d->m_handle, CURLOPT_NOBODY, TRUE);
+
+ if (headers) {
+ curl_easy_setopt(d->m_handle, CURLOPT_HTTPHEADER, headers);
+ d->m_customHeaders = headers;
+ }
+}
+
+void ResourceHandleManager::cancel(ResourceHandle* job)
+{
+ if (removeScheduledJob(job))
+ return;
+
+ ResourceHandleInternal* d = job->getInternal();
+ d->m_cancelled = true;
+ if (!m_downloadTimer.isActive())
+ m_downloadTimer.startOneShot(pollTimeSeconds);
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/curl/ResourceHandleManager.h b/WebCore/platform/network/curl/ResourceHandleManager.h
new file mode 100644
index 0000000..f3ad234
--- /dev/null
+++ b/WebCore/platform/network/curl/ResourceHandleManager.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
+ * All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceHandleManager_h
+#define ResourceHandleManager_h
+
+#include "Frame.h"
+#include "Timer.h"
+#include "ResourceHandleClient.h"
+
+#include <curl/curl.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class ResourceHandleManager {
+public:
+ static ResourceHandleManager* sharedInstance();
+ void add(ResourceHandle*);
+ void cancel(ResourceHandle*);
+ void setCookieJarFileName(const char* cookieJarFileName);
+
+ void dispatchSynchronousJob(ResourceHandle*);
+
+ void setupPOST(ResourceHandle*, struct curl_slist**);
+ void setupPUT(ResourceHandle*, struct curl_slist**);
+
+private:
+ ResourceHandleManager();
+ ~ResourceHandleManager();
+ void downloadTimerCallback(Timer<ResourceHandleManager>*);
+ void removeFromCurl(ResourceHandle*);
+ bool removeScheduledJob(ResourceHandle*);
+ void startJob(ResourceHandle*);
+ bool startScheduledJobs();
+
+ void initializeHandle(ResourceHandle*);
+
+ Timer<ResourceHandleManager> m_downloadTimer;
+ CURLM* m_curlMultiHandle;
+ CURLSH* m_curlShareHandle;
+ char* m_cookieJarFileName;
+ char m_curlErrorBuffer[CURL_ERROR_SIZE];
+ Vector<ResourceHandle*> m_resourceHandleList;
+ int m_runningJobs;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/network/curl/ResourceRequest.h b/WebCore/platform/network/curl/ResourceRequest.h
new file mode 100644
index 0000000..b3032aa
--- /dev/null
+++ b/WebCore/platform/network/curl/ResourceRequest.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceRequest_h
+#define ResourceRequest_h
+
+#include "ResourceRequestBase.h"
+
+typedef const struct _CFURLRequest* CFURLRequestRef;
+
+namespace WebCore {
+
+ struct ResourceRequest : ResourceRequestBase {
+
+ ResourceRequest(const String& url)
+ : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(const KURL& url)
+ : ResourceRequestBase(url, UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(const KURL& url, const String& referrer, ResourceRequestCachePolicy policy = UseProtocolCachePolicy)
+ : ResourceRequestBase(url, policy)
+ {
+ setHTTPReferrer(referrer);
+ }
+
+ ResourceRequest()
+ : ResourceRequestBase(KURL(), UseProtocolCachePolicy)
+ {
+ }
+
+ // Needed for compatibility.
+ CFURLRequestRef cfURLRequest() const { return 0; }
+
+ private:
+ friend class ResourceRequestBase;
+
+ void doUpdatePlatformRequest() {}
+ void doUpdateResourceRequest() {}
+ };
+
+} // namespace WebCore
+
+#endif // ResourceRequest_h
diff --git a/WebCore/platform/network/curl/ResourceResponse.h b/WebCore/platform/network/curl/ResourceResponse.h
new file mode 100644
index 0000000..6195f61
--- /dev/null
+++ b/WebCore/platform/network/curl/ResourceResponse.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceResponse_h
+#define ResourceResponse_h
+
+#include "ResourceResponseBase.h"
+
+namespace WebCore {
+
+class ResourceResponse : public ResourceResponseBase {
+public:
+ ResourceResponse()
+ : m_responseFired(false)
+ {
+ }
+
+ ResourceResponse(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename)
+ : ResourceResponseBase(url, mimeType, expectedLength, textEncodingName, filename),
+ m_responseFired(false)
+ {
+ }
+
+ void setResponseFired(bool fired) { m_responseFired = fired; }
+ bool responseFired() { return m_responseFired; }
+
+private:
+ bool m_responseFired;
+};
+
+} // namespace WebCore
+
+#endif // ResourceResponse_h
diff --git a/WebCore/platform/network/mac/AuthenticationChallenge.h b/WebCore/platform/network/mac/AuthenticationChallenge.h
new file mode 100644
index 0000000..e8f3a2d
--- /dev/null
+++ b/WebCore/platform/network/mac/AuthenticationChallenge.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef AuthenticationChallenge_h
+#define AuthenticationChallenge_h
+
+#include "AuthenticationChallengeBase.h"
+
+#include <wtf/RetainPtr.h>
+#ifndef __OBJC__
+typedef struct objc_object *id;
+class NSURLAuthenticationChallenge;
+#else
+@class NSURLAuthenticationChallenge;
+#endif
+
+namespace WebCore {
+
+class AuthenticationChallenge : public AuthenticationChallengeBase {
+public:
+ AuthenticationChallenge() {}
+ AuthenticationChallenge(const ProtectionSpace& protectionSpace, const Credential& proposedCredential, unsigned previousFailureCount, const ResourceResponse& response, const ResourceError& error);
+ AuthenticationChallenge(NSURLAuthenticationChallenge *);
+
+ id sender() const { return m_sender.get(); }
+ NSURLAuthenticationChallenge *nsURLAuthenticationChallenge() const { return m_macChallenge.get(); }
+
+private:
+ friend class AuthenticationChallengeBase;
+ static bool platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b);
+
+ RetainPtr<id> m_sender;
+ RetainPtr<NSURLAuthenticationChallenge *> m_macChallenge;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/network/mac/AuthenticationMac.h b/WebCore/platform/network/mac/AuthenticationMac.h
new file mode 100644
index 0000000..f55ac24
--- /dev/null
+++ b/WebCore/platform/network/mac/AuthenticationMac.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef AuthenticationMac_h
+#define AuthenticationMac_h
+
+#ifdef __OBJC__
+
+@class NSURLAuthenticationChallenge;
+@class NSURLCredential;
+@class NSURLProtectionSpace;
+
+namespace WebCore {
+
+class AuthenticationChallenge;
+class Credential;
+class ProtectionSpace;
+
+NSURLAuthenticationChallenge *mac(const AuthenticationChallenge&);
+NSURLProtectionSpace *mac(const ProtectionSpace&);
+NSURLCredential *mac(const Credential&);
+
+AuthenticationChallenge core(NSURLAuthenticationChallenge *);
+ProtectionSpace core(NSURLProtectionSpace *);
+Credential core(NSURLCredential *);
+
+}
+#endif
+
+#endif
diff --git a/WebCore/platform/network/mac/AuthenticationMac.mm b/WebCore/platform/network/mac/AuthenticationMac.mm
new file mode 100644
index 0000000..54e7681
--- /dev/null
+++ b/WebCore/platform/network/mac/AuthenticationMac.mm
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#import "config.h"
+#import "AuthenticationMac.h"
+
+#import "AuthenticationChallenge.h"
+#import "Credential.h"
+#import "ProtectionSpace.h"
+
+#import <Foundation/NSURLAuthenticationChallenge.h>
+#import <Foundation/NSURLCredential.h>
+#import <Foundation/NSURLProtectionSpace.h>
+
+
+namespace WebCore {
+
+
+AuthenticationChallenge::AuthenticationChallenge(const ProtectionSpace& protectionSpace,
+ const Credential& proposedCredential,
+ unsigned previousFailureCount,
+ const ResourceResponse& response,
+ const ResourceError& error)
+ : AuthenticationChallengeBase(protectionSpace,
+ proposedCredential,
+ previousFailureCount,
+ response,
+ error)
+{
+}
+
+AuthenticationChallenge::AuthenticationChallenge(NSURLAuthenticationChallenge *macChallenge)
+ : AuthenticationChallengeBase(core([macChallenge protectionSpace]),
+ core([macChallenge proposedCredential]),
+ [macChallenge previousFailureCount],
+ [macChallenge failureResponse],
+ [macChallenge error])
+ , m_sender([macChallenge sender])
+ , m_macChallenge(macChallenge)
+{
+}
+
+bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b)
+{
+ if (a.sender() != b.sender())
+ return false;
+
+ if (a.nsURLAuthenticationChallenge() != b.nsURLAuthenticationChallenge())
+ return false;
+
+ return true;
+}
+
+NSURLAuthenticationChallenge *mac(const AuthenticationChallenge& coreChallenge)
+{
+ if (coreChallenge.nsURLAuthenticationChallenge())
+ return coreChallenge.nsURLAuthenticationChallenge();
+
+ return [[[NSURLAuthenticationChallenge alloc] initWithProtectionSpace:mac(coreChallenge.protectionSpace())
+ proposedCredential:mac(coreChallenge.proposedCredential())
+ previousFailureCount:coreChallenge.previousFailureCount()
+ failureResponse:coreChallenge.failureResponse().nsURLResponse()
+ error:coreChallenge.error()
+ sender:coreChallenge.sender()] autorelease];
+}
+
+NSURLProtectionSpace *mac(const ProtectionSpace& coreSpace)
+{
+ NSString *proxyType = nil;
+ NSString *protocol = nil;
+ switch (coreSpace.serverType()) {
+ case ProtectionSpaceServerHTTP:
+ protocol = @"http";
+ break;
+ case ProtectionSpaceServerHTTPS:
+ protocol = @"https";
+ break;
+ case ProtectionSpaceServerFTP:
+ protocol = @"ftp";
+ break;
+ case ProtectionSpaceServerFTPS:
+ protocol = @"ftps";
+ break;
+ case ProtectionSpaceProxyHTTP:
+ proxyType = NSURLProtectionSpaceHTTPProxy;
+ break;
+ case ProtectionSpaceProxyHTTPS:
+ proxyType = NSURLProtectionSpaceHTTPSProxy;
+ break;
+ case ProtectionSpaceProxyFTP:
+ proxyType = NSURLProtectionSpaceFTPProxy;
+ break;
+ case ProtectionSpaceProxySOCKS:
+ proxyType = NSURLProtectionSpaceSOCKSProxy;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ NSString *method = nil;
+ switch (coreSpace.authenticationScheme()) {
+ case ProtectionSpaceAuthenticationSchemeDefault:
+ method = NSURLAuthenticationMethodDefault;
+ break;
+ case ProtectionSpaceAuthenticationSchemeHTTPBasic:
+ method = NSURLAuthenticationMethodHTTPBasic;
+ break;
+ case ProtectionSpaceAuthenticationSchemeHTTPDigest:
+ method = NSURLAuthenticationMethodHTTPDigest;
+ break;
+ case ProtectionSpaceAuthenticationSchemeHTMLForm:
+ method = NSURLAuthenticationMethodHTMLForm;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ if (proxyType)
+ return [[[NSURLProtectionSpace alloc] initWithProxyHost:coreSpace.host()
+ port:coreSpace.port()
+ type:proxyType
+ realm:coreSpace.realm()
+ authenticationMethod:method] autorelease];
+ return [[[NSURLProtectionSpace alloc] initWithHost:coreSpace.host()
+ port:coreSpace.port()
+ protocol:protocol
+ realm:coreSpace.realm()
+ authenticationMethod:method] autorelease];
+}
+
+NSURLCredential *mac(const Credential& coreCredential)
+{
+ NSURLCredentialPersistence persistence = NSURLCredentialPersistenceNone;
+ switch (coreCredential.persistence()) {
+ case CredentialPersistenceNone:
+ break;
+ case CredentialPersistenceForSession:
+ persistence = NSURLCredentialPersistenceForSession;
+ break;
+ case CredentialPersistencePermanent:
+ persistence = NSURLCredentialPersistencePermanent;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return [[[NSURLCredential alloc] initWithUser:coreCredential.user()
+ password:coreCredential.password()
+ persistence:persistence]
+ autorelease];
+}
+
+AuthenticationChallenge core(NSURLAuthenticationChallenge *macChallenge)
+{
+ return AuthenticationChallenge(macChallenge);
+}
+
+ProtectionSpace core(NSURLProtectionSpace *macSpace)
+{
+ ProtectionSpaceServerType serverType = ProtectionSpaceProxyHTTP;
+
+ if ([macSpace isProxy]) {
+ NSString *proxyType = [macSpace proxyType];
+ if ([proxyType isEqualToString:NSURLProtectionSpaceHTTPProxy])
+ serverType = ProtectionSpaceProxyHTTP;
+ else if ([proxyType isEqualToString:NSURLProtectionSpaceHTTPSProxy])
+ serverType = ProtectionSpaceProxyHTTPS;
+ else if ([proxyType isEqualToString:NSURLProtectionSpaceFTPProxy])
+ serverType = ProtectionSpaceProxyFTP;
+ else if ([proxyType isEqualToString:NSURLProtectionSpaceSOCKSProxy])
+ serverType = ProtectionSpaceProxySOCKS;
+ else
+ ASSERT_NOT_REACHED();
+ } else {
+ NSString *protocol = [macSpace protocol];
+ if ([protocol caseInsensitiveCompare:@"http"] == NSOrderedSame)
+ serverType = ProtectionSpaceServerHTTP;
+ else if ([protocol caseInsensitiveCompare:@"https"] == NSOrderedSame)
+ serverType = ProtectionSpaceServerHTTPS;
+ else if ([protocol caseInsensitiveCompare:@"ftp"] == NSOrderedSame)
+ serverType = ProtectionSpaceServerFTP;
+ else if ([protocol caseInsensitiveCompare:@"ftps"] == NSOrderedSame)
+ serverType = ProtectionSpaceServerFTPS;
+ else
+ ASSERT_NOT_REACHED();
+ }
+
+ ProtectionSpaceAuthenticationScheme scheme = ProtectionSpaceAuthenticationSchemeDefault;
+ NSString *method = [macSpace authenticationMethod];
+ if ([method isEqualToString:NSURLAuthenticationMethodDefault])
+ scheme = ProtectionSpaceAuthenticationSchemeDefault;
+ else if ([method isEqualToString:NSURLAuthenticationMethodHTTPBasic])
+ scheme = ProtectionSpaceAuthenticationSchemeHTTPBasic;
+ else if ([method isEqualToString:NSURLAuthenticationMethodHTTPDigest])
+ scheme = ProtectionSpaceAuthenticationSchemeHTTPDigest;
+ else if ([method isEqualToString:NSURLAuthenticationMethodHTMLForm])
+ scheme = ProtectionSpaceAuthenticationSchemeHTMLForm;
+ else
+ ASSERT_NOT_REACHED();
+
+ return ProtectionSpace([macSpace host], [macSpace port], serverType, [macSpace realm], scheme);
+
+}
+
+Credential core(NSURLCredential *macCredential)
+{
+ CredentialPersistence persistence = CredentialPersistenceNone;
+ switch ([macCredential persistence]) {
+ case NSURLCredentialPersistenceNone:
+ break;
+ case NSURLCredentialPersistenceForSession:
+ persistence = CredentialPersistenceForSession;
+ break;
+ case NSURLCredentialPersistencePermanent:
+ persistence = CredentialPersistencePermanent;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return Credential([macCredential user], [macCredential password], persistence);
+}
+
+};
diff --git a/WebCore/platform/network/mac/FormDataStreamMac.h b/WebCore/platform/network/mac/FormDataStreamMac.h
new file mode 100644
index 0000000..22cc8ce
--- /dev/null
+++ b/WebCore/platform/network/mac/FormDataStreamMac.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#ifndef FormDataStreamMac_h
+#define FormDataStreamMac_h
+
+#include "FormData.h"
+
+@class NSMutableURLRequest;
+
+namespace WebCore {
+
+ class FormData;
+ class ResourceHandle;
+
+ void setHTTPBody(NSMutableURLRequest *, PassRefPtr<FormData>);
+ FormData* httpBodyFromStream(NSInputStream *);
+
+ void associateStreamWithResourceHandle(NSInputStream *, ResourceHandle*);
+ void disassociateStreamWithResourceHandle(NSInputStream *);
+
+} // namespace WebCore
+
+#endif // FormDataStreamMac_h
diff --git a/WebCore/platform/network/mac/FormDataStreamMac.mm b/WebCore/platform/network/mac/FormDataStreamMac.mm
new file mode 100644
index 0000000..3ef224d
--- /dev/null
+++ b/WebCore/platform/network/mac/FormDataStreamMac.mm
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+/* originally written by Becky Willrich, additional code by Darin Adler */
+
+#import "config.h"
+#import "FormDataStreamMac.h"
+
+#import "CString.h"
+#import "FormData.h"
+#import "ResourceHandle.h"
+#import "ResourceHandleClient.h"
+#import "SchedulePair.h"
+#import "WebCoreSystemInterface.h"
+#import <sys/stat.h>
+#import <sys/types.h>
+#import <wtf/Assertions.h>
+#import <wtf/HashMap.h>
+#import <wtf/MainThread.h>
+#import <wtf/Threading.h>
+
+namespace WebCore {
+
+typedef HashMap<CFReadStreamRef, RefPtr<FormData> > StreamFormDataMap;
+static StreamFormDataMap& getStreamFormDataMap()
+{
+ static StreamFormDataMap streamFormDataMap;
+ return streamFormDataMap;
+}
+
+typedef HashMap<CFReadStreamRef, RefPtr<ResourceHandle> > StreamResourceHandleMap;
+static StreamResourceHandleMap& getStreamResourceHandleMap()
+{
+ static StreamResourceHandleMap streamResourceHandleMap;
+ return streamResourceHandleMap;
+}
+
+void associateStreamWithResourceHandle(NSInputStream *stream, ResourceHandle* resourceHandle)
+{
+ ASSERT(isMainThread());
+
+ ASSERT(resourceHandle);
+
+ if (!stream)
+ return;
+
+ if (!getStreamFormDataMap().contains((CFReadStreamRef)stream))
+ return;
+
+ ASSERT(!getStreamResourceHandleMap().contains((CFReadStreamRef)stream));
+ getStreamResourceHandleMap().set((CFReadStreamRef)stream, resourceHandle);
+}
+
+void disassociateStreamWithResourceHandle(NSInputStream *stream)
+{
+ ASSERT(isMainThread());
+
+ if (!stream)
+ return;
+
+ getStreamResourceHandleMap().remove((CFReadStreamRef)stream);
+}
+
+struct DidSendDataCallbackData {
+ DidSendDataCallbackData(CFReadStreamRef stream_, unsigned long long bytesSent_, unsigned long long streamLength_)
+ : stream(stream_)
+ , bytesSent(bytesSent_)
+ , streamLength(streamLength_)
+ {
+ }
+
+ CFReadStreamRef stream;
+ unsigned long long bytesSent;
+ unsigned long long streamLength;
+};
+
+static void performDidSendDataCallback(void* context)
+{
+ ASSERT(isMainThread());
+
+ DidSendDataCallbackData* data = static_cast<DidSendDataCallbackData*>(context);
+ ResourceHandle* resourceHandle = getStreamResourceHandleMap().get(data->stream).get();
+
+ if (resourceHandle && resourceHandle->client())
+ resourceHandle->client()->didSendData(resourceHandle, data->bytesSent, data->streamLength);
+
+ delete data;
+}
+
+static void formEventCallback(CFReadStreamRef stream, CFStreamEventType type, void* context);
+
+struct FormContext {
+ FormData* formData;
+ unsigned long long streamLength;
+};
+
+struct FormStreamFields {
+ SchedulePairHashSet scheduledRunLoopPairs;
+ Vector<FormDataElement> remainingElements; // in reverse order
+ CFReadStreamRef currentStream;
+ char* currentData;
+ CFReadStreamRef formStream;
+ unsigned long long streamLength;
+ unsigned long long bytesSent;
+};
+
+static void closeCurrentStream(FormStreamFields *form)
+{
+ if (form->currentStream) {
+ CFReadStreamClose(form->currentStream);
+ CFReadStreamSetClient(form->currentStream, kCFStreamEventNone, NULL, NULL);
+ CFRelease(form->currentStream);
+ form->currentStream = NULL;
+ }
+ if (form->currentData) {
+ fastFree(form->currentData);
+ form->currentData = 0;
+ }
+}
+
+static void advanceCurrentStream(FormStreamFields *form)
+{
+ closeCurrentStream(form);
+
+ if (form->remainingElements.isEmpty())
+ return;
+
+ // Create the new stream.
+ FormDataElement& nextInput = form->remainingElements.last();
+ if (nextInput.m_type == FormDataElement::data) {
+ size_t size = nextInput.m_data.size();
+ char* data = nextInput.m_data.releaseBuffer();
+ form->currentStream = CFReadStreamCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data), size, kCFAllocatorNull);
+ form->currentData = data;
+ } else {
+ const String& path = nextInput.m_shouldGenerateFile ? nextInput.m_generatedFilename : nextInput.m_filename;
+ CFStringRef filename = path.createCFString();
+ CFURLRef fileURL = CFURLCreateWithFileSystemPath(0, filename, kCFURLPOSIXPathStyle, FALSE);
+ CFRelease(filename);
+ form->currentStream = CFReadStreamCreateWithFile(0, fileURL);
+ CFRelease(fileURL);
+ }
+ form->remainingElements.removeLast();
+
+ // Set up the callback.
+ CFStreamClientContext context = { 0, form, NULL, NULL, NULL };
+ CFReadStreamSetClient(form->currentStream, kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
+ formEventCallback, &context);
+
+ // Schedule with the current set of run loops.
+ SchedulePairHashSet::iterator end = form->scheduledRunLoopPairs.end();
+ for (SchedulePairHashSet::iterator it = form->scheduledRunLoopPairs.begin(); it != end; ++it)
+ CFReadStreamScheduleWithRunLoop(form->currentStream, (*it)->runLoop(), (*it)->mode());
+}
+
+static void openNextStream(FormStreamFields* form)
+{
+ // Skip over any streams we can't open.
+ // For some purposes we might want to return an error, but the current NSURLConnection
+ // can't really do anything useful with an error at this point, so this is better.
+ advanceCurrentStream(form);
+ while (form->currentStream && !CFReadStreamOpen(form->currentStream))
+ advanceCurrentStream(form);
+}
+
+static void* formCreate(CFReadStreamRef stream, void* context)
+{
+ FormContext* formContext = static_cast<FormContext*>(context);
+
+ FormStreamFields* newInfo = new FormStreamFields;
+ newInfo->currentStream = NULL;
+ newInfo->currentData = 0;
+ newInfo->formStream = stream; // Don't retain. That would create a reference cycle.
+ newInfo->streamLength = formContext->streamLength;
+ newInfo->bytesSent = 0;
+
+ FormData* formData = formContext->formData;
+
+ // Append in reverse order since we remove elements from the end.
+ size_t size = formData->elements().size();
+ newInfo->remainingElements.reserveCapacity(size);
+ for (size_t i = 0; i < size; ++i)
+ newInfo->remainingElements.append(formData->elements()[size - i - 1]);
+
+ getStreamFormDataMap().set(stream, adoptRef(formData));
+
+ return newInfo;
+}
+
+static void formFinalize(CFReadStreamRef stream, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ getStreamFormDataMap().remove(stream);
+
+ closeCurrentStream(form);
+ delete form;
+}
+
+static Boolean formOpen(CFReadStreamRef stream, CFStreamError* error, Boolean* openComplete, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ openNextStream(form);
+
+ *openComplete = TRUE;
+ error->error = 0;
+ return TRUE;
+}
+
+static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLength, CFStreamError* error, Boolean* atEOF, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ while (form->currentStream) {
+ CFIndex bytesRead = CFReadStreamRead(form->currentStream, buffer, bufferLength);
+ if (bytesRead < 0) {
+ *error = CFReadStreamGetError(form->currentStream);
+ return -1;
+ }
+ if (bytesRead > 0) {
+ error->error = 0;
+ *atEOF = FALSE;
+ form->bytesSent += bytesRead;
+
+ if (!ResourceHandle::didSendBodyDataDelegateExists()) {
+ // FIXME: Figure out how to only do this when a ResourceHandleClient is available.
+ DidSendDataCallbackData* data = new DidSendDataCallbackData(stream, form->bytesSent, form->streamLength);
+ callOnMainThread(performDidSendDataCallback, data);
+ }
+
+ return bytesRead;
+ }
+ openNextStream(form);
+ }
+
+ error->error = 0;
+ *atEOF = TRUE;
+ return 0;
+}
+
+static Boolean formCanRead(CFReadStreamRef stream, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ while (form->currentStream && CFReadStreamGetStatus(form->currentStream) == kCFStreamStatusAtEnd) {
+ openNextStream(form);
+ }
+ if (!form->currentStream) {
+ wkSignalCFReadStreamEnd(stream);
+ return FALSE;
+ }
+ return CFReadStreamHasBytesAvailable(form->currentStream);
+}
+
+static void formClose(CFReadStreamRef stream, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ closeCurrentStream(form);
+}
+
+static void formSchedule(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ if (form->currentStream)
+ CFReadStreamScheduleWithRunLoop(form->currentStream, runLoop, runLoopMode);
+ form->scheduledRunLoopPairs.add(SchedulePair::create(runLoop, runLoopMode));
+}
+
+static void formUnschedule(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ if (form->currentStream)
+ CFReadStreamUnscheduleFromRunLoop(form->currentStream, runLoop, runLoopMode);
+ form->scheduledRunLoopPairs.remove(SchedulePair::create(runLoop, runLoopMode));
+}
+
+static void formEventCallback(CFReadStreamRef stream, CFStreamEventType type, void* context)
+{
+ FormStreamFields* form = static_cast<FormStreamFields*>(context);
+
+ switch (type) {
+ case kCFStreamEventHasBytesAvailable:
+ wkSignalCFReadStreamHasBytes(form->formStream);
+ break;
+ case kCFStreamEventErrorOccurred: {
+ CFStreamError readStreamError = CFReadStreamGetError(stream);
+ wkSignalCFReadStreamError(form->formStream, &readStreamError);
+ break;
+ }
+ case kCFStreamEventEndEncountered:
+ openNextStream(form);
+ if (!form->currentStream) {
+ wkSignalCFReadStreamEnd(form->formStream);
+ }
+ break;
+ case kCFStreamEventNone:
+ LOG_ERROR("unexpected kCFStreamEventNone");
+ break;
+ case kCFStreamEventOpenCompleted:
+ LOG_ERROR("unexpected kCFStreamEventOpenCompleted");
+ break;
+ case kCFStreamEventCanAcceptBytes:
+ LOG_ERROR("unexpected kCFStreamEventCanAcceptBytes");
+ break;
+ }
+}
+
+void setHTTPBody(NSMutableURLRequest *request, PassRefPtr<FormData> formData)
+{
+ if (!formData)
+ return;
+
+ size_t count = formData->elements().size();
+
+ // Handle the common special case of one piece of form data, with no files.
+ if (count == 1 && !formData->alwaysStream()) {
+ const FormDataElement& element = formData->elements()[0];
+ if (element.m_type == FormDataElement::data) {
+ NSData *data = [[NSData alloc] initWithBytes:element.m_data.data() length:element.m_data.size()];
+ [request setHTTPBody:data];
+ [data release];
+ return;
+ }
+ }
+
+ // Precompute the content length so NSURLConnection doesn't use chunked mode.
+ long long length = 0;
+ for (size_t i = 0; i < count; ++i) {
+ const FormDataElement& element = formData->elements()[i];
+ if (element.m_type == FormDataElement::data)
+ length += element.m_data.size();
+ else {
+ const String& filename = element.m_shouldGenerateFile ? element.m_generatedFilename : element.m_filename;
+ struct stat sb;
+ int statResult = stat(filename.utf8().data(), &sb);
+ if (statResult == 0 && (sb.st_mode & S_IFMT) == S_IFREG)
+ length += sb.st_size;
+ }
+ }
+
+ // Set the length.
+ [request setValue:[NSString stringWithFormat:@"%lld", length] forHTTPHeaderField:@"Content-Length"];
+
+ // Create and set the stream.
+
+ // Pass the length along with the formData so it does not have to be recomputed.
+ FormContext formContext = { formData.releaseRef(), length };
+
+ CFReadStreamRef stream = wkCreateCustomCFReadStream(formCreate, formFinalize,
+ formOpen, formRead, formCanRead, formClose, formSchedule, formUnschedule,
+ &formContext);
+ [request setHTTPBodyStream:(NSInputStream *)stream];
+ CFRelease(stream);
+}
+
+FormData* httpBodyFromStream(NSInputStream* stream)
+{
+ return getStreamFormDataMap().get((CFReadStreamRef)stream).get();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/mac/NetworkStateNotifierMac.cpp b/WebCore/platform/network/mac/NetworkStateNotifierMac.cpp
new file mode 100644
index 0000000..6e0b70d
--- /dev/null
+++ b/WebCore/platform/network/mac/NetworkStateNotifierMac.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * 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"
+#include "NetworkStateNotifier.h"
+
+#include <SystemConfiguration/SystemConfiguration.h>
+
+namespace WebCore {
+
+static const double StateChangeTimerInterval = 2.0;
+
+void NetworkStateNotifier::updateState()
+{
+ // Assume that we're offline until proven otherwise.
+ m_isOnLine = false;
+
+ RetainPtr<CFStringRef> str(AdoptCF, SCDynamicStoreKeyCreateNetworkInterface(0, kSCDynamicStoreDomainState));
+
+ RetainPtr<CFPropertyListRef> propertyList(AdoptCF, SCDynamicStoreCopyValue(m_store.get(), str.get()));
+
+ if (!propertyList)
+ return;
+
+ if (CFGetTypeID(propertyList.get()) != CFDictionaryGetTypeID())
+ return;
+
+ CFArrayRef netInterfaces = (CFArrayRef)CFDictionaryGetValue((CFDictionaryRef)propertyList.get(), kSCDynamicStorePropNetInterfaces);
+ if (CFGetTypeID(netInterfaces) != CFArrayGetTypeID())
+ return;
+
+ for (CFIndex i = 0; i < CFArrayGetCount(netInterfaces); i++) {
+ CFStringRef interface = (CFStringRef)CFArrayGetValueAtIndex(netInterfaces, i);
+ if (CFGetTypeID(interface) != CFStringGetTypeID())
+ continue;
+
+ // Ignore the loopback interface.
+ if (CFStringFind(interface, CFSTR("lo"), kCFCompareAnchored).location != kCFNotFound)
+ continue;
+
+ RetainPtr<CFStringRef> key(AdoptCF, SCDynamicStoreKeyCreateNetworkInterfaceEntity(0, kSCDynamicStoreDomainState, interface, kSCEntNetIPv4));
+
+ RetainPtr<CFArrayRef> keyList(AdoptCF, SCDynamicStoreCopyKeyList(m_store.get(), key.get()));
+
+ if (keyList && CFArrayGetCount(keyList.get())) {
+ m_isOnLine = true;
+ break;
+ }
+ }
+}
+
+void NetworkStateNotifier::dynamicStoreCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
+{
+ NetworkStateNotifier* notifier = static_cast<NetworkStateNotifier*>(info);
+
+ // Calling updateState() could be expensive so we schedule a timer that will do it
+ // when things have cooled down.
+ notifier->m_networkStateChangeTimer.startOneShot(StateChangeTimerInterval);
+}
+
+void NetworkStateNotifier::networkStateChangeTimerFired(Timer<NetworkStateNotifier>*)
+{
+ bool oldOnLine = m_isOnLine;
+
+ updateState();
+
+ if (m_isOnLine == oldOnLine)
+ return;
+
+ if (m_networkStateChangedFunction)
+ m_networkStateChangedFunction();
+}
+
+NetworkStateNotifier::NetworkStateNotifier()
+ : m_isOnLine(false)
+ , m_networkStateChangeTimer(this, &NetworkStateNotifier::networkStateChangeTimerFired)
+{
+ SCDynamicStoreContext context = { 0, this, 0, 0, 0 };
+
+ m_store.adoptCF(SCDynamicStoreCreate(0, CFSTR("com.apple.WebCore"), dynamicStoreCallback, &context));
+ if (!m_store)
+ return;
+
+ RetainPtr<CFRunLoopSourceRef> configSource = SCDynamicStoreCreateRunLoopSource(0, m_store.get(), 0);
+ if (!configSource)
+ return;
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), configSource.get(), kCFRunLoopCommonModes);
+
+ RetainPtr<CFMutableArrayRef> keys(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks));
+ RetainPtr<CFMutableArrayRef> patterns(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks));
+
+ RetainPtr<CFStringRef> key;
+ RetainPtr<CFStringRef> pattern;
+
+ key.adoptCF(SCDynamicStoreKeyCreateNetworkGlobalEntity(0, kSCDynamicStoreDomainState, kSCEntNetIPv4));
+ CFArrayAppendValue(keys.get(), key.get());
+
+ pattern.adoptCF(SCDynamicStoreKeyCreateNetworkInterfaceEntity(0, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4));
+ CFArrayAppendValue(patterns.get(), pattern.get());
+
+ key.adoptCF(SCDynamicStoreKeyCreateNetworkGlobalEntity(0, kSCDynamicStoreDomainState, kSCEntNetDNS));
+ CFArrayAppendValue(keys.get(), key.get());
+
+ SCDynamicStoreSetNotificationKeys(m_store.get(), keys.get(), patterns.get());
+
+ updateState();
+}
+
+}
diff --git a/WebCore/platform/network/mac/ResourceError.h b/WebCore/platform/network/mac/ResourceError.h
new file mode 100644
index 0000000..2f779c9
--- /dev/null
+++ b/WebCore/platform/network/mac/ResourceError.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceError_h
+#define ResourceError_h
+
+#include "ResourceErrorBase.h"
+#include <wtf/RetainPtr.h>
+
+#ifdef __OBJC__
+@class NSError;
+#else
+class NSError;
+#endif
+
+namespace WebCore {
+
+ class ResourceError : public ResourceErrorBase {
+ public:
+ ResourceError()
+ : m_dataIsUpToDate(true)
+ {
+ }
+
+ ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription)
+ : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription)
+ , m_dataIsUpToDate(true)
+ {
+ }
+
+ ResourceError(NSError* error)
+ : m_dataIsUpToDate(false)
+ , m_platformError(error)
+ {
+ m_isNull = !error;
+ }
+
+ operator NSError*() const;
+
+ private:
+ friend class ResourceErrorBase;
+
+ void platformLazyInit();
+ static bool platformCompare(const ResourceError& a, const ResourceError& b);
+
+ bool m_dataIsUpToDate;
+ mutable RetainPtr<NSError> m_platformError;
+};
+
+} // namespace WebCore
+
+#endif // ResourceError_h_
diff --git a/WebCore/platform/network/mac/ResourceErrorMac.mm b/WebCore/platform/network/mac/ResourceErrorMac.mm
new file mode 100644
index 0000000..e59eadd
--- /dev/null
+++ b/WebCore/platform/network/mac/ResourceErrorMac.mm
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#import "config.h"
+#import "ResourceError.h"
+
+#import "KURL.h"
+#import <Foundation/Foundation.h>
+
+@interface NSError (WebExtras)
+- (NSString *)_web_localizedDescription;
+@end
+
+namespace WebCore {
+
+void ResourceError::platformLazyInit()
+{
+ if (m_dataIsUpToDate)
+ return;
+
+ m_domain = [m_platformError.get() domain];
+ m_errorCode = [m_platformError.get() code];
+
+ NSString* failingURLString = [[m_platformError.get() userInfo] valueForKey:@"NSErrorFailingURLStringKey"];
+ if (!failingURLString)
+ failingURLString = [[[m_platformError.get() userInfo] valueForKey:@"NSErrorFailingURLKey"] absoluteString];
+
+ m_localizedDescription = [m_platformError.get() _web_localizedDescription];
+
+ m_dataIsUpToDate = true;
+}
+
+bool ResourceError::platformCompare(const ResourceError& a, const ResourceError& b)
+{
+ return (NSError*)a == (NSError*)b;
+}
+
+ResourceError::operator NSError*() const
+{
+ if (m_isNull) {
+ ASSERT(!m_platformError);
+ return nil;
+ }
+
+ if (!m_platformError) {
+ RetainPtr<NSMutableDictionary> userInfo(AdoptNS, [[NSMutableDictionary alloc] init]);
+
+ if (!m_localizedDescription.isEmpty())
+ [userInfo.get() setValue:m_localizedDescription forKey:NSLocalizedDescriptionKey];
+
+ if (!m_failingURL.isEmpty()) {
+ NSURL *cocoaURL = KURL(m_failingURL);
+ [userInfo.get() setValue:m_failingURL forKey:@"NSErrorFailingURLStringKey"];
+ [userInfo.get() setValue:cocoaURL forKey:@"NSErrorFailingURLKey"];
+ }
+
+ m_platformError.adoptNS([[NSError alloc] initWithDomain:m_domain code:m_errorCode userInfo:userInfo.get()]);
+ }
+
+ return m_platformError.get();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/mac/ResourceHandleMac.mm b/WebCore/platform/network/mac/ResourceHandleMac.mm
new file mode 100644
index 0000000..b4c5ddf
--- /dev/null
+++ b/WebCore/platform/network/mac/ResourceHandleMac.mm
@@ -0,0 +1,779 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#import "config.h"
+#import "ResourceHandle.h"
+#import "ResourceHandleInternal.h"
+
+#import "AuthenticationChallenge.h"
+#import "AuthenticationMac.h"
+#import "BlockExceptions.h"
+#import "DocLoader.h"
+#import "FormDataStreamMac.h"
+#import "Frame.h"
+#import "FrameLoader.h"
+#import "Page.h"
+#import "ResourceError.h"
+#import "ResourceResponse.h"
+#import "SchedulePair.h"
+#import "SharedBuffer.h"
+#import "SubresourceLoader.h"
+#import "WebCoreSystemInterface.h"
+
+#ifdef BUILDING_ON_TIGER
+typedef int NSInteger;
+#endif
+
+using namespace WebCore;
+
+@interface WebCoreResourceHandleAsDelegate : NSObject <NSURLAuthenticationChallengeSender>
+{
+ ResourceHandle* m_handle;
+#ifndef BUILDING_ON_TIGER
+ NSURL *m_url;
+#endif
+}
+- (id)initWithHandle:(ResourceHandle*)handle;
+- (void)detachHandle;
+@end
+
+@interface NSURLConnection (NSURLConnectionTigerPrivate)
+- (NSData *)_bufferedData;
+@end
+
+#ifndef BUILDING_ON_TIGER
+@interface WebCoreSynchronousLoader : NSObject {
+ NSURL *m_url;
+ NSURLResponse *m_response;
+ NSMutableData *m_data;
+ NSError *m_error;
+ BOOL m_isDone;
+}
++ (NSData *)loadRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;
+@end
+
+static NSString *WebCoreSynchronousLoaderRunLoopMode = @"WebCoreSynchronousLoaderRunLoopMode";
+#endif
+
+namespace WebCore {
+
+#ifdef BUILDING_ON_TIGER
+static unsigned inNSURLConnectionCallback;
+#endif
+
+#ifndef NDEBUG
+static bool isInitializingConnection;
+#endif
+
+class CallbackGuard {
+public:
+ CallbackGuard()
+ {
+#ifdef BUILDING_ON_TIGER
+ ++inNSURLConnectionCallback;
+#endif
+ }
+ ~CallbackGuard()
+ {
+#ifdef BUILDING_ON_TIGER
+ ASSERT(inNSURLConnectionCallback > 0);
+ --inNSURLConnectionCallback;
+#endif
+ }
+};
+
+ResourceHandleInternal::~ResourceHandleInternal()
+{
+}
+
+ResourceHandle::~ResourceHandle()
+{
+ releaseDelegate();
+}
+
+static const double MaxFoundationVersionWithoutdidSendBodyDataDelegate = 677.21;
+bool ResourceHandle::didSendBodyDataDelegateExists()
+{
+// FIXME: Refine this check as the delegate becomes more widely available.
+#ifdef BUILDING_ON_LEOPARD
+ return NSFoundationVersionNumber > MaxFoundationVersionWithoutdidSendBodyDataDelegate;
+#else
+ return false;
+#endif
+}
+
+bool ResourceHandle::start(Frame* frame)
+{
+ if (!frame)
+ return false;
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+ // If we are no longer attached to a Page, this must be an attempted load from an
+ // onUnload handler, so let's just block it.
+ Page* page = frame->page();
+ if (!page)
+ return false;
+
+#ifndef NDEBUG
+ isInitializingConnection = YES;
+#endif
+ id delegate;
+
+ if (d->m_mightDownloadFromHandle) {
+ ASSERT(!d->m_proxy);
+ d->m_proxy = wkCreateNSURLConnectionDelegateProxy();
+ [d->m_proxy.get() setDelegate:ResourceHandle::delegate()];
+ [d->m_proxy.get() release];
+
+ delegate = d->m_proxy.get();
+ } else
+ delegate = ResourceHandle::delegate();
+
+ if (!ResourceHandle::didSendBodyDataDelegateExists())
+ associateStreamWithResourceHandle([d->m_request.nsURLRequest() HTTPBodyStream], this);
+
+ NSURLConnection *connection;
+
+ if (d->m_shouldContentSniff)
+#ifdef BUILDING_ON_TIGER
+ connection = [[NSURLConnection alloc] initWithRequest:d->m_request.nsURLRequest() delegate:delegate];
+#else
+ connection = [[NSURLConnection alloc] initWithRequest:d->m_request.nsURLRequest() delegate:delegate startImmediately:NO];
+#endif
+ else {
+ NSMutableURLRequest *request = [d->m_request.nsURLRequest() mutableCopy];
+ wkSetNSURLRequestShouldContentSniff(request, NO);
+#ifdef BUILDING_ON_TIGER
+ connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegate];
+#else
+ connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegate startImmediately:NO];
+#endif
+ [request release];
+ }
+
+#ifndef BUILDING_ON_TIGER
+ bool scheduled = false;
+ if (SchedulePairHashSet* scheduledPairs = page->scheduledRunLoopPairs()) {
+ SchedulePairHashSet::iterator end = scheduledPairs->end();
+ for (SchedulePairHashSet::iterator it = scheduledPairs->begin(); it != end; ++it) {
+ if (NSRunLoop *runLoop = (*it)->nsRunLoop()) {
+ [connection scheduleInRunLoop:runLoop forMode:(NSString *)(*it)->mode()];
+ scheduled = true;
+ }
+ }
+ }
+
+ // Start the connection if we did schedule with at least one runloop.
+ // We can't start the connection until we have one runloop scheduled.
+ if (scheduled)
+ [connection start];
+ else
+ d->m_startWhenScheduled = true;
+#endif
+
+#ifndef NDEBUG
+ isInitializingConnection = NO;
+#endif
+
+ d->m_connection = connection;
+
+ if (d->m_connection) {
+ [connection release];
+
+ if (d->m_defersLoading)
+ wkSetNSURLConnectionDefersCallbacks(d->m_connection.get(), YES);
+
+ return true;
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS;
+
+ return false;
+}
+
+void ResourceHandle::cancel()
+{
+ if (!ResourceHandle::didSendBodyDataDelegateExists())
+ disassociateStreamWithResourceHandle([d->m_request.nsURLRequest() HTTPBodyStream]);
+ [d->m_connection.get() cancel];
+}
+
+void ResourceHandle::setDefersLoading(bool defers)
+{
+ d->m_defersLoading = defers;
+ if (d->m_connection)
+ wkSetNSURLConnectionDefersCallbacks(d->m_connection.get(), defers);
+}
+
+void ResourceHandle::schedule(SchedulePair* pair)
+{
+#ifndef BUILDING_ON_TIGER
+ NSRunLoop *runLoop = pair->nsRunLoop();
+ if (!runLoop)
+ return;
+ [d->m_connection.get() scheduleInRunLoop:runLoop forMode:(NSString *)pair->mode()];
+ if (d->m_startWhenScheduled) {
+ [d->m_connection.get() start];
+ d->m_startWhenScheduled = false;
+ }
+#endif
+}
+
+void ResourceHandle::unschedule(SchedulePair* pair)
+{
+#ifndef BUILDING_ON_TIGER
+ if (NSRunLoop *runLoop = pair->nsRunLoop())
+ [d->m_connection.get() unscheduleFromRunLoop:runLoop forMode:(NSString *)pair->mode()];
+#endif
+}
+
+WebCoreResourceHandleAsDelegate *ResourceHandle::delegate()
+{
+ if (!d->m_delegate) {
+ WebCoreResourceHandleAsDelegate *delegate = [[WebCoreResourceHandleAsDelegate alloc] initWithHandle:this];
+ d->m_delegate = delegate;
+ [delegate release];
+ }
+ return d->m_delegate.get();
+}
+
+void ResourceHandle::releaseDelegate()
+{
+ if (!d->m_delegate)
+ return;
+ if (d->m_proxy)
+ [d->m_proxy.get() setDelegate:nil];
+ [d->m_delegate.get() detachHandle];
+ d->m_delegate = nil;
+}
+
+bool ResourceHandle::supportsBufferedData()
+{
+ static bool supportsBufferedData = [NSURLConnection instancesRespondToSelector:@selector(_bufferedData)];
+ return supportsBufferedData;
+}
+
+PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
+{
+ if (ResourceHandle::supportsBufferedData())
+ return SharedBuffer::wrapNSData([d->m_connection.get() _bufferedData]);
+
+ return 0;
+}
+
+id ResourceHandle::releaseProxy()
+{
+ id proxy = [[d->m_proxy.get() retain] autorelease];
+ d->m_proxy = nil;
+ [proxy setDelegate:nil];
+ return proxy;
+}
+
+NSURLConnection *ResourceHandle::connection() const
+{
+ return d->m_connection.get();
+}
+
+bool ResourceHandle::loadsBlocked()
+{
+#ifndef BUILDING_ON_TIGER
+ return false;
+#else
+ // On Tiger, if we're in an NSURLConnection callback, that blocks all other NSURLConnection callbacks.
+ // On Leopard and newer, it blocks only callbacks on that same NSURLConnection object, which is not
+ // a problem in practice.
+ return inNSURLConnectionCallback != 0;
+#endif
+}
+
+bool ResourceHandle::willLoadFromCache(ResourceRequest& request)
+{
+ request.setCachePolicy(ReturnCacheDataDontLoad);
+ NSURLResponse *nsURLResponse = nil;
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+ [NSURLConnection sendSynchronousRequest:request.nsURLRequest() returningResponse:&nsURLResponse error:nil];
+
+ END_BLOCK_OBJC_EXCEPTIONS;
+
+ return nsURLResponse;
+}
+
+void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame*)
+{
+ NSError *nsError = nil;
+
+ NSURLResponse *nsURLResponse = nil;
+ NSData *result = nil;
+
+ ASSERT(!request.isEmpty());
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+#ifndef BUILDING_ON_TIGER
+ result = [WebCoreSynchronousLoader loadRequest:request.nsURLRequest() returningResponse:&nsURLResponse error:&nsError];
+#else
+ result = [NSURLConnection sendSynchronousRequest:request.nsURLRequest() returningResponse:&nsURLResponse error:&nsError];
+#endif
+ END_BLOCK_OBJC_EXCEPTIONS;
+
+ if (nsError == nil)
+ response = nsURLResponse;
+ else {
+ response = ResourceResponse(request.url(), String(), 0, String(), String());
+ if ([nsError domain] == NSURLErrorDomain)
+ switch ([nsError code]) {
+ case NSURLErrorUserCancelledAuthentication:
+ // FIXME: we should really return the actual HTTP response, but sendSynchronousRequest doesn't provide us with one.
+ response.setHTTPStatusCode(401);
+ break;
+ default:
+ response.setHTTPStatusCode([nsError code]);
+ }
+ else
+ response.setHTTPStatusCode(404);
+ }
+
+ data.resize([result length]);
+ memcpy(data.data(), [result bytes], [result length]);
+
+ error = nsError;
+}
+
+void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge)
+{
+ ASSERT(!d->m_currentMacChallenge);
+ ASSERT(d->m_currentWebChallenge.isNull());
+ // Since NSURLConnection networking relies on keeping a reference to the original NSURLAuthenticationChallenge,
+ // we make sure that is actually present
+ ASSERT(challenge.nsURLAuthenticationChallenge());
+
+ d->m_currentMacChallenge = challenge.nsURLAuthenticationChallenge();
+ NSURLAuthenticationChallenge *webChallenge = [[NSURLAuthenticationChallenge alloc] initWithAuthenticationChallenge:d->m_currentMacChallenge
+ sender:(id<NSURLAuthenticationChallengeSender>)delegate()];
+ d->m_currentWebChallenge = core(webChallenge);
+ [webChallenge release];
+
+ if (client())
+ client()->didReceiveAuthenticationChallenge(this, d->m_currentWebChallenge);
+}
+
+void ResourceHandle::didCancelAuthenticationChallenge(const AuthenticationChallenge& challenge)
+{
+ ASSERT(d->m_currentMacChallenge);
+ ASSERT(!d->m_currentWebChallenge.isNull());
+ ASSERT(d->m_currentWebChallenge == challenge);
+
+ if (client())
+ client()->didCancelAuthenticationChallenge(this, d->m_currentWebChallenge);
+}
+
+void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge, const Credential& credential)
+{
+ ASSERT(!challenge.isNull());
+ if (challenge != d->m_currentWebChallenge)
+ return;
+
+ [[d->m_currentMacChallenge sender] useCredential:mac(credential) forAuthenticationChallenge:d->m_currentMacChallenge];
+
+ clearAuthentication();
+}
+
+void ResourceHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& challenge)
+{
+ ASSERT(!challenge.isNull());
+ if (challenge != d->m_currentWebChallenge)
+ return;
+
+ [[d->m_currentMacChallenge sender] continueWithoutCredentialForAuthenticationChallenge:d->m_currentMacChallenge];
+
+ clearAuthentication();
+}
+
+void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challenge)
+{
+ if (challenge != d->m_currentWebChallenge)
+ return;
+
+ if (client())
+ client()->receivedCancellation(this, challenge);
+}
+
+} // namespace WebCore
+
+@implementation WebCoreResourceHandleAsDelegate
+
+- (id)initWithHandle:(ResourceHandle*)handle
+{
+ self = [self init];
+ if (!self)
+ return nil;
+ m_handle = handle;
+ return self;
+}
+
+#ifndef BUILDING_ON_TIGER
+- (void)dealloc
+{
+ [m_url release];
+ [super dealloc];
+}
+#endif
+
+- (void)detachHandle
+{
+ m_handle = 0;
+}
+
+- (NSURLRequest *)connection:(NSURLConnection *)con willSendRequest:(NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse
+{
+ // the willSendRequest call may cancel this load, in which case self could be deallocated
+ RetainPtr<WebCoreResourceHandleAsDelegate> protect(self);
+
+ if (!m_handle || !m_handle->client())
+ return nil;
+
+ // See <rdar://problem/5380697> . This is a workaround for a behavior change in CFNetwork where willSendRequest gets called more often.
+ if (!redirectResponse)
+ return newRequest;
+
+ CallbackGuard guard;
+ ResourceRequest request = newRequest;
+ m_handle->client()->willSendRequest(m_handle, request, redirectResponse);
+#ifndef BUILDING_ON_TIGER
+ NSURL *copy = [[request.nsURLRequest() URL] copy];
+ [m_url release];
+ m_url = copy;
+#endif
+
+ if (!ResourceHandle::didSendBodyDataDelegateExists()) {
+ // The client may change the request's body stream, in which case we have to re-associate
+ // the handle with the new stream so upload progress callbacks continue to work correctly.
+ NSInputStream* oldBodyStream = [newRequest HTTPBodyStream];
+ NSInputStream* newBodyStream = [request.nsURLRequest() HTTPBodyStream];
+ if (oldBodyStream != newBodyStream) {
+ disassociateStreamWithResourceHandle(oldBodyStream);
+ associateStreamWithResourceHandle(newBodyStream, m_handle);
+ }
+ }
+
+ return request.nsURLRequest();
+}
+
+- (void)connection:(NSURLConnection *)con didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+{
+#ifndef BUILDING_ON_TIGER
+ if ([challenge previousFailureCount] == 0) {
+ NSString *user = [m_url user];
+ NSString *password = [m_url password];
+
+ if (user && password) {
+ NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:user
+ password:password
+ persistence:NSURLCredentialPersistenceForSession];
+ [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
+ [credential release];
+ return;
+ }
+ }
+#endif
+
+ if (!m_handle)
+ return;
+ CallbackGuard guard;
+ m_handle->didReceiveAuthenticationChallenge(core(challenge));
+}
+
+- (void)connection:(NSURLConnection *)con didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+{
+ if (!m_handle)
+ return;
+ CallbackGuard guard;
+ m_handle->didCancelAuthenticationChallenge(core(challenge));
+}
+
+- (void)connection:(NSURLConnection *)con didReceiveResponse:(NSURLResponse *)r
+{
+ if (!m_handle || !m_handle->client())
+ return;
+ CallbackGuard guard;
+ m_handle->client()->didReceiveResponse(m_handle, r);
+}
+
+- (void)connection:(NSURLConnection *)con didReceiveData:(NSData *)data lengthReceived:(long long)lengthReceived
+{
+ if (!m_handle || !m_handle->client())
+ return;
+ // FIXME: If we get more than 2B bytes in a single chunk, this code won't do the right thing.
+ // However, with today's computers and networking speeds, this won't happen in practice.
+ // Could be an issue with a giant local file.
+ CallbackGuard guard;
+ m_handle->client()->didReceiveData(m_handle, (const char*)[data bytes], [data length], static_cast<int>(lengthReceived));
+}
+
+- (void)connection:(NSURLConnection *)con willStopBufferingData:(NSData *)data
+{
+ if (!m_handle || !m_handle->client())
+ return;
+ // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
+ // However, with today's computers and networking speeds, this won't happen in practice.
+ // Could be an issue with a giant local file.
+ CallbackGuard guard;
+ m_handle->client()->willStopBufferingData(m_handle, (const char*)[data bytes], static_cast<int>([data length]));
+}
+
+- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
+{
+ if (!m_handle || !m_handle->client())
+ return;
+ CallbackGuard guard;
+ m_handle->client()->didSendData(m_handle, totalBytesWritten, totalBytesExpectedToWrite);
+}
+
+- (void)connectionDidFinishLoading:(NSURLConnection *)con
+{
+ if (!m_handle || !m_handle->client())
+ return;
+ CallbackGuard guard;
+
+ if (!ResourceHandle::didSendBodyDataDelegateExists())
+ disassociateStreamWithResourceHandle([m_handle->request().nsURLRequest() HTTPBodyStream]);
+
+ m_handle->client()->didFinishLoading(m_handle);
+}
+
+- (void)connection:(NSURLConnection *)con didFailWithError:(NSError *)error
+{
+ if (!m_handle || !m_handle->client())
+ return;
+ CallbackGuard guard;
+
+ if (!ResourceHandle::didSendBodyDataDelegateExists())
+ disassociateStreamWithResourceHandle([m_handle->request().nsURLRequest() HTTPBodyStream]);
+
+ m_handle->client()->didFail(m_handle, error);
+}
+
+#ifdef BUILDING_ON_TIGER
+- (void)_callConnectionWillCacheResponseWithInfo:(NSMutableDictionary *)info
+{
+ NSURLConnection *connection = [info objectForKey:@"connection"];
+ NSCachedURLResponse *cachedResponse = [info objectForKey:@"cachedResponse"];
+ NSCachedURLResponse *result = [self connection:connection willCacheResponse:cachedResponse];
+ if (result)
+ [info setObject:result forKey:@"result"];
+}
+#endif
+
+- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
+{
+#ifdef BUILDING_ON_TIGER
+ // On Tiger CFURLConnection can sometimes call the connection:willCacheResponse: delegate method on
+ // a secondary thread instead of the main thread. If this happens perform the work on the main thread.
+ if (!pthread_main_np()) {
+ NSMutableDictionary *info = [[NSMutableDictionary alloc] init];
+ if (connection)
+ [info setObject:connection forKey:@"connection"];
+ if (cachedResponse)
+ [info setObject:cachedResponse forKey:@"cachedResponse"];
+
+ // Include synchronous url connection's mode as an acceptable run loopmode
+ // <rdar://problem/5511842>
+ NSArray *modes = [[NSArray alloc] initWithObjects:(NSString *)kCFRunLoopCommonModes, @"NSSynchronousURLConnection_PrivateMode", nil];
+ [self performSelectorOnMainThread:@selector(_callConnectionWillCacheResponseWithInfo:) withObject:info waitUntilDone:YES modes:modes];
+ [modes release];
+
+ NSCachedURLResponse *result = [[info valueForKey:@"result"] retain];
+ [info release];
+
+ return [result autorelease];
+ }
+#endif
+
+#ifndef NDEBUG
+ if (isInitializingConnection)
+ LOG_ERROR("connection:willCacheResponse: was called inside of [NSURLConnection initWithRequest:delegate:] (4067625)");
+#endif
+ if (!m_handle || !m_handle->client())
+ return nil;
+
+ CallbackGuard guard;
+
+ NSCachedURLResponse *newResponse = m_handle->client()->willCacheResponse(m_handle, cachedResponse);
+ if (newResponse != cachedResponse)
+ return newResponse;
+
+ CacheStoragePolicy policy = static_cast<CacheStoragePolicy>([newResponse storagePolicy]);
+
+ m_handle->client()->willCacheResponse(m_handle, policy);
+
+ if (static_cast<NSURLCacheStoragePolicy>(policy) != [newResponse storagePolicy])
+ newResponse = [[[NSCachedURLResponse alloc] initWithResponse:[newResponse response]
+ data:[newResponse data]
+ userInfo:[newResponse userInfo]
+ storagePolicy:static_cast<NSURLCacheStoragePolicy>(policy)] autorelease];
+
+ return newResponse;
+}
+
+- (void)useCredential:(NSURLCredential *)credential forAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+{
+ if (!m_handle)
+ return;
+ m_handle->receivedCredential(core(challenge), core(credential));
+}
+
+- (void)continueWithoutCredentialForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+{
+ if (!m_handle)
+ return;
+ m_handle->receivedRequestToContinueWithoutCredential(core(challenge));
+}
+
+- (void)cancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+{
+ if (!m_handle)
+ return;
+ m_handle->receivedCancellation(core(challenge));
+}
+
+@end
+
+#ifndef BUILDING_ON_TIGER
+@implementation WebCoreSynchronousLoader
+
+- (BOOL)_isDone
+{
+ return m_isDone;
+}
+
+- (void)dealloc
+{
+ [m_url release];
+ [m_response release];
+ [m_data release];
+ [m_error release];
+
+ [super dealloc];
+}
+
+- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse
+{
+ NSURL *copy = [[newRequest URL] copy];
+ [m_url release];
+ m_url = copy;
+
+ return newRequest;
+}
+
+- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+{
+ if ([challenge previousFailureCount] == 0) {
+ NSString *user = [m_url user];
+ NSString *password = [m_url password];
+
+ if (user && password) {
+ NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:user
+ password:password
+ persistence:NSURLCredentialPersistenceForSession];
+ [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
+ [credential release];
+ return;
+ }
+ }
+
+ [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
+}
+
+- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
+{
+ NSURLResponse *r = [response copy];
+
+ [m_response release];
+ m_response = r;
+}
+
+- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
+{
+ if (!m_data)
+ m_data = [[NSMutableData alloc] init];
+
+ [m_data appendData:data];
+}
+
+- (void)connectionDidFinishLoading:(NSURLConnection *)connection
+{
+ m_isDone = YES;
+}
+
+- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
+{
+ ASSERT(!m_error);
+
+ m_error = [error retain];
+ m_isDone = YES;
+}
+
+- (NSData *)_data
+{
+ return [[m_data retain] autorelease];
+}
+
+- (NSURLResponse *)_response
+{
+ return [[m_response retain] autorelease];
+}
+
+- (NSError *)_error
+{
+ return [[m_error retain] autorelease];
+}
+
++ (NSData *)loadRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
+{
+ WebCoreSynchronousLoader *delegate = [[WebCoreSynchronousLoader alloc] init];
+
+ NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegate startImmediately:NO];
+ [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:WebCoreSynchronousLoaderRunLoopMode];
+ [connection start];
+
+ while (![delegate _isDone])
+ [[NSRunLoop currentRunLoop] runMode:WebCoreSynchronousLoaderRunLoopMode beforeDate:[NSDate distantFuture]];
+
+ NSData *data = [delegate _data];
+ *response = [delegate _response];
+ *error = [delegate _error];
+
+ [connection cancel];
+
+ [connection release];
+ [delegate release];
+
+ return data;
+}
+
+@end
+#endif
diff --git a/WebCore/platform/network/mac/ResourceRequest.h b/WebCore/platform/network/mac/ResourceRequest.h
new file mode 100644
index 0000000..5bcb33e
--- /dev/null
+++ b/WebCore/platform/network/mac/ResourceRequest.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceRequest_h
+#define ResourceRequest_h
+
+#include "ResourceRequestBase.h"
+
+#include <wtf/RetainPtr.h>
+#ifdef __OBJC__
+@class NSURLRequest;
+#else
+class NSURLRequest;
+#endif
+
+namespace WebCore {
+
+ class ResourceRequest : public ResourceRequestBase {
+ public:
+ ResourceRequest(const String& url)
+ : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(const KURL& url)
+ : ResourceRequestBase(url, UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(const KURL& url, const String& referrer, ResourceRequestCachePolicy policy = UseProtocolCachePolicy)
+ : ResourceRequestBase(url, policy)
+ {
+ setHTTPReferrer(referrer);
+ }
+
+ ResourceRequest()
+ : ResourceRequestBase(KURL(), UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(NSURLRequest* nsRequest)
+ : ResourceRequestBase()
+ , m_nsRequest(nsRequest) { }
+
+ void applyWebArchiveHackForMail();
+ NSURLRequest* nsURLRequest() const;
+
+ private:
+ friend class ResourceRequestBase;
+
+ void doUpdatePlatformRequest();
+ void doUpdateResourceRequest();
+
+ RetainPtr<NSURLRequest> m_nsRequest;
+ };
+
+} // namespace WebCore
+
+#endif // ResourceRequest_h
diff --git a/WebCore/platform/network/mac/ResourceRequestMac.mm b/WebCore/platform/network/mac/ResourceRequestMac.mm
new file mode 100644
index 0000000..63fffe1
--- /dev/null
+++ b/WebCore/platform/network/mac/ResourceRequestMac.mm
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#import "config.h"
+#import "ResourceRequest.h"
+#import "WebCoreSystemInterface.h"
+
+#import "FormDataStreamMac.h"
+
+#import <Foundation/Foundation.h>
+
+namespace WebCore {
+
+NSURLRequest* ResourceRequest::nsURLRequest() const
+{
+ updatePlatformRequest();
+
+ return [[m_nsRequest.get() retain] autorelease];
+}
+
+void ResourceRequest::doUpdateResourceRequest()
+{
+ m_url = [m_nsRequest.get() URL];
+ m_cachePolicy = (ResourceRequestCachePolicy)[m_nsRequest.get() cachePolicy];
+ m_timeoutInterval = [m_nsRequest.get() timeoutInterval];
+ m_mainDocumentURL = [m_nsRequest.get() mainDocumentURL];
+
+ if (NSString* method = [m_nsRequest.get() HTTPMethod])
+ m_httpMethod = method;
+ m_allowHTTPCookies = [m_nsRequest.get() HTTPShouldHandleCookies];
+
+ NSDictionary *headers = [m_nsRequest.get() allHTTPHeaderFields];
+ NSEnumerator *e = [headers keyEnumerator];
+ NSString *name;
+ while ((name = [e nextObject]))
+ m_httpHeaderFields.set(name, [headers objectForKey:name]);
+
+ if (NSData* bodyData = [m_nsRequest.get() HTTPBody])
+ m_httpBody = FormData::create([bodyData bytes], [bodyData length]);
+ else if (NSInputStream* bodyStream = [m_nsRequest.get() HTTPBodyStream])
+ if (FormData* formData = httpBodyFromStream(bodyStream))
+ m_httpBody = formData;
+}
+
+void ResourceRequest::doUpdatePlatformRequest()
+{
+ if (isNull()) {
+ m_nsRequest = nil;
+ return;
+ }
+
+ NSMutableURLRequest* nsRequest = [m_nsRequest.get() mutableCopy];
+
+ if (nsRequest)
+ [nsRequest setURL:url()];
+ else
+ nsRequest = [[NSMutableURLRequest alloc] initWithURL:url()];
+
+#ifdef BUILDING_ON_TIGER
+ wkSupportsMultipartXMixedReplace(nsRequest);
+#endif
+
+ [nsRequest setCachePolicy:(NSURLRequestCachePolicy)cachePolicy()];
+ if (timeoutInterval() != unspecifiedTimeoutInterval)
+ [nsRequest setTimeoutInterval:timeoutInterval()];
+ [nsRequest setMainDocumentURL:mainDocumentURL()];
+ if (!httpMethod().isEmpty())
+ [nsRequest setHTTPMethod:httpMethod()];
+ [nsRequest setHTTPShouldHandleCookies:allowHTTPCookies()];
+
+ HTTPHeaderMap::const_iterator end = httpHeaderFields().end();
+ for (HTTPHeaderMap::const_iterator it = httpHeaderFields().begin(); it != end; ++it)
+ [nsRequest setValue:it->second forHTTPHeaderField:it->first];
+
+ RefPtr<FormData> formData = httpBody();
+ if (formData && !formData->isEmpty())
+ WebCore::setHTTPBody(nsRequest, formData);
+
+ m_nsRequest.adoptNS(nsRequest);
+}
+
+void ResourceRequest::applyWebArchiveHackForMail()
+{
+ // Hack because Mail checks for this property to detect data / archive loads
+ [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)nsURLRequest()];
+}
+
+}
diff --git a/WebCore/platform/network/mac/ResourceResponse.h b/WebCore/platform/network/mac/ResourceResponse.h
new file mode 100644
index 0000000..b65760c
--- /dev/null
+++ b/WebCore/platform/network/mac/ResourceResponse.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceResponse_h
+#define ResourceResponse_h
+
+#include "ResourceResponseBase.h"
+#include <wtf/RetainPtr.h>
+
+#ifdef __OBJC__
+@class NSURLResponse;
+#else
+class NSURLResponse;
+#endif
+
+namespace WebCore {
+
+class ResourceResponse : public ResourceResponseBase {
+public:
+ ResourceResponse()
+ : m_isUpToDate(true)
+ {
+ }
+
+ ResourceResponse(NSURLResponse* nsResponse)
+ : m_nsResponse(nsResponse)
+ , m_isUpToDate(false)
+ {
+ m_isNull = !nsResponse;
+ }
+
+ ResourceResponse(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename)
+ : ResourceResponseBase(url, mimeType, expectedLength, textEncodingName, filename)
+ , m_isUpToDate(true)
+ {
+ }
+
+ NSURLResponse *nsURLResponse() const;
+
+private:
+ friend class ResourceResponseBase;
+
+ void platformLazyInit();
+ static bool platformCompare(const ResourceResponse& a, const ResourceResponse& b);
+
+ RetainPtr<NSURLResponse> m_nsResponse;
+ bool m_isUpToDate;
+};
+
+} // namespace WebCore
+
+#endif // ResourceResponse_h
diff --git a/WebCore/platform/network/mac/ResourceResponseMac.mm b/WebCore/platform/network/mac/ResourceResponseMac.mm
new file mode 100644
index 0000000..f60b496
--- /dev/null
+++ b/WebCore/platform/network/mac/ResourceResponseMac.mm
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#import "config.h"
+#import "ResourceResponse.h"
+
+#import "WebCoreURLResponse.h"
+#import <Foundation/Foundation.h>
+#import <limits>
+
+@interface NSURLResponse (FoundationSecretsWebCoreKnowsAbout)
+- (NSTimeInterval)_calculatedExpiration;
+@end
+
+#ifdef BUILDING_ON_TIGER
+typedef int NSInteger;
+#endif
+
+namespace WebCore {
+
+NSURLResponse *ResourceResponse::nsURLResponse() const
+{
+ if (!m_nsResponse && !m_isNull) {
+ // Work around a mistake in the NSURLResponse class.
+ // The init function takes an NSInteger, even though the accessor returns a long long.
+ // For values that won't fit in an NSInteger, pass -1 instead.
+ NSInteger expectedContentLength;
+ if (m_expectedContentLength < 0 || m_expectedContentLength > std::numeric_limits<NSInteger>::max())
+ expectedContentLength = -1;
+ else
+ expectedContentLength = static_cast<NSInteger>(m_expectedContentLength);
+ const_cast<ResourceResponse*>(this)->m_nsResponse.adoptNS([[NSURLResponse alloc] initWithURL:m_url MIMEType:m_mimeType expectedContentLength:expectedContentLength textEncodingName:m_textEncodingName]);
+ }
+ return m_nsResponse.get();
+}
+
+void ResourceResponse::platformLazyInit()
+{
+ if (m_isUpToDate)
+ return;
+ m_isUpToDate = true;
+
+ if (m_isNull) {
+ ASSERT(!m_nsResponse);
+ return;
+ }
+
+ m_url = [m_nsResponse.get() URL];
+ m_mimeType = [m_nsResponse.get() _webcore_MIMEType];
+ m_expectedContentLength = [m_nsResponse.get() expectedContentLength];
+ m_textEncodingName = [m_nsResponse.get() textEncodingName];
+ m_suggestedFilename = [m_nsResponse.get() suggestedFilename];
+
+ const time_t maxTime = std::numeric_limits<time_t>::max();
+
+ NSTimeInterval expiration = [m_nsResponse.get() _calculatedExpiration];
+ expiration += kCFAbsoluteTimeIntervalSince1970;
+ m_expirationDate = expiration > maxTime ? maxTime : static_cast<time_t>(expiration);
+
+ if ([m_nsResponse.get() isKindOfClass:[NSHTTPURLResponse class]]) {
+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)m_nsResponse.get();
+
+ m_httpStatusCode = [httpResponse statusCode];
+
+ // FIXME: it would be nice to have a way to get the real status text eventually.
+ m_httpStatusText = "OK";
+
+ NSDictionary *headers = [httpResponse allHeaderFields];
+ NSEnumerator *e = [headers keyEnumerator];
+ while (NSString *name = [e nextObject])
+ m_httpHeaderFields.set(name, [headers objectForKey:name]);
+ } else {
+ m_httpStatusCode = 0;
+
+#ifndef BUILDING_ON_TIGER
+ // FIXME: This is a work around for <rdar://problem/5230154> (-[NSURLConnection initWithRequest:delegate:]
+ // is returning incorrect MIME type for local .xhtml files) which is only required in Leopard.
+ if (m_url.isLocalFile() && m_mimeType == "text/html") {
+ const String& path = m_url.path();
+ static const String xhtmlExt(".xhtml");
+ if (path.endsWith(xhtmlExt, false))
+ m_mimeType = "application/xhtml+xml";
+ }
+#endif
+ }
+}
+
+bool ResourceResponse::platformCompare(const ResourceResponse& a, const ResourceResponse& b)
+{
+ return a.nsURLResponse() == b.nsURLResponse();
+}
+
+}
diff --git a/WebCore/platform/network/mac/WebCoreURLResponse.h b/WebCore/platform/network/mac/WebCoreURLResponse.h
new file mode 100644
index 0000000..a06ab70
--- /dev/null
+++ b/WebCore/platform/network/mac/WebCoreURLResponse.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+// FIXME: This is a workaround for <rdar://problem/5321972> REGRESSION: Plain text document from HTTP server detected
+// as application/octet-stream
+
+@interface NSURLResponse (WebCoreURLResponse)
+- (NSString *)_webcore_MIMEType;
+@end
diff --git a/WebCore/platform/network/mac/WebCoreURLResponse.mm b/WebCore/platform/network/mac/WebCoreURLResponse.mm
new file mode 100644
index 0000000..b8843af
--- /dev/null
+++ b/WebCore/platform/network/mac/WebCoreURLResponse.mm
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
+ */
+
+#import "config.h"
+
+#import "WebCoreURLResponse.h"
+
+#ifndef BUILDING_ON_TIGER
+static NSSet *createBinaryExtensionsSet()
+{
+ return [[NSSet alloc] initWithObjects:
+ @"3g2",
+ @"3gp",
+ @"ai",
+ @"aif",
+ @"aifc",
+ @"aiff",
+ @"au",
+ @"avi",
+ @"bcpio",
+ @"bin",
+ @"bmp",
+ @"boz",
+ @"bpk",
+ @"bz",
+ @"bz2",
+ @"chm",
+ @"class",
+ @"com",
+ @"cpio",
+ @"dcr",
+ @"dir",
+ @"dist",
+ @"distz",
+ @"dll",
+ @"dmg",
+ @"dms",
+ @"doc",
+ @"dot",
+ @"dump",
+ @"dv",
+ @"dvi",
+ @"dxr",
+ @"elc",
+ @"eot",
+ @"eps",
+ @"exe",
+ @"fgd",
+ @"gif",
+ @"gtar",
+ @"h261",
+ @"h263",
+ @"h264",
+ @"ico",
+ @"ims",
+ @"indd",
+ @"iso",
+ @"jp2",
+ @"jpe",
+ @"jpeg",
+ @"jpg",
+ @"jpgm",
+ @"jpgv",
+ @"jpm",
+ @"kar",
+ @"lha",
+ @"lrm",
+ @"lzh",
+ @"m1v",
+ @"m2a",
+ @"m2v",
+ @"m3a",
+ @"m3u",
+ @"m4a",
+ @"m4p",
+ @"m4v",
+ @"mdb",
+ @"mid",
+ @"midi",
+ @"mj2",
+ @"mjp2",
+ @"mov",
+ @"movie",
+ @"mp2",
+ @"mp2a",
+ @"mp3",
+ @"mp4",
+ @"mp4a",
+ @"mp4s",
+ @"mp4v",
+ @"mpe",
+ @"mpeg",
+ @"mpg",
+ @"mpg4",
+ @"mpga",
+ @"mpp",
+ @"mpt",
+ @"msi",
+ @"ogg",
+ @"otf",
+ @"pct",
+ @"pdf",
+ @"pfa",
+ @"pfb",
+ @"pic",
+ @"pict",
+ @"pkg",
+ @"png",
+ @"pot",
+ @"pps",
+ @"ppt",
+ @"ps",
+ @"psd",
+ @"qt",
+ @"qti",
+ @"qtif",
+ @"qwd",
+ @"qwt",
+ @"qxb",
+ @"qxd",
+ @"qxl",
+ @"qxp",
+ @"qxt",
+ @"ra",
+ @"ram",
+ @"rm",
+ @"rmi",
+ @"rmp",
+ @"scpt",
+ @"sit",
+ @"sitx",
+ @"snd",
+ @"so",
+ @"swf",
+ @"tar",
+ @"tif",
+ @"tiff",
+ @"ttf",
+ @"wav",
+ @"wcm",
+ @"wdb",
+ @"wks",
+ @"wm",
+ @"wma",
+ @"wmd",
+ @"wmf",
+ @"wmv",
+ @"wmx",
+ @"wmz",
+ @"wpd",
+ @"wpl",
+ @"wps",
+ @"wvx",
+ @"xla",
+ @"xlc",
+ @"xlm",
+ @"xls",
+ @"xlt",
+ @"xlw",
+ @"xps",
+ @"zip",
+ nil
+ ];
+}
+#endif
+
+@implementation NSURLResponse (WebCoreURLResponse)
+
+- (NSString *)_webcore_MIMEType
+{
+ NSString *MIMEType = [self MIMEType];
+#ifdef BUILDING_ON_LEOPARD
+ // Workaround for <rdar://problem/5539824>
+ if ([MIMEType isEqualToString:@"text/xml"])
+ return @"application/xml";
+#endif
+ return MIMEType;
+}
+
+@end
+
+@implementation NSHTTPURLResponse (WebCoreURLResponse)
+
+- (NSString *)_webcore_MIMEType
+{
+ NSString *MIMEType = [self MIMEType];
+#ifndef BUILDING_ON_TIGER
+ if ([MIMEType isEqualToString:@"application/octet-stream"] && [[[self allHeaderFields] objectForKey:@"Content-Type"] hasPrefix:@"text/plain"]) {
+ static NSSet *binaryExtensions = createBinaryExtensionsSet();
+ return [binaryExtensions containsObject:[[[self suggestedFilename] pathExtension] lowercaseString]] ? MIMEType : @"text/plain";
+ }
+#endif
+ return MIMEType;
+}
+
+@end
diff --git a/WebCore/platform/network/qt/AuthenticationChallenge.h b/WebCore/platform/network/qt/AuthenticationChallenge.h
new file mode 100644
index 0000000..753ac6f
--- /dev/null
+++ b/WebCore/platform/network/qt/AuthenticationChallenge.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef AuthenticationChallenge_h
+#define AuthenticationChallenge_h
+
+#include "AuthenticationChallengeBase.h"
+
+namespace WebCore {
+
+class AuthenticationChallenge : public AuthenticationChallengeBase {
+public:
+ AuthenticationChallenge()
+ {
+ }
+
+ AuthenticationChallenge(const ProtectionSpace& protectionSpace, const Credential& proposedCredential, unsigned previousFailureCount, const ResourceResponse& response, const ResourceError& error)
+ : AuthenticationChallengeBase(protectionSpace, proposedCredential, previousFailureCount, response, error)
+ {
+ }
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
new file mode 100644
index 0000000..2de2125
--- /dev/null
+++ b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -0,0 +1,435 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2007 Staikos Computing Services Inc. <info@staikos.net>
+ Copyright (C) 2008 Holger Hans Peter Freyther
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#include "config.h"
+#include "QNetworkReplyHandler.h"
+
+#if QT_VERSION >= 0x040400
+
+#include "HTTPParsers.h"
+#include "MIMETypeRegistry.h"
+#include "ResourceHandle.h"
+#include "ResourceHandleClient.h"
+#include "ResourceHandleInternal.h"
+#include "ResourceResponse.h"
+#include "ResourceRequest.h"
+#include <QDateTime>
+#include <QFile>
+#include <QNetworkReply>
+#include <QNetworkCookie>
+#include <qwebframe.h>
+#include <qwebpage.h>
+
+#include <QDebug>
+#include <QCoreApplication>
+
+namespace WebCore {
+
+// Take a deep copy of the FormDataElement
+FormDataIODevice::FormDataIODevice(FormData* data)
+ : m_formElements(data ? data->elements() : Vector<FormDataElement>())
+ , m_currentFile(0)
+ , m_currentDelta(0)
+{
+ setOpenMode(FormDataIODevice::ReadOnly);
+}
+
+FormDataIODevice::~FormDataIODevice()
+{
+ delete m_currentFile;
+}
+
+void FormDataIODevice::moveToNextElement()
+{
+ if (m_currentFile)
+ m_currentFile->close();
+ m_currentDelta = 0;
+
+ m_formElements.remove(0);
+
+ if (m_formElements.isEmpty() || m_formElements[0].m_type == FormDataElement::data)
+ return;
+
+ if (!m_currentFile)
+ m_currentFile = new QFile;
+
+ m_currentFile->setFileName(m_formElements[0].m_filename);
+ m_currentFile->open(QFile::ReadOnly);
+}
+
+// m_formElements[0] is the current item. If the destination buffer is
+// big enough we are going to read from more than one FormDataElement
+qint64 FormDataIODevice::readData(char* destination, qint64 size)
+{
+ if (m_formElements.isEmpty())
+ return -1;
+
+ qint64 copied = 0;
+ while (copied < size && !m_formElements.isEmpty()) {
+ const FormDataElement& element = m_formElements[0];
+ const qint64 available = size-copied;
+
+ if (element.m_type == FormDataElement::data) {
+ const qint64 toCopy = qMin<qint64>(available, element.m_data.size() - m_currentDelta);
+ memcpy(destination+copied, element.m_data.data()+m_currentDelta, toCopy);
+ m_currentDelta += toCopy;
+ copied += toCopy;
+
+ if (m_currentDelta == element.m_data.size())
+ moveToNextElement();
+ } else {
+ const QByteArray data = m_currentFile->read(available);
+ memcpy(destination+copied, data.constData(), data.size());
+ copied += data.size();
+
+ if (m_currentFile->atEnd() || !m_currentFile->isOpen())
+ moveToNextElement();
+ }
+ }
+
+ return copied;
+}
+
+qint64 FormDataIODevice::writeData(const char*, qint64)
+{
+ return -1;
+}
+
+void FormDataIODevice::setParent(QNetworkReply* reply)
+{
+ QIODevice::setParent(reply);
+
+ connect(reply, SIGNAL(finished()), SLOT(slotFinished()), Qt::QueuedConnection);
+}
+
+bool FormDataIODevice::isSequential() const
+{
+ return true;
+}
+
+void FormDataIODevice::slotFinished()
+{
+ deleteLater();
+}
+
+QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadMode loadMode)
+ : QObject(0)
+ , m_resourceHandle(handle)
+ , m_reply(0)
+ , m_redirected(false)
+ , m_responseSent(false)
+ , m_loadMode(loadMode)
+ , m_startTime(0)
+ , m_shouldStart(true)
+ , m_shouldFinish(false)
+ , m_shouldSendResponse(false)
+ , m_shouldForwardData(false)
+{
+ const ResourceRequest &r = m_resourceHandle->request();
+
+ if (r.httpMethod() == "GET")
+ m_method = QNetworkAccessManager::GetOperation;
+ else if (r.httpMethod() == "HEAD")
+ m_method = QNetworkAccessManager::HeadOperation;
+ else if (r.httpMethod() == "POST")
+ m_method = QNetworkAccessManager::PostOperation;
+ else if (r.httpMethod() == "PUT")
+ m_method = QNetworkAccessManager::PutOperation;
+ else
+ m_method = QNetworkAccessManager::UnknownOperation;
+
+ m_request = r.toNetworkRequest();
+
+ if (m_loadMode == LoadNormal)
+ start();
+}
+
+void QNetworkReplyHandler::setLoadMode(LoadMode mode)
+{
+ m_loadMode = mode;
+ if (m_loadMode == LoadNormal)
+ sendQueuedItems();
+}
+
+void QNetworkReplyHandler::abort()
+{
+ m_resourceHandle = 0;
+ if (m_reply) {
+ QNetworkReply* reply = release();
+ reply->abort();
+ deleteLater();
+ }
+}
+
+QNetworkReply* QNetworkReplyHandler::release()
+{
+ QNetworkReply* reply = m_reply;
+ if (m_reply) {
+ disconnect(m_reply, 0, this, 0);
+ // We have queued connections to the QNetworkReply. Make sure any
+ // posted meta call events that were the result of a signal emission
+ // don't reach the slots in our instance.
+ QCoreApplication::removePostedEvents(this, QEvent::MetaCall);
+ m_reply = 0;
+ }
+ return reply;
+}
+
+void QNetworkReplyHandler::finish()
+{
+ m_shouldFinish = (m_loadMode == LoadDeferred);
+ if (m_loadMode == LoadDeferred)
+ return;
+
+ sendResponseIfNeeded();
+
+ if (!m_resourceHandle)
+ return;
+ ResourceHandleClient* client = m_resourceHandle->client();
+ if (!client) {
+ m_reply->deleteLater();
+ m_reply = 0;
+ return;
+ }
+ QNetworkReply* oldReply = m_reply;
+ if (m_redirected) {
+ resetState();
+ start();
+ } else if (m_reply->error() != QNetworkReply::NoError
+ // a web page that returns 403/404 can still have content
+ && m_reply->error() != QNetworkReply::ContentOperationNotPermittedError
+ && m_reply->error() != QNetworkReply::ContentNotFoundError) {
+ QUrl url = m_reply->url();
+ ResourceError error(url.host(), m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),
+ url.toString(), m_reply->errorString());
+ client->didFail(m_resourceHandle, error);
+ } else {
+ client->didFinishLoading(m_resourceHandle);
+ }
+ oldReply->deleteLater();
+ if (oldReply == m_reply)
+ m_reply = 0;
+}
+
+void QNetworkReplyHandler::sendResponseIfNeeded()
+{
+ m_shouldSendResponse = (m_loadMode == LoadDeferred);
+ if (m_loadMode == LoadDeferred)
+ return;
+
+ if (m_responseSent || !m_resourceHandle)
+ return;
+ m_responseSent = true;
+
+ ResourceHandleClient* client = m_resourceHandle->client();
+ if (!client)
+ return;
+
+ WebCore::String contentType = m_reply->header(QNetworkRequest::ContentTypeHeader).toString();
+ WebCore::String encoding = extractCharsetFromMediaType(contentType);
+ WebCore::String mimeType = extractMIMETypeFromMediaType(contentType);
+
+ if (mimeType.isEmpty()) {
+ // let's try to guess from the extension
+ QString extension = m_reply->url().path();
+ int index = extension.lastIndexOf(QLatin1Char('.'));
+ if (index > 0) {
+ extension = extension.mid(index + 1);
+ mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
+ }
+ }
+
+ KURL url(m_reply->url());
+ String suggestedFilename = filenameFromHTTPContentDisposition(QString::fromAscii(m_reply->rawHeader("Content-Disposition")));
+
+ if (suggestedFilename.isEmpty())
+ suggestedFilename = url.lastPathComponent();
+
+ ResourceResponse response(url, mimeType,
+ m_reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(),
+ encoding,
+ suggestedFilename);
+
+ const bool isLocalFileReply = (m_reply->url().scheme() == QLatin1String("file"));
+ int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+ if (!isLocalFileReply)
+ response.setHTTPStatusCode(statusCode);
+ else if (m_reply->error() == QNetworkReply::ContentNotFoundError)
+ response.setHTTPStatusCode(404);
+
+
+ /* Fill in the other fields
+ * For local file requests remove the content length and the last-modified
+ * headers as required by fast/dom/xmlhttprequest-get.xhtml
+ */
+ foreach (QByteArray headerName, m_reply->rawHeaderList()) {
+
+ if (isLocalFileReply
+ && (headerName == "Content-Length" || headerName == "Last-Modified"))
+ continue;
+
+ response.setHTTPHeaderField(QString::fromAscii(headerName), QString::fromAscii(m_reply->rawHeader(headerName)));
+ }
+
+ if (isLocalFileReply)
+ response.setExpirationDate(m_startTime);
+
+ QUrl redirection = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
+ if (redirection.isValid()) {
+ QUrl newUrl = m_reply->url().resolved(redirection);
+ ResourceRequest newRequest = m_resourceHandle->request();
+ newRequest.setURL(newUrl);
+
+ if (((statusCode >= 301 && statusCode <= 303) || statusCode == 307) && m_method == QNetworkAccessManager::PostOperation) {
+ m_method = QNetworkAccessManager::GetOperation;
+ newRequest.setHTTPMethod("GET");
+ }
+
+ client->willSendRequest(m_resourceHandle, newRequest, response);
+ m_redirected = true;
+ m_request = newRequest.toNetworkRequest();
+ } else {
+ client->didReceiveResponse(m_resourceHandle, response);
+ }
+}
+
+void QNetworkReplyHandler::forwardData()
+{
+ m_shouldForwardData = (m_loadMode == LoadDeferred);
+ if (m_loadMode == LoadDeferred)
+ return;
+
+ sendResponseIfNeeded();
+
+ // don't emit the "Document has moved here" type of HTML
+ if (m_redirected)
+ return;
+
+ if (!m_resourceHandle)
+ return;
+
+ QByteArray data = m_reply->read(m_reply->bytesAvailable());
+
+ ResourceHandleClient* client = m_resourceHandle->client();
+ if (!client)
+ return;
+
+ if (!data.isEmpty())
+ client->didReceiveData(m_resourceHandle, data.constData(), data.length(), data.length() /*FixMe*/);
+}
+
+void QNetworkReplyHandler::start()
+{
+ m_shouldStart = false;
+
+ ResourceHandleInternal* d = m_resourceHandle->getInternal();
+
+ QNetworkAccessManager* manager = d->m_frame->page()->networkAccessManager();
+
+ const QUrl url = m_request.url();
+ const QString scheme = url.scheme();
+ // Post requests on files and data don't really make sense, but for
+ // fast/forms/form-post-urlencoded.html and for fast/forms/button-state-restore.html
+ // we still need to retrieve the file/data, which means we map it to a Get instead.
+ if (m_method == QNetworkAccessManager::PostOperation
+ && (!url.toLocalFile().isEmpty() || url.scheme() == QLatin1String("data")))
+ m_method = QNetworkAccessManager::GetOperation;
+
+ m_startTime = QDateTime::currentDateTime().toTime_t();
+
+ switch (m_method) {
+ case QNetworkAccessManager::GetOperation:
+ m_reply = manager->get(m_request);
+ break;
+ case QNetworkAccessManager::PostOperation: {
+ FormDataIODevice* postDevice = new FormDataIODevice(d->m_request.httpBody());
+ m_reply = manager->post(m_request, postDevice);
+ postDevice->setParent(m_reply);
+ break;
+ }
+ case QNetworkAccessManager::HeadOperation:
+ m_reply = manager->head(m_request);
+ break;
+ case QNetworkAccessManager::PutOperation: {
+ FormDataIODevice* putDevice = new FormDataIODevice(d->m_request.httpBody());
+ m_reply = manager->put(m_request, putDevice);
+ putDevice->setParent(m_reply);
+ break;
+ }
+ case QNetworkAccessManager::UnknownOperation: {
+ m_reply = 0;
+ ResourceHandleClient* client = m_resourceHandle->client();
+ if (client) {
+ ResourceError error(url.host(), 400 /*bad request*/,
+ url.toString(),
+ QCoreApplication::translate("QWebPage", "Bad HTTP request"));
+ client->didFail(m_resourceHandle, error);
+ }
+ return;
+ }
+ }
+
+ m_reply->setParent(this);
+
+ connect(m_reply, SIGNAL(finished()),
+ this, SLOT(finish()), Qt::QueuedConnection);
+
+ // For http(s) we know that the headers are complete upon metaDataChanged() emission, so we
+ // can send the response as early as possible
+ if (scheme == QLatin1String("http") || scheme == QLatin1String("https"))
+ connect(m_reply, SIGNAL(metaDataChanged()),
+ this, SLOT(sendResponseIfNeeded()), Qt::QueuedConnection);
+
+ connect(m_reply, SIGNAL(readyRead()),
+ this, SLOT(forwardData()), Qt::QueuedConnection);
+}
+
+void QNetworkReplyHandler::resetState()
+{
+ m_redirected = false;
+ m_responseSent = false;
+ m_shouldStart = true;
+ m_shouldFinish = false;
+ m_shouldSendResponse = false;
+ m_shouldForwardData = false;
+}
+
+void QNetworkReplyHandler::sendQueuedItems()
+{
+ Q_ASSERT(m_loadMode == LoadNormal);
+
+ if (m_shouldStart)
+ start();
+
+ if (m_shouldSendResponse)
+ sendResponseIfNeeded();
+
+ if (m_shouldForwardData)
+ forwardData();
+
+ if (m_shouldFinish)
+ finish();
+}
+
+}
+
+#include "moc_QNetworkReplyHandler.cpp"
+
+#endif
diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.h b/WebCore/platform/network/qt/QNetworkReplyHandler.h
new file mode 100644
index 0000000..98be28d
--- /dev/null
+++ b/WebCore/platform/network/qt/QNetworkReplyHandler.h
@@ -0,0 +1,118 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef QNETWORKREPLYHANDLER_H
+#define QNETWORKREPLYHANDLER_H
+
+#include <QObject>
+
+#if QT_VERSION >= 0x040400
+
+#include <QNetworkRequest>
+#include <QNetworkAccessManager>
+
+#include "FormData.h"
+
+QT_BEGIN_NAMESPACE
+class QFile;
+class QNetworkReply;
+QT_END_NAMESPACE
+
+namespace WebCore {
+
+class ResourceHandle;
+
+class QNetworkReplyHandler : public QObject
+{
+ Q_OBJECT
+public:
+ enum LoadMode {
+ LoadNormal,
+ LoadDeferred
+ };
+
+ QNetworkReplyHandler(ResourceHandle *handle, LoadMode);
+ void setLoadMode(LoadMode);
+
+ QNetworkReply* reply() const { return m_reply; }
+
+ void abort();
+
+ QNetworkReply* release();
+
+private slots:
+ void finish();
+ void sendResponseIfNeeded();
+ void forwardData();
+
+private:
+ void start();
+ void resetState();
+ void sendQueuedItems();
+
+ QNetworkReply* m_reply;
+ ResourceHandle* m_resourceHandle;
+ bool m_redirected;
+ bool m_responseSent;
+ LoadMode m_loadMode;
+ QNetworkAccessManager::Operation m_method;
+ QNetworkRequest m_request;
+ uint m_startTime;
+
+ // defer state holding
+ bool m_shouldStart;
+ bool m_shouldFinish;
+ bool m_shouldSendResponse;
+ bool m_shouldForwardData;
+};
+
+// Self destructing QIODevice for FormData
+// For QNetworkAccessManager::put we will have to gurantee that the
+// QIODevice is valid as long finished() of the QNetworkReply has not
+// been emitted. With the presence of QNetworkReplyHandler::release I do
+// not want to gurantee this.
+class FormDataIODevice : public QIODevice {
+ Q_OBJECT
+public:
+ FormDataIODevice(FormData*);
+ ~FormDataIODevice();
+
+ void setParent(QNetworkReply*);
+ bool isSequential() const;
+
+protected:
+ qint64 readData(char*, qint64);
+ qint64 writeData(const char*, qint64);
+
+private Q_SLOTS:
+ void slotFinished();
+
+private:
+ void moveToNextElement();
+
+private:
+ Vector<FormDataElement> m_formElements;
+ QFile* m_currentFile;
+ qint64 m_currentDelta;
+};
+
+}
+
+#endif
+
+#endif // QNETWORKREPLYHANDLER_H
diff --git a/WebCore/platform/network/qt/ResourceError.h b/WebCore/platform/network/qt/ResourceError.h
new file mode 100644
index 0000000..ca8d36b
--- /dev/null
+++ b/WebCore/platform/network/qt/ResourceError.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceError_h
+#define ResourceError_h
+
+#include "ResourceErrorBase.h"
+
+namespace WebCore {
+
+class ResourceError : public ResourceErrorBase
+{
+public:
+ ResourceError()
+ {
+ }
+
+ ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription)
+ : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription)
+ {
+ }
+};
+
+}
+
+#endif // ResourceError_h_
diff --git a/WebCore/platform/network/qt/ResourceHandleQt.cpp b/WebCore/platform/network/qt/ResourceHandleQt.cpp
new file mode 100644
index 0000000..7af5895
--- /dev/null
+++ b/WebCore/platform/network/qt/ResourceHandleQt.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008 Holger Hans Peter Freyther
+ *
+ * All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+
+#include "Frame.h"
+#include "DocLoader.h"
+#include "ResourceHandle.h"
+#include "ResourceHandleClient.h"
+#include "ResourceHandleInternal.h"
+#include "qwebpage_p.h"
+#include "ChromeClientQt.h"
+#include "FrameLoaderClientQt.h"
+#include "Page.h"
+#include "QNetworkReplyHandler.h"
+
+#include "NotImplemented.h"
+
+#include <QCoreApplication>
+#include <QUrl>
+#if QT_VERSION >= 0x040400
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#else
+#include "qwebnetworkinterface_p.h"
+#endif
+
+namespace WebCore {
+
+class WebCoreSynchronousLoader : public ResourceHandleClient {
+public:
+ WebCoreSynchronousLoader();
+
+ void waitForCompletion();
+
+ virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived);
+ virtual void didFinishLoading(ResourceHandle*);
+ 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;
+ bool m_finished;
+};
+
+WebCoreSynchronousLoader::WebCoreSynchronousLoader()
+ : m_finished(false)
+{
+}
+
+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*)
+{
+ m_finished = true;
+}
+
+void WebCoreSynchronousLoader::didFail(ResourceHandle*, const ResourceError& error)
+{
+ m_error = error;
+ m_finished = true;
+}
+
+void WebCoreSynchronousLoader::waitForCompletion()
+{
+ while (!m_finished)
+ QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+}
+
+ResourceHandleInternal::~ResourceHandleInternal()
+{
+}
+
+ResourceHandle::~ResourceHandle()
+{
+ if (d->m_job)
+ cancel();
+}
+
+bool ResourceHandle::start(Frame* frame)
+{
+ if (!frame)
+ return false;
+
+ Page *page = frame->page();
+ // If we are no longer attached to a Page, this must be an attempted load from an
+ // onUnload handler, so let's just block it.
+ if (!page)
+ return false;
+
+ getInternal()->m_frame = static_cast<FrameLoaderClientQt*>(frame->loader()->client())->webFrame();
+#if QT_VERSION < 0x040400
+ return QWebNetworkManager::self()->add(this, getInternal()->m_frame->page()->d->networkInterface);
+#else
+ ResourceHandleInternal *d = getInternal();
+ d->m_job = new QNetworkReplyHandler(this, QNetworkReplyHandler::LoadMode(d->m_defersLoading));
+ return true;
+#endif
+}
+
+void ResourceHandle::cancel()
+{
+#if QT_VERSION < 0x040400
+ QWebNetworkManager::self()->cancel(this);
+#else
+ if (d->m_job)
+ d->m_job->abort();
+#endif
+}
+
+bool ResourceHandle::loadsBlocked()
+{
+ return false;
+}
+
+bool ResourceHandle::willLoadFromCache(ResourceRequest& request)
+{
+ notImplemented();
+ return false;
+}
+
+bool ResourceHandle::supportsBufferedData()
+{
+ return false;
+}
+
+PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame* frame)
+{
+ WebCoreSynchronousLoader syncLoader;
+ ResourceHandle handle(request, &syncLoader, true, false, true);
+
+#if QT_VERSION < 0x040400
+ if (!QWebNetworkManager::self()->add(&handle, QWebNetworkInterface::defaultInterface(), QWebNetworkManager::SynchronousJob)) {
+ // FIXME Create a sane ResourceError
+ error = ResourceError(String(), -1, String(), String());
+ return;
+ }
+#else
+ ResourceHandleInternal *d = handle.getInternal();
+ d->m_frame = static_cast<FrameLoaderClientQt*>(frame->loader()->client())->webFrame();
+ d->m_job = new QNetworkReplyHandler(&handle, QNetworkReplyHandler::LoadNormal);
+#endif
+
+ syncLoader.waitForCompletion();
+ error = syncLoader.resourceError();
+ data = syncLoader.data();
+ response = syncLoader.resourceResponse();
+}
+
+
+void ResourceHandle::setDefersLoading(bool defers)
+{
+ d->m_defersLoading = defers;
+
+#if QT_VERSION >= 0x040400
+ if (d->m_job)
+ d->m_job->setLoadMode(QNetworkReplyHandler::LoadMode(defers));
+#endif
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/qt/ResourceRequest.h b/WebCore/platform/network/qt/ResourceRequest.h
new file mode 100644
index 0000000..af76f61
--- /dev/null
+++ b/WebCore/platform/network/qt/ResourceRequest.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceRequest_h
+#define ResourceRequest_h
+
+#include "ResourceRequestBase.h"
+
+QT_BEGIN_NAMESPACE
+class QNetworkRequest;
+QT_END_NAMESPACE
+
+namespace WebCore {
+
+ struct ResourceRequest : ResourceRequestBase {
+
+ ResourceRequest(const String& url)
+ : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(const KURL& url)
+ : ResourceRequestBase(url, UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(const KURL& url, const String& referrer, ResourceRequestCachePolicy policy = UseProtocolCachePolicy)
+ : ResourceRequestBase(url, policy)
+ {
+ setHTTPReferrer(referrer);
+ }
+
+ ResourceRequest()
+ : ResourceRequestBase(KURL(), UseProtocolCachePolicy)
+ {
+ }
+
+#if QT_VERSION >= 0x040400
+ QNetworkRequest toNetworkRequest() const;
+#endif
+
+ private:
+ friend class ResourceRequestBase;
+
+ void doUpdatePlatformRequest() {}
+ void doUpdateResourceRequest() {}
+ };
+
+} // namespace WebCore
+
+#endif // ResourceRequest_h
diff --git a/WebCore/platform/network/qt/ResourceRequestQt.cpp b/WebCore/platform/network/qt/ResourceRequestQt.cpp
new file mode 100644
index 0000000..9308878
--- /dev/null
+++ b/WebCore/platform/network/qt/ResourceRequestQt.cpp
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "ResourceRequest.h"
+
+#include <qglobal.h>
+#if QT_VERSION >= 0x040400
+
+#include <QNetworkRequest>
+#include <QUrl>
+
+namespace WebCore {
+
+QNetworkRequest ResourceRequest::toNetworkRequest() const
+{
+ QNetworkRequest request;
+ request.setUrl(url());
+
+ const HTTPHeaderMap &headers = httpHeaderFields();
+ for (HTTPHeaderMap::const_iterator it = headers.begin(), end = headers.end();
+ it != end; ++it) {
+ QByteArray name = QString(it->first).toAscii();
+ QByteArray value = QString(it->second).toAscii();
+ request.setRawHeader(name, value);
+ }
+
+ return request;
+}
+
+}
+
+#endif
diff --git a/WebCore/platform/network/qt/ResourceResponse.h b/WebCore/platform/network/qt/ResourceResponse.h
new file mode 100644
index 0000000..345ef25
--- /dev/null
+++ b/WebCore/platform/network/qt/ResourceResponse.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceResponse_h
+#define ResourceResponse_h
+
+#include "ResourceResponseBase.h"
+
+namespace WebCore {
+
+class ResourceResponse : public ResourceResponseBase {
+public:
+ ResourceResponse()
+ {
+ }
+
+ ResourceResponse(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename)
+ : ResourceResponseBase(url, mimeType, expectedLength, textEncodingName, filename)
+ {
+ }
+};
+
+} // namespace WebCore
+
+#endif // ResourceResponse_h
diff --git a/WebCore/platform/network/soup/AuthenticationChallenge.h b/WebCore/platform/network/soup/AuthenticationChallenge.h
new file mode 100644
index 0000000..5177f1e
--- /dev/null
+++ b/WebCore/platform/network/soup/AuthenticationChallenge.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+#ifndef AuthenticationChallenge_h
+#define AuthenticationChallenge_h
+
+#include "AuthenticationChallengeBase.h"
+
+namespace WebCore {
+
+class AuthenticationChallenge : public AuthenticationChallengeBase {
+public:
+ AuthenticationChallenge()
+ {
+ }
+
+ AuthenticationChallenge(const ProtectionSpace& protectionSpace, const Credential& proposedCredential, unsigned previousFailureCount, const ResourceResponse& response, const ResourceError& error)
+ : AuthenticationChallengeBase(protectionSpace, proposedCredential, previousFailureCount, response, error)
+ {
+ }
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/network/soup/CookieJarSoup.cpp b/WebCore/platform/network/soup/CookieJarSoup.cpp
new file mode 100644
index 0000000..4ae90e5
--- /dev/null
+++ b/WebCore/platform/network/soup/CookieJarSoup.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 Xan Lopez <xan@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "CString.h"
+#include "CookieJar.h"
+
+#include "KURL.h"
+#include "PlatformString.h"
+#include "StringHash.h"
+
+#include <libsoup/soup.h>
+
+namespace WebCore {
+
+SoupCookieJar* getCookieJar()
+{
+ static SoupCookieJar* jar = NULL;
+
+ if (!jar)
+ jar = soup_cookie_jar_new();
+
+ return jar;
+}
+
+void setCookies(Document* /*document*/, const KURL& url, const KURL& /*policyURL*/, const String& value)
+{
+ SoupCookieJar* jar = getCookieJar();
+ if (!jar)
+ return;
+
+ SoupURI* origin = soup_uri_new(url.string().utf8().data());
+
+ soup_cookie_jar_set_cookie(jar, origin, value.utf8().data());
+ soup_uri_free(origin);
+}
+
+String cookies(const Document* /*document*/, const KURL& url)
+{
+ SoupCookieJar* jar = getCookieJar();
+ if (!jar)
+ return String();
+
+ SoupURI* uri = soup_uri_new(url.string().utf8().data());
+ char* cookies = soup_cookie_jar_get_cookies(jar, uri, FALSE);
+ soup_uri_free(uri);
+
+ String result(cookies);
+ g_free(cookies);
+
+ return result;
+}
+
+bool cookiesEnabled(const Document* /*document*/)
+{
+ return getCookieJar();
+}
+
+}
diff --git a/WebCore/platform/network/soup/DNSSoup.cpp b/WebCore/platform/network/soup/DNSSoup.cpp
new file mode 100644
index 0000000..1ffe1a0
--- /dev/null
+++ b/WebCore/platform/network/soup/DNSSoup.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 AND ITS CONTRIBUTORS "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 COMPUTER, 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"
+#include "DNS.h"
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+void prefetchDNS(const String& hostname)
+{
+ notImplemented();
+}
+
+}
diff --git a/WebCore/platform/network/soup/ResourceError.h b/WebCore/platform/network/soup/ResourceError.h
new file mode 100644
index 0000000..2d11367
--- /dev/null
+++ b/WebCore/platform/network/soup/ResourceError.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceError_h
+#define ResourceError_h
+
+#include "ResourceErrorBase.h"
+
+namespace WebCore {
+
+class ResourceError : public ResourceErrorBase
+{
+public:
+ ResourceError()
+ {
+ }
+
+ ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription)
+ : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription)
+ {
+ }
+};
+
+}
+
+#endif // ResourceError_h_
diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
new file mode 100644
index 0000000..d48ce27
--- /dev/null
+++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -0,0 +1,591 @@
+/*
+ * Copyright (C) 2008 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2008 Xan Lopez <xan@gnome.org>
+ * Copyright (C) 2008 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "CString.h"
+#include "ResourceHandle.h"
+
+#include "Base64.h"
+#include "CookieJar.h"
+#include "DocLoader.h"
+#include "Frame.h"
+#include "HTTPParsers.h"
+#include "MIMETypeRegistry.h"
+#include "NotImplemented.h"
+#include "ResourceError.h"
+#include "ResourceHandleClient.h"
+#include "ResourceHandleInternal.h"
+#include "ResourceResponse.h"
+#include "TextEncoding.h"
+
+#include <gio/gio.h>
+#include <libsoup/soup.h>
+#include <libsoup/soup-message.h>
+
+#if PLATFORM(GTK)
+ #if GLIB_CHECK_VERSION(2,12,0)
+ #define USE_GLIB_BASE64
+ #endif
+#endif
+
+namespace WebCore {
+
+static SoupSession* session = 0;
+
+enum
+{
+ ERROR_TRANSPORT,
+ ERROR_UNKNOWN_PROTOCOL,
+ ERROR_BAD_NON_HTTP_METHOD
+};
+
+ResourceHandleInternal::~ResourceHandleInternal()
+{
+ if (m_msg) {
+ g_object_unref(m_msg);
+ m_msg = 0;
+ }
+}
+
+ResourceHandle::~ResourceHandle()
+{
+}
+
+static void fillResponseFromMessage(SoupMessage* msg, ResourceResponse* response)
+{
+ SoupMessageHeadersIter iter;
+ const char* name = NULL;
+ const char* value = NULL;
+ soup_message_headers_iter_init(&iter, msg->response_headers);
+ while (soup_message_headers_iter_next(&iter, &name, &value))
+ response->setHTTPHeaderField(name, value);
+
+ String contentType = soup_message_headers_get(msg->response_headers, "Content-Type");
+ char* uri = soup_uri_to_string(soup_message_get_uri(msg), FALSE);
+ response->setUrl(KURL(uri));
+ g_free(uri);
+ response->setMimeType(extractMIMETypeFromMediaType(contentType));
+ response->setTextEncodingName(extractCharsetFromMediaType(contentType));
+ response->setExpectedContentLength(soup_message_headers_get_content_length(msg->response_headers));
+ response->setHTTPStatusCode(msg->status_code);
+ response->setSuggestedFilename(filenameFromHTTPContentDisposition(response->httpHeaderField("Content-Disposition")));
+}
+
+// Called each time the message is going to be sent again except the first time.
+// It's used mostly to let webkit know about redirects.
+static void restartedCallback(SoupMessage* msg, gpointer data)
+{
+ ResourceHandle* handle = static_cast<ResourceHandle*>(data);
+ if (!handle)
+ return;
+ ResourceHandleInternal* d = handle->getInternal();
+ if (d->m_cancelled)
+ return;
+
+ char* uri = soup_uri_to_string(soup_message_get_uri(msg), FALSE);
+ String location = String(uri);
+ g_free(uri);
+ KURL newURL = KURL(handle->request().url(), location);
+
+ ResourceRequest request = handle->request();
+ ResourceResponse response;
+ request.setURL(newURL);
+ fillResponseFromMessage(msg, &response);
+ if (d->client())
+ d->client()->willSendRequest(handle, request, response);
+
+ d->m_request.setURL(newURL);
+}
+
+static void gotHeadersCallback(SoupMessage* msg, gpointer data)
+{
+ if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code))
+ return;
+
+ ResourceHandle* handle = static_cast<ResourceHandle*>(data);
+ if (!handle)
+ return;
+ ResourceHandleInternal* d = handle->getInternal();
+ if (d->m_cancelled)
+ return;
+ ResourceHandleClient* client = handle->client();
+ if (!client)
+ return;
+
+ fillResponseFromMessage(msg, &d->m_response);
+ client->didReceiveResponse(handle, d->m_response);
+ soup_message_set_flags(msg, SOUP_MESSAGE_OVERWRITE_CHUNKS);
+}
+
+static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data)
+{
+ if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code))
+ return;
+
+ ResourceHandle* handle = static_cast<ResourceHandle*>(data);
+ if (!handle)
+ return;
+ ResourceHandleInternal* d = handle->getInternal();
+ if (d->m_cancelled)
+ return;
+ ResourceHandleClient* client = handle->client();
+ if (!client)
+ return;
+
+ client->didReceiveData(handle, chunk->data, chunk->length, false);
+}
+
+// Called at the end of the message, with all the necessary about the last informations.
+// Doesn't get called for redirects.
+static void finishedCallback(SoupSession *session, SoupMessage* msg, gpointer data)
+{
+ ResourceHandle* handle = static_cast<ResourceHandle*>(data);
+ // TODO: maybe we should run this code even if there's no client?
+ if (!handle)
+ return;
+
+ ResourceHandleInternal* d = handle->getInternal();
+ // The message has been handled.
+ d->m_msg = NULL;
+
+ ResourceHandleClient* client = handle->client();
+ if (!client)
+ return;
+
+ if (d->m_cancelled)
+ return;
+
+ if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)) {
+ char* uri = soup_uri_to_string(soup_message_get_uri(msg), FALSE);
+ ResourceError error("webkit-network-error", ERROR_TRANSPORT, uri, String::fromUTF8(msg->reason_phrase));
+ g_free(uri);
+ client->didFail(handle, error);
+ return;
+ } else if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) {
+ fillResponseFromMessage(msg, &d->m_response);
+ client->didReceiveResponse(handle, d->m_response);
+
+ // WebCore might have cancelled the job in the while
+ if (d->m_cancelled)
+ return;
+
+ if (msg->response_body->data)
+ client->didReceiveData(handle, msg->response_body->data, msg->response_body->length, true);
+ }
+
+ client->didFinishLoading(handle);
+}
+
+// parseDataUrl() is taken from the CURL http backend.
+static gboolean parseDataUrl(gpointer callback_data)
+{
+ ResourceHandle* handle = static_cast<ResourceHandle*>(callback_data);
+ ResourceHandleClient* client = handle->client();
+
+ ASSERT(client);
+ if (!client)
+ return FALSE;
+
+ String url = handle->request().url().string();
+ ASSERT(url.startsWith("data:", false));
+
+ int index = url.find(',');
+ if (index == -1) {
+ client->cannotShowURL(handle);
+ return FALSE;
+ }
+
+ String mediaType = url.substring(5, index - 5);
+ String data = url.substring(index + 1);
+
+ bool base64 = mediaType.endsWith(";base64", false);
+ if (base64)
+ mediaType = mediaType.left(mediaType.length() - 7);
+
+ if (mediaType.isEmpty())
+ mediaType = "text/plain;charset=US-ASCII";
+
+ String mimeType = extractMIMETypeFromMediaType(mediaType);
+ String charset = extractCharsetFromMediaType(mediaType);
+
+ ResourceResponse response;
+ response.setMimeType(mimeType);
+
+ if (base64) {
+ data = decodeURLEscapeSequences(data);
+ response.setTextEncodingName(charset);
+ client->didReceiveResponse(handle, response);
+
+ // Use the GLib Base64 if available, since WebCore's decoder isn't
+ // general-purpose and fails on Acid3 test 97 (whitespace).
+#ifdef USE_GLIB_BASE64
+ size_t outLength = 0;
+ char* outData = 0;
+ outData = reinterpret_cast<char*>(g_base64_decode(data.utf8().data(), &outLength));
+ if (outData && outLength > 0)
+ client->didReceiveData(handle, outData, outLength, 0);
+ g_free(outData);
+#else
+ Vector<char> out;
+ if (base64Decode(data.latin1().data(), data.latin1().length(), out) && out.size() > 0)
+ client->didReceiveData(handle, out.data(), out.size(), 0);
+#endif
+ } else {
+ // We have to convert to UTF-16 early due to limitations in KURL
+ data = decodeURLEscapeSequences(data, TextEncoding(charset));
+ response.setTextEncodingName("UTF-16");
+ client->didReceiveResponse(handle, response);
+ if (data.length() > 0)
+ client->didReceiveData(handle, reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0);
+ }
+
+ client->didFinishLoading(handle);
+
+ return FALSE;
+}
+
+bool ResourceHandle::startData(String urlString)
+{
+ // If parseDataUrl is called synchronously the job is not yet effectively started
+ // and webkit won't never know that the data has been parsed even didFinishLoading is called.
+ g_idle_add(parseDataUrl, this);
+ return true;
+}
+
+bool ResourceHandle::startHttp(String urlString)
+{
+ if (!session) {
+ session = soup_session_async_new();
+
+ soup_session_add_feature(session, SOUP_SESSION_FEATURE(getCookieJar()));
+
+ const char* soup_debug = g_getenv("WEBKIT_SOUP_LOGGING");
+ if (soup_debug) {
+ int soup_debug_level = atoi(soup_debug);
+
+ SoupLogger* logger = soup_logger_new(static_cast<SoupLoggerLogLevel>(soup_debug_level), -1);
+ soup_logger_attach(logger, session);
+ g_object_unref(logger);
+ }
+ }
+
+ SoupMessage* msg;
+ msg = soup_message_new(request().httpMethod().utf8().data(), urlString.utf8().data());
+ g_signal_connect(msg, "restarted", G_CALLBACK(restartedCallback), this);
+
+ g_signal_connect(msg, "got-headers", G_CALLBACK(gotHeadersCallback), this);
+ g_signal_connect(msg, "got-chunk", G_CALLBACK(gotChunkCallback), this);
+
+ HTTPHeaderMap customHeaders = d->m_request.httpHeaderFields();
+ if (!customHeaders.isEmpty()) {
+ HTTPHeaderMap::const_iterator end = customHeaders.end();
+ for (HTTPHeaderMap::const_iterator it = customHeaders.begin(); it != end; ++it)
+ soup_message_headers_append(msg->request_headers, it->first.utf8().data(), it->second.utf8().data());
+ }
+
+ FormData* httpBody = d->m_request.httpBody();
+ if (httpBody && !httpBody->isEmpty()) {
+ // Making a copy of the request body isn't the most efficient way to
+ // serialize it, but by far the most simple. Dealing with individual
+ // FormData elements and shared buffers should be more memory
+ // efficient.
+ //
+ // This possibly isn't handling file uploads/attachments, for which
+ // shared buffers or streaming should definitely be used.
+ Vector<char> body;
+ httpBody->flatten(body);
+ soup_message_set_request(msg, d->m_request.httpContentType().utf8().data(),
+ SOUP_MEMORY_COPY, body.data(), body.size());
+ }
+
+ d->m_msg = static_cast<SoupMessage*>(g_object_ref(msg));
+ soup_session_queue_message(session, d->m_msg, finishedCallback, this);
+
+ return true;
+}
+
+bool ResourceHandle::start(Frame* frame)
+{
+ ASSERT(!d->m_msg);
+
+ // If we are no longer attached to a Page, this must be an attempted load from an
+ // onUnload handler, so let's just block it.
+ if (!frame->page())
+ return false;
+
+ KURL url = request().url();
+ String urlString = url.string();
+ String protocol = url.protocol();
+
+ if (equalIgnoringCase(protocol, "data"))
+ return startData(urlString);
+ else if (equalIgnoringCase(protocol, "http") || equalIgnoringCase(protocol, "https"))
+ return startHttp(urlString);
+ else if (equalIgnoringCase(protocol, "file") || equalIgnoringCase(protocol, "ftp") || equalIgnoringCase(protocol, "ftps"))
+ // FIXME: should we be doing any other protocols here?
+ return startGio(urlString);
+ else {
+ // If we don't call didFail the job is not complete for webkit even false is returned.
+ if (d->client()) {
+ ResourceError error("webkit-network-error", ERROR_UNKNOWN_PROTOCOL, urlString, protocol);
+ d->client()->didFail(this, error);
+ }
+ return false;
+ }
+}
+
+void ResourceHandle::cancel()
+{
+ d->m_cancelled = true;
+ if (d->m_msg) {
+ soup_session_cancel_message(session, d->m_msg, SOUP_STATUS_CANCELLED);
+ // For re-entrancy troubles we call didFinishLoading when the message hasn't been handled yet.
+ d->client()->didFinishLoading(this);
+ } else if (d->m_cancellable) {
+ g_cancellable_cancel(d->m_cancellable);
+ d->client()->didFinishLoading(this);
+ }
+}
+
+PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+bool ResourceHandle::supportsBufferedData()
+{
+ return false;
+}
+
+void ResourceHandle::setDefersLoading(bool defers)
+{
+ d->m_defersLoading = defers;
+ notImplemented();
+}
+
+bool ResourceHandle::loadsBlocked()
+{
+ return false;
+}
+
+bool ResourceHandle::willLoadFromCache(ResourceRequest&)
+{
+ // Not having this function means that we'll ask the user about re-posting a form
+ // even when we go back to a page that's still in the cache.
+ notImplemented();
+ return false;
+}
+
+void ResourceHandle::loadResourceSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>&, Frame*)
+{
+ notImplemented();
+}
+
+// GIO-based loader
+
+static inline ResourceError networkErrorForFile(GFile* file, GError* error)
+{
+ // FIXME: Map gio errors to a more detailed error code when we have it in WebKit.
+ gchar* uri = g_file_get_uri(file);
+ ResourceError resourceError("webkit-network-error", ERROR_TRANSPORT, uri, String::fromUTF8(error->message));
+ g_free(uri);
+ return resourceError;
+}
+
+static void cleanupGioOperation(ResourceHandle* handle)
+{
+ ResourceHandleInternal* d = handle->getInternal();
+
+ if (d->m_gfile) {
+ g_object_unref(d->m_gfile);
+ d->m_gfile = NULL;
+ }
+ if (d->m_cancellable) {
+ g_object_unref(d->m_cancellable);
+ d->m_cancellable = NULL;
+ }
+ if (d->m_input_stream) {
+ g_object_unref(d->m_input_stream);
+ d->m_input_stream = NULL;
+ }
+ if (d->m_buffer) {
+ g_free(d->m_buffer);
+ d->m_buffer = NULL;
+ }
+}
+
+static void closeCallback(GObject* source, GAsyncResult* res, gpointer data)
+{
+ ResourceHandle* handle = static_cast<ResourceHandle*>(data);
+ ResourceHandleInternal* d = handle->getInternal();
+ ResourceHandleClient* client = handle->client();
+
+ g_input_stream_close_finish(d->m_input_stream, res, NULL);
+ cleanupGioOperation(handle);
+ client->didFinishLoading(handle);
+}
+
+static void readCallback(GObject* source, GAsyncResult* res, gpointer data)
+{
+ ResourceHandle* handle = static_cast<ResourceHandle*>(data);
+ ResourceHandleInternal* d = handle->getInternal();
+ ResourceHandleClient* client = handle->client();
+
+ if (d->m_cancelled || !client) {
+ cleanupGioOperation(handle);
+ return;
+ }
+
+ gssize nread;
+ GError *error = 0;
+
+ nread = g_input_stream_read_finish(d->m_input_stream, res, &error);
+ if (error) {
+ client->didFail(handle, networkErrorForFile(d->m_gfile, error));
+ cleanupGioOperation(handle);
+ return;
+ } else if (!nread) {
+ g_input_stream_close_async(d->m_input_stream, G_PRIORITY_DEFAULT,
+ NULL, closeCallback, handle);
+ return;
+ }
+
+ d->m_total += nread;
+ client->didReceiveData(handle, d->m_buffer, nread, d->m_total);
+
+ g_input_stream_read_async(d->m_input_stream, d->m_buffer, d->m_bufsize,
+ G_PRIORITY_DEFAULT, d->m_cancellable,
+ readCallback, handle);
+}
+
+static void openCallback(GObject* source, GAsyncResult* res, gpointer data)
+{
+ ResourceHandle* handle = static_cast<ResourceHandle*>(data);
+ ResourceHandleInternal* d = handle->getInternal();
+ ResourceHandleClient* client = handle->client();
+
+ if (d->m_cancelled || !client) {
+ cleanupGioOperation(handle);
+ return;
+ }
+
+ GFileInputStream* in;
+ GError *error = NULL;
+ in = g_file_read_finish(G_FILE(source), res, &error);
+ if (error) {
+ client->didFail(handle, networkErrorForFile(d->m_gfile, error));
+ cleanupGioOperation(handle);
+ return;
+ }
+
+ d->m_input_stream = G_INPUT_STREAM(in);
+ d->m_bufsize = 8192;
+ d->m_buffer = static_cast<char*>(g_malloc(d->m_bufsize));
+ d->m_total = 0;
+ g_input_stream_read_async(d->m_input_stream, d->m_buffer, d->m_bufsize,
+ G_PRIORITY_DEFAULT, d->m_cancellable,
+ readCallback, handle);
+}
+
+static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer data)
+{
+ ResourceHandle* handle = static_cast<ResourceHandle*>(data);
+ ResourceHandleInternal* d = handle->getInternal();
+ ResourceHandleClient* client = handle->client();
+
+ if (d->m_cancelled) {
+ cleanupGioOperation(handle);
+ return;
+ }
+
+ ResourceResponse response;
+
+ char* uri = g_file_get_uri(d->m_gfile);
+ response.setUrl(KURL(uri));
+ g_free(uri);
+
+ GError *error = NULL;
+ GFileInfo* info = g_file_query_info_finish(d->m_gfile, res, &error);
+
+ if (error) {
+ // FIXME: to be able to handle ftp URIs properly, we must
+ // check if the error is G_IO_ERROR_NOT_MOUNTED, and if so,
+ // call g_file_mount_enclosing_volume() to mount the ftp
+ // server (and then keep track of the fact that we mounted it,
+ // and set a timeout to unmount it later after it's been idle
+ // for a while).
+
+ client->didFail(handle, networkErrorForFile(d->m_gfile, error));
+ cleanupGioOperation(handle);
+ return;
+ }
+
+ if (g_file_info_get_file_type(info) != G_FILE_TYPE_REGULAR) {
+ // FIXME: what if the URI points to a directory? Should we
+ // generate a listing? How? What do other backends do here?
+
+ client->didFail(handle, networkErrorForFile(d->m_gfile, error));
+ cleanupGioOperation(handle);
+ return;
+ }
+
+ response.setMimeType(g_file_info_get_content_type(info));
+ response.setExpectedContentLength(g_file_info_get_size(info));
+ response.setHTTPStatusCode(SOUP_STATUS_OK);
+
+ GTimeVal tv;
+ g_file_info_get_modification_time(info, &tv);
+ response.setLastModifiedDate(tv.tv_sec);
+
+ client->didReceiveResponse(handle, response);
+
+ g_file_read_async(d->m_gfile, G_PRIORITY_DEFAULT, d->m_cancellable,
+ openCallback, handle);
+}
+
+bool ResourceHandle::startGio(String urlString)
+{
+ if (request().httpMethod() != "GET") {
+ ResourceError error("webkit-network-error", ERROR_BAD_NON_HTTP_METHOD, urlString, request().httpMethod());
+ d->client()->didFail(this, error);
+ return false;
+ }
+
+ // Remove the fragment part of the URL since the file backend doesn't deal with it
+ int fragPos;
+ if ((fragPos = urlString.find("#")) != -1)
+ urlString = urlString.left(fragPos);
+
+ d->m_gfile = g_file_new_for_uri(urlString.utf8().data());
+ d->m_cancellable = g_cancellable_new();
+ g_file_query_info_async(d->m_gfile,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
+ G_FILE_ATTRIBUTE_STANDARD_SIZE,
+ G_FILE_QUERY_INFO_NONE,
+ G_PRIORITY_DEFAULT, d->m_cancellable,
+ queryInfoCallback, this);
+ return true;
+}
+
+}
+
diff --git a/WebCore/platform/network/soup/ResourceRequest.h b/WebCore/platform/network/soup/ResourceRequest.h
new file mode 100644
index 0000000..efb1240
--- /dev/null
+++ b/WebCore/platform/network/soup/ResourceRequest.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceRequest_h
+#define ResourceRequest_h
+
+#include "ResourceRequestBase.h"
+
+namespace WebCore {
+
+ struct ResourceRequest : ResourceRequestBase {
+
+ ResourceRequest(const String& url)
+ : ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(const KURL& url)
+ : ResourceRequestBase(url, UseProtocolCachePolicy)
+ {
+ }
+
+ ResourceRequest(const KURL& url, const String& referrer, ResourceRequestCachePolicy policy = UseProtocolCachePolicy)
+ : ResourceRequestBase(url, policy)
+ {
+ setHTTPReferrer(referrer);
+ }
+
+ ResourceRequest()
+ : ResourceRequestBase(KURL(), UseProtocolCachePolicy)
+ {
+ }
+
+ private:
+ friend class ResourceRequestBase;
+
+ void doUpdatePlatformRequest() {}
+ void doUpdateResourceRequest() {}
+ };
+
+} // namespace WebCore
+
+#endif // ResourceRequest_h
diff --git a/WebCore/platform/network/soup/ResourceResponse.h b/WebCore/platform/network/soup/ResourceResponse.h
new file mode 100644
index 0000000..b8cb586
--- /dev/null
+++ b/WebCore/platform/network/soup/ResourceResponse.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceResponse_h
+#define ResourceResponse_h
+
+#include "ResourceResponseBase.h"
+
+namespace WebCore {
+
+class ResourceResponse : public ResourceResponseBase {
+public:
+ ResourceResponse()
+ : ResourceResponseBase()
+ {
+ }
+
+ ResourceResponse(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename)
+ : ResourceResponseBase(url, mimeType, expectedLength, textEncodingName, filename)
+ {
+ }
+
+private:
+ friend class ResourceResponseBase;
+
+ void doUpdateResourceResponse()
+ {
+ }
+};
+
+} // namespace WebCore
+
+#endif // ResourceResponse_h
diff --git a/WebCore/platform/network/win/CookieJarCFNetWin.cpp b/WebCore/platform/network/win/CookieJarCFNetWin.cpp
new file mode 100644
index 0000000..fd795ee
--- /dev/null
+++ b/WebCore/platform/network/win/CookieJarCFNetWin.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "CookieJar.h"
+
+#include "CookieStorageWin.h"
+#include "KURL.h"
+#include "PlatformString.h"
+#include "Document.h"
+#include "ResourceHandle.h"
+#include <windows.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CFNetwork/CFHTTPCookiesPriv.h>
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
+
+namespace WebCore {
+
+static const CFStringRef s_setCookieKeyCF = CFSTR("Set-Cookie");
+static const CFStringRef s_cookieCF = CFSTR("Cookie");
+
+void setCookies(Document* /*document*/, const KURL& url, const KURL& policyURL, const String& value)
+{
+ // <rdar://problem/5632883> CFHTTPCookieStorage happily stores an empty cookie, which would be sent as "Cookie: =".
+ if (value.isEmpty())
+ return;
+
+ CFHTTPCookieStorageRef cookieStorage = currentCookieStorage();
+ if (!cookieStorage)
+ return;
+
+ RetainPtr<CFURLRef> urlCF(AdoptCF, url.createCFURL());
+ RetainPtr<CFURLRef> policyURLCF(AdoptCF, policyURL.createCFURL());
+
+ // <http://bugs.webkit.org/show_bug.cgi?id=6531>, <rdar://4409034>
+ // cookiesWithResponseHeaderFields doesn't parse cookies without a value
+ String cookieString = value.contains('=') ? value : value + "=";
+
+ RetainPtr<CFStringRef> cookieStringCF(AdoptCF, cookieString.createCFString());
+ RetainPtr<CFDictionaryRef> headerFieldsCF(AdoptCF, CFDictionaryCreate(kCFAllocatorDefault, (const void**)&s_setCookieKeyCF,
+ (const void**)&cookieStringCF, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+ RetainPtr<CFArrayRef> cookiesCF(AdoptCF, CFHTTPCookieCreateWithResponseHeaderFields(kCFAllocatorDefault,
+ headerFieldsCF.get(), urlCF.get()));
+
+ CFHTTPCookieStorageSetCookies(cookieStorage, cookiesCF.get(), urlCF.get(), policyURLCF.get());
+}
+
+String cookies(const Document* /*document*/, const KURL& url)
+{
+ CFHTTPCookieStorageRef cookieStorage = currentCookieStorage();
+ if (!cookieStorage)
+ return String();
+
+ String cookieString;
+ RetainPtr<CFURLRef> urlCF(AdoptCF, url.createCFURL());
+
+ bool secure = equalIgnoringCase(url.protocol(), "https");
+
+ RetainPtr<CFArrayRef> cookiesCF(AdoptCF, CFHTTPCookieStorageCopyCookiesForURL(cookieStorage, urlCF.get(), secure));
+
+ // <rdar://problem/5632883> CFHTTPCookieStorage happily stores an empty cookie, which would be sent as "Cookie: =".
+ // We have a workaround in setCookies() to prevent that, but we also need to avoid sending cookies that were previously stored.
+ CFIndex count = CFArrayGetCount(cookiesCF.get());
+ RetainPtr<CFMutableArrayRef> cookiesForURLFilteredCopy(AdoptCF, CFArrayCreateMutable(0, count, &kCFTypeArrayCallBacks));
+ for (CFIndex i = 0; i < count; ++i) {
+ CFHTTPCookieRef cookie = (CFHTTPCookieRef)CFArrayGetValueAtIndex(cookiesCF.get(), i);
+ if (CFStringGetLength(CFHTTPCookieGetName(cookie)) != 0)
+ CFArrayAppendValue(cookiesForURLFilteredCopy.get(), cookie);
+ }
+ RetainPtr<CFDictionaryRef> headerCF(AdoptCF, CFHTTPCookieCopyRequestHeaderFields(kCFAllocatorDefault, cookiesForURLFilteredCopy.get()));
+
+ return (CFStringRef)CFDictionaryGetValue(headerCF.get(), s_cookieCF);
+}
+
+bool cookiesEnabled(const Document* /*document*/)
+{
+ CFHTTPCookieStorageAcceptPolicy policy = CFHTTPCookieStorageAcceptPolicyOnlyFromMainDocumentDomain;
+ if (CFHTTPCookieStorageRef cookieStorage = currentCookieStorage())
+ policy = CFHTTPCookieStorageGetCookieAcceptPolicy(cookieStorage);
+ return policy == CFHTTPCookieStorageAcceptPolicyOnlyFromMainDocumentDomain || policy == CFHTTPCookieStorageAcceptPolicyAlways;
+}
+
+}
diff --git a/WebCore/platform/network/win/CookieJarWin.cpp b/WebCore/platform/network/win/CookieJarWin.cpp
new file mode 100644
index 0000000..cdafb1b
--- /dev/null
+++ b/WebCore/platform/network/win/CookieJarWin.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "CookieJar.h"
+
+#include "KURL.h"
+#include "PlatformString.h"
+#include "Document.h"
+#include "ResourceHandle.h"
+#include <windows.h>
+#include <Wininet.h>
+
+namespace WebCore {
+
+
+void setCookies(Document* /*document*/, const KURL& url, const KURL& policyURL, const String& value)
+{
+ // FIXME: Deal with the policy URL.
+ String str = url.string();
+ String val = value;
+ InternetSetCookie(str.charactersWithNullTermination(), 0, val.charactersWithNullTermination());
+}
+
+String cookies(const Document* /*document*/, const KURL& url)
+{
+ String str = url.string();
+
+ DWORD count = str.length() + 1;
+ InternetGetCookie(str.charactersWithNullTermination(), 0, 0, &count);
+ if (count <= 1) // Null terminator counts as 1.
+ return String();
+
+ Vector<UChar> buffer(count);
+ InternetGetCookie(str.charactersWithNullTermination(), 0, buffer.data(), &count);
+ buffer.shrink(count - 1); // Ignore the null terminator.
+ return String::adopt(buffer);
+}
+
+bool cookiesEnabled(const Document* /*document*/)
+{
+ return true;
+}
+
+}
diff --git a/WebCore/platform/network/win/CookieStorageWin.cpp b/WebCore/platform/network/win/CookieStorageWin.cpp
new file mode 100644
index 0000000..5e74c17
--- /dev/null
+++ b/WebCore/platform/network/win/CookieStorageWin.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+
+#include "CookieStorageWin.h"
+
+#include <CFNetwork/CFHTTPCookiesPriv.h>
+#include <WebKitSystemInterface/WebKitSystemInterface.h>
+#include <wtf/RetainPtr.h>
+
+namespace WebCore {
+
+static RetainPtr<CFHTTPCookieStorageRef> s_cookieStorage;
+
+CFHTTPCookieStorageRef currentCookieStorage()
+{
+ if (s_cookieStorage)
+ return s_cookieStorage.get();
+ return wkGetDefaultHTTPCookieStorage();
+}
+
+void setCurrentCookieStorage(CFHTTPCookieStorageRef cookieStorage)
+{
+ s_cookieStorage = cookieStorage;
+}
+
+}
diff --git a/WebCore/platform/network/win/CookieStorageWin.h b/WebCore/platform/network/win/CookieStorageWin.h
new file mode 100644
index 0000000..4350b72
--- /dev/null
+++ b/WebCore/platform/network/win/CookieStorageWin.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef CookieStorageWin_h
+#define CookieStorageWin_h
+
+typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef;
+
+namespace WebCore {
+
+ CFHTTPCookieStorageRef currentCookieStorage();
+
+ void setCurrentCookieStorage(CFHTTPCookieStorageRef cookieStorage);
+
+}
+
+#endif // CookieStorageWin_h
diff --git a/WebCore/platform/network/win/NetworkStateNotifierWin.cpp b/WebCore/platform/network/win/NetworkStateNotifierWin.cpp
new file mode 100644
index 0000000..f8cbace
--- /dev/null
+++ b/WebCore/platform/network/win/NetworkStateNotifierWin.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * 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"
+#include "NetworkStateNotifier.h"
+
+#include <wtf/MainThread.h>
+#include <wtf/Vector.h>
+
+#include <winsock2.h>
+#include <iphlpapi.h>
+
+namespace WebCore {
+
+void NetworkStateNotifier::updateState()
+{
+ // Assume that we're online until proven otherwise.
+ m_isOnLine = true;
+
+ Vector<char> buffer;
+ DWORD size = 0;
+
+ if (::GetAdaptersAddresses(AF_UNSPEC, 0, 0, 0, &size) != ERROR_BUFFER_OVERFLOW)
+ return;
+
+ buffer.resize(size);
+ PIP_ADAPTER_ADDRESSES addresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(buffer.data());
+
+ if (::GetAdaptersAddresses(AF_UNSPEC, 0, 0, addresses, &size) != ERROR_SUCCESS) {
+ // We couldn't determine whether we're online or not, so assume that we are.
+ return;
+ }
+
+ for (; addresses; addresses = addresses->Next) {
+ if (addresses->IfType == MIB_IF_TYPE_LOOPBACK)
+ continue;
+
+ if (addresses->OperStatus != IfOperStatusUp)
+ continue;
+
+ // We found an interface that was up.
+ return;
+ }
+
+ // We didn't find any valid interfaces, so we must be offline.
+ m_isOnLine = false;
+}
+
+void NetworkStateNotifier::addressChanged()
+{
+ bool oldOnLine = m_isOnLine;
+
+ updateState();
+
+ if (m_isOnLine == oldOnLine)
+ return;
+
+ if (m_networkStateChangedFunction)
+ m_networkStateChangedFunction();
+}
+
+void NetworkStateNotifier::callAddressChanged(void* context)
+{
+ static_cast<NetworkStateNotifier*>(context)->addressChanged();
+}
+
+void CALLBACK NetworkStateNotifier::addrChangeCallback(void* context, BOOLEAN timedOut)
+{
+ callOnMainThread(callAddressChanged, context);
+}
+
+void NetworkStateNotifier::registerForAddressChange()
+{
+ HANDLE handle;
+ ::NotifyAddrChange(&handle, &m_overlapped);
+}
+
+NetworkStateNotifier::NetworkStateNotifier()
+ : m_isOnLine(false)
+{
+ updateState();
+
+ memset(&m_overlapped, 0, sizeof(m_overlapped));
+
+ m_overlapped.hEvent = ::CreateEvent(0, false, false, 0);
+
+ ::RegisterWaitForSingleObject(&m_waitHandle, m_overlapped.hEvent, addrChangeCallback, this, INFINITE, 0);
+
+ registerForAddressChange();
+}
+
+}
diff --git a/WebCore/platform/network/win/ResourceHandleWin.cpp b/WebCore/platform/network/win/ResourceHandleWin.cpp
new file mode 100644
index 0000000..337b752
--- /dev/null
+++ b/WebCore/platform/network/win/ResourceHandleWin.cpp
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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"
+#include "ResourceHandle.h"
+#include "ResourceHandleClient.h"
+#include "ResourceHandleInternal.h"
+#include "ResourceHandleWin.h"
+
+#include "CString.h"
+#include "DocLoader.h"
+#include "Document.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "Page.h"
+#include "ResourceError.h"
+#include "Timer.h"
+#include <windows.h>
+#include <wininet.h>
+
+namespace WebCore {
+
+static unsigned transferJobId = 0;
+static HashMap<int, ResourceHandle*>* jobIdMap = 0;
+
+static HWND transferJobWindowHandle = 0;
+const LPCWSTR kResourceHandleWindowClassName = L"ResourceHandleWindowClass";
+
+// Message types for internal use (keep in sync with kMessageHandlers)
+enum {
+ handleCreatedMessage = WM_USER,
+ requestRedirectedMessage,
+ requestCompleteMessage
+};
+
+typedef void (ResourceHandle:: *ResourceHandleEventHandler)(LPARAM);
+static const ResourceHandleEventHandler messageHandlers[] = {
+ &ResourceHandle::onHandleCreated,
+ &ResourceHandle::onRequestRedirected,
+ &ResourceHandle::onRequestComplete
+};
+
+static int addToOutstandingJobs(ResourceHandle* job)
+{
+ if (!jobIdMap)
+ jobIdMap = new HashMap<int, ResourceHandle*>;
+ transferJobId++;
+ jobIdMap->set(transferJobId, job);
+ return transferJobId;
+}
+
+static void removeFromOutstandingJobs(int jobId)
+{
+ if (!jobIdMap)
+ return;
+ jobIdMap->remove(jobId);
+}
+
+static ResourceHandle* lookupResourceHandle(int jobId)
+{
+ if (!jobIdMap)
+ return 0;
+ return jobIdMap->get(jobId);
+}
+
+static LRESULT CALLBACK ResourceHandleWndProc(HWND hWnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ if (message >= handleCreatedMessage) {
+ UINT index = message - handleCreatedMessage;
+ if (index < _countof(messageHandlers)) {
+ unsigned jobId = (unsigned) wParam;
+ ResourceHandle* job = lookupResourceHandle(jobId);
+ if (job) {
+ ASSERT(job->d->m_jobId == jobId);
+ ASSERT(job->d->m_threadId == GetCurrentThreadId());
+ (job->*(messageHandlers[index]))(lParam);
+ }
+ return 0;
+ }
+ }
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+static void initializeOffScreenResourceHandleWindow()
+{
+ if (transferJobWindowHandle)
+ return;
+
+ WNDCLASSEX wcex;
+ memset(&wcex, 0, sizeof(WNDCLASSEX));
+ wcex.cbSize = sizeof(WNDCLASSEX);
+ wcex.lpfnWndProc = ResourceHandleWndProc;
+ wcex.hInstance = Page::instanceHandle();
+ wcex.lpszClassName = kResourceHandleWindowClassName;
+ RegisterClassEx(&wcex);
+
+ transferJobWindowHandle = CreateWindow(kResourceHandleWindowClassName, 0, 0, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
+ HWND_MESSAGE, 0, Page::instanceHandle(), 0);
+}
+
+ResourceHandleInternal::~ResourceHandleInternal()
+{
+ if (m_fileHandle != INVALID_HANDLE_VALUE)
+ CloseHandle(m_fileHandle);
+}
+
+ResourceHandle::~ResourceHandle()
+{
+ if (d->m_jobId)
+ removeFromOutstandingJobs(d->m_jobId);
+}
+
+void ResourceHandle::onHandleCreated(LPARAM lParam)
+{
+ if (!d->m_resourceHandle) {
+ d->m_resourceHandle = HINTERNET(lParam);
+ if (d->status != 0) {
+ // We were canceled before Windows actually created a handle for us, close and delete now.
+ InternetCloseHandle(d->m_resourceHandle);
+ delete this;
+ return;
+ }
+
+ if (method() == "POST") {
+ // FIXME: Too late to set referrer properly.
+ String urlStr = url().path();
+ int fragmentIndex = urlStr.find('#');
+ if (fragmentIndex != -1)
+ urlStr = urlStr.left(fragmentIndex);
+ static LPCSTR accept[2]={"*/*", NULL};
+ HINTERNET urlHandle = HttpOpenRequestA(d->m_resourceHandle,
+ "POST", urlStr.latin1().data(), 0, 0, accept,
+ INTERNET_FLAG_KEEP_CONNECTION |
+ INTERNET_FLAG_FORMS_SUBMIT |
+ INTERNET_FLAG_RELOAD |
+ INTERNET_FLAG_NO_CACHE_WRITE |
+ INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS |
+ INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP,
+ (DWORD_PTR)d->m_jobId);
+ if (urlHandle == INVALID_HANDLE_VALUE) {
+ InternetCloseHandle(d->m_resourceHandle);
+ delete this;
+ }
+ }
+ } else if (!d->m_secondaryHandle) {
+ assert(method() == "POST");
+ d->m_secondaryHandle = HINTERNET(lParam);
+
+ // Need to actually send the request now.
+ String headers = "Content-Type: application/x-www-form-urlencoded\n";
+ headers += "Referer: ";
+ headers += d->m_postReferrer;
+ headers += "\n";
+ const CString& headersLatin1 = headers.latin1();
+ String formData = postData()->flattenToString();
+ INTERNET_BUFFERSA buffers;
+ memset(&buffers, 0, sizeof(buffers));
+ buffers.dwStructSize = sizeof(INTERNET_BUFFERSA);
+ buffers.lpcszHeader = headersLatin1;
+ buffers.dwHeadersLength = headers.length();
+ buffers.dwBufferTotal = formData.length();
+
+ d->m_bytesRemainingToWrite = formData.length();
+ d->m_formDataString = (char*)malloc(formData.length());
+ d->m_formDataLength = formData.length();
+ strncpy(d->m_formDataString, formData.latin1(), formData.length());
+ d->m_writing = true;
+ HttpSendRequestExA(d->m_secondaryHandle, &buffers, 0, 0, (DWORD_PTR)d->m_jobId);
+ // FIXME: add proper error handling
+ }
+}
+
+void ResourceHandle::onRequestRedirected(LPARAM lParam)
+{
+ // If already canceled, then ignore this event.
+ if (d->status != 0)
+ return;
+
+ ResourceRequest request((StringImpl*) lParam);
+ ResourceResponse redirectResponse;
+ client()->willSendRequest(this, request, redirectResponse);
+}
+
+void ResourceHandle::onRequestComplete(LPARAM lParam)
+{
+ if (d->m_writing) {
+ DWORD bytesWritten;
+ InternetWriteFile(d->m_secondaryHandle,
+ d->m_formDataString + (d->m_formDataLength - d->m_bytesRemainingToWrite),
+ d->m_bytesRemainingToWrite,
+ &bytesWritten);
+ d->m_bytesRemainingToWrite -= bytesWritten;
+ if (!d->m_bytesRemainingToWrite) {
+ // End the request.
+ d->m_writing = false;
+ HttpEndRequest(d->m_secondaryHandle, 0, 0, (DWORD_PTR)d->m_jobId);
+ free(d->m_formDataString);
+ d->m_formDataString = 0;
+ }
+ return;
+ }
+
+ HINTERNET handle = (method() == "POST") ? d->m_secondaryHandle : d->m_resourceHandle;
+ BOOL ok = FALSE;
+
+ static const int bufferSize = 32768;
+ char buffer[bufferSize];
+ INTERNET_BUFFERSA buffers;
+ buffers.dwStructSize = sizeof(INTERNET_BUFFERSA);
+ buffers.lpvBuffer = buffer;
+ buffers.dwBufferLength = bufferSize;
+
+ bool receivedAnyData = false;
+ while ((ok = InternetReadFileExA(handle, &buffers, IRF_NO_WAIT, (DWORD_PTR)this)) && buffers.dwBufferLength) {
+ if (!hasReceivedResponse()) {
+ setHasReceivedResponse();
+ ResourceResponse response;
+ client()->didReceiveResponse(this, response);
+ }
+ client()->didReceiveData(this, buffer, buffers.dwBufferLength, 0);
+ buffers.dwBufferLength = bufferSize;
+ }
+
+ PlatformDataStruct platformData;
+ platformData.errorString = 0;
+ platformData.error = 0;
+ platformData.loaded = ok;
+
+ if (!ok) {
+ int error = GetLastError();
+ if (error == ERROR_IO_PENDING)
+ return;
+ DWORD errorStringChars = 0;
+ if (!InternetGetLastResponseInfo(&platformData.error, 0, &errorStringChars)) {
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ platformData.errorString = new TCHAR[errorStringChars];
+ InternetGetLastResponseInfo(&platformData.error, platformData.errorString, &errorStringChars);
+ }
+ }
+ _RPTF1(_CRT_WARN, "Load error: %i\n", error);
+ }
+
+ if (d->m_secondaryHandle)
+ InternetCloseHandle(d->m_secondaryHandle);
+ InternetCloseHandle(d->m_resourceHandle);
+
+ client()->didFinishLoading(this);
+ delete this;
+}
+
+static void __stdcall transferJobStatusCallback(HINTERNET internetHandle,
+ DWORD_PTR jobId,
+ DWORD internetStatus,
+ LPVOID statusInformation,
+ DWORD statusInformationLength)
+{
+#ifdef RESOURCE_LOADER_DEBUG
+ char buf[64];
+ _snprintf(buf, sizeof(buf), "status-callback: status=%u, job=%p\n",
+ internetStatus, jobId);
+ OutputDebugStringA(buf);
+#endif
+
+ UINT msg;
+ LPARAM lParam;
+
+ switch (internetStatus) {
+ case INTERNET_STATUS_HANDLE_CREATED:
+ // tell the main thread about the newly created handle
+ msg = handleCreatedMessage;
+ lParam = (LPARAM) LPINTERNET_ASYNC_RESULT(statusInformation)->dwResult;
+ break;
+ case INTERNET_STATUS_REQUEST_COMPLETE:
+#ifdef RESOURCE_LOADER_DEBUG
+ _snprintf(buf, sizeof(buf), "request-complete: result=%p, error=%u\n",
+ LPINTERNET_ASYNC_RESULT(statusInformation)->dwResult,
+ LPINTERNET_ASYNC_RESULT(statusInformation)->dwError);
+ OutputDebugStringA(buf);
+#endif
+ // tell the main thread that the request is done
+ msg = requestCompleteMessage;
+ lParam = 0;
+ break;
+ case INTERNET_STATUS_REDIRECT:
+ // tell the main thread to observe this redirect (FIXME: we probably
+ // need to block the redirect at this point so the application can
+ // decide whether or not to follow the redirect)
+ msg = requestRedirectedMessage;
+ lParam = (LPARAM) new StringImpl((const UChar*) statusInformation,
+ statusInformationLength);
+ break;
+ case INTERNET_STATUS_USER_INPUT_REQUIRED:
+ // FIXME: prompt the user if necessary
+ ResumeSuspendedDownload(internetHandle, 0);
+ case INTERNET_STATUS_STATE_CHANGE:
+ // may need to call ResumeSuspendedDownload here as well
+ default:
+ return;
+ }
+
+ PostMessage(transferJobWindowHandle, msg, (WPARAM) jobId, lParam);
+}
+
+bool ResourceHandle::start(Frame* frame)
+{
+ ref();
+ if (url().isLocalFile()) {
+ String path = url().path();
+ // windows does not enjoy a leading slash on paths
+ if (path[0] == '/')
+ path = path.substring(1);
+ // FIXME: This is wrong. Need to use wide version of this call.
+ d->m_fileHandle = CreateFileA(path.utf8().data(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ // FIXME: perhaps this error should be reported asynchronously for
+ // consistency.
+ if (d->m_fileHandle == INVALID_HANDLE_VALUE) {
+ delete this;
+ return false;
+ }
+
+ d->m_fileLoadTimer.startOneShot(0.0);
+ return true;
+ } else {
+ static HINTERNET internetHandle = 0;
+ if (!internetHandle) {
+ String userAgentStr = frame->loader()->userAgent() + String("", 1);
+ LPCWSTR userAgent = reinterpret_cast<const WCHAR*>(userAgentStr.characters());
+ // leak the Internet for now
+ internetHandle = InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, INTERNET_FLAG_ASYNC);
+ }
+ if (!internetHandle) {
+ delete this;
+ return false;
+ }
+ static INTERNET_STATUS_CALLBACK callbackHandle =
+ InternetSetStatusCallback(internetHandle, transferJobStatusCallback);
+
+ initializeOffScreenResourceHandleWindow();
+ d->m_jobId = addToOutstandingJobs(this);
+
+ DWORD flags =
+ INTERNET_FLAG_KEEP_CONNECTION |
+ INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS |
+ INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP;
+
+ // For form posting, we can't use InternetOpenURL. We have to use
+ // InternetConnect followed by HttpSendRequest.
+ HINTERNET urlHandle;
+ String referrer = frame->loader()->referrer();
+ if (method() == "POST") {
+ d->m_postReferrer = referrer;
+ String host = url().host();
+ urlHandle = InternetConnectA(internetHandle, host.latin1().data(),
+ url().port(),
+ NULL, // no username
+ NULL, // no password
+ INTERNET_SERVICE_HTTP,
+ flags, (DWORD_PTR)d->m_jobId);
+ } else {
+ String urlStr = url().string();
+ int fragmentIndex = urlStr.find('#');
+ if (fragmentIndex != -1)
+ urlStr = urlStr.left(fragmentIndex);
+ String headers;
+ if (!referrer.isEmpty())
+ headers += String("Referer: ") + referrer + "\r\n";
+
+ urlHandle = InternetOpenUrlA(internetHandle, urlStr.latin1().data(),
+ headers.latin1().data(), headers.length(),
+ flags, (DWORD_PTR)d->m_jobId);
+ }
+
+ if (urlHandle == INVALID_HANDLE_VALUE) {
+ delete this;
+ return false;
+ }
+ d->m_threadId = GetCurrentThreadId();
+
+ return true;
+ }
+}
+
+void ResourceHandle::fileLoadTimer(Timer<ResourceHandle>* timer)
+{
+ ResourceResponse response;
+ client()->didReceiveResponse(this, response);
+
+ bool result = false;
+ DWORD bytesRead = 0;
+
+ do {
+ const int bufferSize = 8192;
+ char buffer[bufferSize];
+ result = ReadFile(d->m_fileHandle, &buffer, bufferSize, &bytesRead, NULL);
+ if (result && bytesRead)
+ client()->didReceiveData(this, buffer, bytesRead, 0);
+ // Check for end of file.
+ } while (result && bytesRead);
+
+ // FIXME: handle errors better
+
+ CloseHandle(d->m_fileHandle);
+ d->m_fileHandle = INVALID_HANDLE_VALUE;
+
+ client()->didFinishLoading(this);
+}
+
+void ResourceHandle::cancel()
+{
+ if (d->m_resourceHandle)
+ InternetCloseHandle(d->m_resourceHandle);
+ else
+ d->m_fileLoadTimer.stop();
+
+ client()->didFinishLoading(this);
+
+ if (!d->m_resourceHandle)
+ // Async load canceled before we have a handle -- mark ourselves as in error, to be deleted later.
+ // FIXME: need real cancel error
+ client()->didFail(this, ResourceError());
+}
+
+void ResourceHandle::setHasReceivedResponse(bool b)
+{
+ d->m_hasReceivedResponse = b;
+}
+
+bool ResourceHandle::hasReceivedResponse() const
+{
+ return d->m_hasReceivedResponse;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/win/ResourceHandleWin.h b/WebCore/platform/network/win/ResourceHandleWin.h
new file mode 100644
index 0000000..2964bcb
--- /dev/null
+++ b/WebCore/platform/network/win/ResourceHandleWin.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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.
+ */
+
+#ifndef ResourceHandleWin_h
+#define ResourceHandleWin_h
+
+#include <windows.h>
+
+namespace WebCore {
+
+struct PlatformDataStruct
+{
+ DWORD error;
+ BOOL loaded;
+ LPTSTR errorString;
+};
+
+struct PlatformResponseStruct
+{
+};
+
+}
+
+#endif