Title: [230551] trunk/Source/WebKit
Revision
230551
Author
hironori.fu...@sony.com
Date
2018-04-11 17:53:26 -0700 (Wed, 11 Apr 2018)

Log Message

[curl][WebKit] Implement NetworkDataTaskCurl
https://bugs.webkit.org/show_bug.cgi?id=184488

Reviewed by Alex Christensen.

* NetworkProcess/NetworkDataTask.cpp:
(WebKit::NetworkDataTask::create):
* NetworkProcess/curl/NetworkDataTaskCurl.cpp: Added.
(WebKit::NetworkDataTaskCurl::NetworkDataTaskCurl):
(WebKit::NetworkDataTaskCurl::~NetworkDataTaskCurl):
(WebKit::NetworkDataTaskCurl::resume):
(WebKit::NetworkDataTaskCurl::suspend):
(WebKit::NetworkDataTaskCurl::cancel):
(WebKit::NetworkDataTaskCurl::invalidateAndCancel):
(WebKit::NetworkDataTaskCurl::state const):
(WebKit::NetworkDataTaskCurl::createCurlRequest):
(WebKit::NetworkDataTaskCurl::curlDidSendData):
(WebKit::NetworkDataTaskCurl::curlDidReceiveResponse):
(WebKit::NetworkDataTaskCurl::curlDidReceiveBuffer):
(WebKit::NetworkDataTaskCurl::curlDidComplete):
(WebKit::NetworkDataTaskCurl::curlDidFailWithError):
(WebKit::NetworkDataTaskCurl::shouldRedirectAsGET):
(WebKit::NetworkDataTaskCurl::willPerformHTTPRedirection):
(WebKit::NetworkDataTaskCurl::tryHttpAuthentication):
(WebKit::NetworkDataTaskCurl::restartWithCredential):
(WebKit::NetworkDataTaskCurl::appendCookieHeader):
(WebKit::NetworkDataTaskCurl::handleCookieHeaders):
* NetworkProcess/curl/NetworkDataTaskCurl.h: Added.
* PlatformWin.cmake:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (230550 => 230551)


--- trunk/Source/WebKit/ChangeLog	2018-04-11 22:46:55 UTC (rev 230550)
+++ trunk/Source/WebKit/ChangeLog	2018-04-12 00:53:26 UTC (rev 230551)
@@ -1,3 +1,35 @@
+2018-04-11  Fujii Hironori  <hironori.fu...@sony.com>
+
+        [curl][WebKit] Implement NetworkDataTaskCurl
+        https://bugs.webkit.org/show_bug.cgi?id=184488
+
+        Reviewed by Alex Christensen.
+
+        * NetworkProcess/NetworkDataTask.cpp:
+        (WebKit::NetworkDataTask::create):
+        * NetworkProcess/curl/NetworkDataTaskCurl.cpp: Added.
+        (WebKit::NetworkDataTaskCurl::NetworkDataTaskCurl):
+        (WebKit::NetworkDataTaskCurl::~NetworkDataTaskCurl):
+        (WebKit::NetworkDataTaskCurl::resume):
+        (WebKit::NetworkDataTaskCurl::suspend):
+        (WebKit::NetworkDataTaskCurl::cancel):
+        (WebKit::NetworkDataTaskCurl::invalidateAndCancel):
+        (WebKit::NetworkDataTaskCurl::state const):
+        (WebKit::NetworkDataTaskCurl::createCurlRequest):
+        (WebKit::NetworkDataTaskCurl::curlDidSendData):
+        (WebKit::NetworkDataTaskCurl::curlDidReceiveResponse):
+        (WebKit::NetworkDataTaskCurl::curlDidReceiveBuffer):
+        (WebKit::NetworkDataTaskCurl::curlDidComplete):
+        (WebKit::NetworkDataTaskCurl::curlDidFailWithError):
+        (WebKit::NetworkDataTaskCurl::shouldRedirectAsGET):
+        (WebKit::NetworkDataTaskCurl::willPerformHTTPRedirection):
+        (WebKit::NetworkDataTaskCurl::tryHttpAuthentication):
+        (WebKit::NetworkDataTaskCurl::restartWithCredential):
+        (WebKit::NetworkDataTaskCurl::appendCookieHeader):
+        (WebKit::NetworkDataTaskCurl::handleCookieHeaders):
+        * NetworkProcess/curl/NetworkDataTaskCurl.h: Added.
+        * PlatformWin.cmake:
+
 2018-04-11  Wenson Hsieh  <wenson_hs...@apple.com>
 
         [Extra zoom mode] Support pushing input view controllers onto the navigation stack

Modified: trunk/Source/WebKit/NetworkProcess/NetworkDataTask.cpp (230550 => 230551)


--- trunk/Source/WebKit/NetworkProcess/NetworkDataTask.cpp	2018-04-11 22:46:55 UTC (rev 230550)
+++ trunk/Source/WebKit/NetworkProcess/NetworkDataTask.cpp	2018-04-12 00:53:26 UTC (rev 230551)
@@ -40,6 +40,9 @@
 #if USE(SOUP)
 #include "NetworkDataTaskSoup.h"
 #endif
+#if USE(CURL)
+#include "NetworkDataTaskCurl.h"
+#endif
 
 using namespace WebCore;
 
@@ -56,6 +59,9 @@
 #if USE(SOUP)
     return NetworkDataTaskSoup::create(session, client, parameters.request, parameters.storedCredentialsPolicy, parameters.contentSniffingPolicy, parameters.contentEncodingSniffingPolicy, parameters.shouldClearReferrerOnHTTPSToHTTPRedirect);
 #endif
+#if USE(CURL)
+    return NetworkDataTaskCurl::create(session, client, parameters.request, parameters.storedCredentialsPolicy, parameters.contentSniffingPolicy, parameters.contentEncodingSniffingPolicy, parameters.shouldClearReferrerOnHTTPSToHTTPRedirect);
+#endif
 }
 
 NetworkDataTask::NetworkDataTask(NetworkSession& session, NetworkDataTaskClient& client, const ResourceRequest& requestWithCredentials, StoredCredentialsPolicy storedCredentialsPolicy, bool shouldClearReferrerOnHTTPSToHTTPRedirect)

Added: trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp (0 => 230551)


--- trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp	2018-04-12 00:53:26 UTC (rev 230551)
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2018 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "NetworkDataTaskCurl.h"
+
+#include "AuthenticationManager.h"
+#include "NetworkSessionCurl.h"
+#include <WebCore/AuthenticationChallenge.h>
+#include <WebCore/CookiesStrategy.h>
+#include <WebCore/CurlRequest.h>
+#include <WebCore/NetworkStorageSession.h>
+#include <WebCore/NotImplemented.h>
+#include <WebCore/ResourceError.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+NetworkDataTaskCurl::NetworkDataTaskCurl(NetworkSession& session, NetworkDataTaskClient& client, const ResourceRequest& requestWithCredentials, StoredCredentialsPolicy storedCredentialsPolicy, ContentSniffingPolicy shouldContentSniff, ContentEncodingSniffingPolicy, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
+    : NetworkDataTask(session, client, requestWithCredentials, storedCredentialsPolicy, shouldClearReferrerOnHTTPSToHTTPRedirect)
+{
+    if (m_scheduledFailureType != NoFailure)
+        return;
+
+    auto request = requestWithCredentials;
+    if (request.url().protocolIsInHTTPFamily()) {
+        if (m_storedCredentialsPolicy == StoredCredentialsPolicy::Use) {
+            auto url = ""
+            m_user = url.user();
+            m_password = url.pass();
+            request.removeCredentials();
+
+            if (m_user.isEmpty() && m_password.isEmpty())
+                m_initialCredential = m_session->networkStorageSession().credentialStorage().get(m_partition, request.url());
+            else
+                m_session->networkStorageSession().credentialStorage().set(m_partition, Credential(m_user, m_password, CredentialPersistenceNone), request.url());
+        }
+    }
+
+    m_curlRequest = createCurlRequest(request, ShouldPreprocess::Yes);
+    if (!m_initialCredential.isEmpty())
+        m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
+    m_curlRequest->start();
+}
+
+NetworkDataTaskCurl::~NetworkDataTaskCurl()
+{
+    if (m_curlRequest)
+        m_curlRequest->invalidateClient();
+}
+
+void NetworkDataTaskCurl::resume()
+{
+    ASSERT(m_state != State::Running);
+    if (m_state == State::Canceling || m_state == State::Completed)
+        return;
+
+    m_state = State::Running;
+
+    if (m_scheduledFailureType != NoFailure) {
+        ASSERT(m_failureTimer.isActive());
+        return;
+    }
+
+    if (m_curlRequest)
+        m_curlRequest->resume();
+}
+
+void NetworkDataTaskCurl::suspend()
+{
+    ASSERT(m_state != State::Suspended);
+    if (m_state == State::Canceling || m_state == State::Completed)
+        return;
+
+    m_state = State::Suspended;
+
+    if (m_curlRequest)
+        m_curlRequest->suspend();
+}
+
+void NetworkDataTaskCurl::cancel()
+{
+    if (m_state == State::Canceling || m_state == State::Completed)
+        return;
+
+    m_state = State::Canceling;
+
+    if (m_curlRequest)
+        m_curlRequest->cancel();
+}
+
+void NetworkDataTaskCurl::invalidateAndCancel()
+{
+    cancel();
+
+    if (m_curlRequest)
+        m_curlRequest->invalidateClient();
+}
+
+NetworkDataTask::State NetworkDataTaskCurl::state() const
+{
+    return m_state;
+}
+
+Ref<CurlRequest> NetworkDataTaskCurl::createCurlRequest(const ResourceRequest& request, ShouldPreprocess shouldPreprocess)
+{
+    m_currentRequest = request;
+
+    if (shouldPreprocess == ShouldPreprocess::Yes)
+        appendCookieHeader(m_currentRequest);
+
+    // Creates a CurlRequest in suspended state.
+    // Then, NetworkDataTaskCurl::resume() will be called and communication resumes.
+    return CurlRequest::create(m_currentRequest, *this, CurlRequest::ShouldSuspend::Yes);
+}
+
+void NetworkDataTaskCurl::curlDidSendData(CurlRequest&, unsigned long long totalBytesSent, unsigned long long totalBytesExpectedToSend)
+{
+    auto protectedThis = makeRef(*this);
+    if (state() == State::Canceling || state() == State::Completed || !m_client)
+        return;
+
+    m_client->didSendData(totalBytesSent, totalBytesExpectedToSend);
+}
+
+void NetworkDataTaskCurl::curlDidReceiveResponse(CurlRequest&, const CurlResponse& receivedResponse)
+{
+    auto protectedThis = makeRef(*this);
+    if (state() == State::Canceling || state() == State::Completed || !m_client)
+        return;
+
+    m_response = ResourceResponse(receivedResponse);
+
+    handleCookieHeaders(receivedResponse);
+
+    if (m_response.shouldRedirect()) {
+        willPerformHTTPRedirection();
+        return;
+    }
+
+    if (m_response.isUnauthorized()) {
+        tryHttpAuthentication(AuthenticationChallenge(receivedResponse, m_authFailureCount, m_response));
+        m_authFailureCount++;
+        return;
+    }
+
+    didReceiveResponse(ResourceResponse(m_response), [this, protectedThis = makeRef(*this)](PolicyAction policyAction) {
+        if (m_state == State::Canceling || m_state == State::Completed)
+            return;
+
+        switch (policyAction) {
+        case PolicyAction::Use:
+            if (m_curlRequest)
+                m_curlRequest->completeDidReceiveResponse();
+            break;
+        case PolicyAction::Ignore:
+            break;
+        case PolicyAction::Download:
+            notImplemented();
+            break;
+        }
+    });
+}
+
+void NetworkDataTaskCurl::curlDidReceiveBuffer(CurlRequest&, Ref<SharedBuffer>&& buffer)
+{
+    auto protectedThis = makeRef(*this);
+    if (state() == State::Canceling || state() == State::Completed || (!m_client && !isDownload()))
+        return;
+
+    m_client->didReceiveData(WTFMove(buffer));
+}
+
+void NetworkDataTaskCurl::curlDidComplete(CurlRequest& request)
+{
+    if (state() == State::Canceling || state() == State::Completed || (!m_client && !isDownload()))
+        return;
+
+    m_response.setDeprecatedNetworkLoadMetrics(request.getNetworkLoadMetrics());
+
+    m_client->didCompleteWithError({ }, m_response.deprecatedNetworkLoadMetrics());
+}
+
+void NetworkDataTaskCurl::curlDidFailWithError(CurlRequest&, const ResourceError& resourceError)
+{
+    if (state() == State::Canceling || state() == State::Completed || (!m_client && !isDownload()))
+        return;
+
+    m_client->didCompleteWithError(resourceError);
+}
+
+bool NetworkDataTaskCurl::shouldRedirectAsGET(const ResourceRequest& request, bool crossOrigin)
+{
+    if (request.httpMethod() == "GET" || request.httpMethod() == "HEAD")
+        return false;
+
+    if (!request.url().protocolIsInHTTPFamily())
+        return true;
+
+    if (m_response.isSeeOther())
+        return true;
+
+    if ((m_response.isMovedPermanently() || m_response.isFound()) && (request.httpMethod() == "POST"))
+        return true;
+
+    if (crossOrigin && (request.httpMethod() == "DELETE"))
+        return true;
+
+    return false;
+}
+
+void NetworkDataTaskCurl::willPerformHTTPRedirection()
+{
+    static const int maxRedirects = 20;
+
+    if (m_redirectCount++ > maxRedirects) {
+        m_client->didCompleteWithError(ResourceError::httpError(CURLE_TOO_MANY_REDIRECTS, m_response.url()));
+        return;
+    }
+
+    ResourceRequest request = m_currentRequest;
+    URL redirectedURL = URL(m_response.url(), m_response.httpHeaderField(HTTPHeaderName::Location));
+    if (!redirectedURL.hasFragmentIdentifier() && request.url().hasFragmentIdentifier())
+        redirectedURL.setFragmentIdentifier(request.url().fragmentIdentifier());
+    request.setURL(redirectedURL);
+
+    // Should not set Referer after a redirect from a secure resource to non-secure one.
+    if (m_shouldClearReferrerOnHTTPSToHTTPRedirect && !request.url().protocolIs("https") && protocolIs(request.httpReferrer(), "https"))
+        request.clearHTTPReferrer();
+
+    bool isCrossOrigin = !protocolHostAndPortAreEqual(m_currentRequest.url(), request.url());
+    if (!equalLettersIgnoringASCIICase(request.httpMethod(), "get")) {
+        // Change request method to GET if change was made during a previous redirection or if current redirection says so.
+        if (!request.url().protocolIsInHTTPFamily() || shouldRedirectAsGET(request, isCrossOrigin)) {
+            request.setHTTPMethod("GET");
+            request.setHTTPBody(nullptr);
+            request.clearHTTPContentType();
+        }
+    }
+
+    bool didChangeCredential = false;
+    const auto& url = ""
+    m_user = url.user();
+    m_password = url.pass();
+    m_lastHTTPMethod = request.httpMethod();
+    request.removeCredentials();
+
+    if (isCrossOrigin) {
+        // The network layer might carry over some headers from the original request that
+        // we want to strip here because the redirect is cross-origin.
+        request.clearHTTPAuthorization();
+        request.clearHTTPOrigin();
+    } else if (m_storedCredentialsPolicy == StoredCredentialsPolicy::Use) {
+        // Only consider applying authentication credentials if this is actually a redirect and the redirect
+        // URL didn't include credentials of its own.
+        if (m_user.isEmpty() && m_password.isEmpty()) {
+            auto credential = m_session->networkStorageSession().credentialStorage().get(m_partition, request.url());
+            if (!credential.isEmpty()) {
+                m_initialCredential = credential;
+                didChangeCredential = true;
+            }
+        }
+    }
+
+    auto response = ResourceResponse(m_response);
+    m_client->willPerformHTTPRedirection(WTFMove(response), WTFMove(request), [this, protectedThis = makeRef(*this), didChangeCredential](const ResourceRequest& newRequest) {
+        if (newRequest.isNull() || m_state == State::Canceling)
+            return;
+
+        if (m_curlRequest)
+            m_curlRequest->cancel();
+
+        m_curlRequest = createCurlRequest(newRequest, ShouldPreprocess::Yes);
+        if (didChangeCredential && !m_initialCredential.isEmpty())
+            m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
+        m_curlRequest->start();
+
+        if (m_state != State::Suspended) {
+            m_state = State::Suspended;
+            resume();
+        }
+    });
+}
+
+void NetworkDataTaskCurl::tryHttpAuthentication(const AuthenticationChallenge& challenge)
+{
+    if (!m_user.isNull() && !m_password.isNull()) {
+        auto persistence = m_storedCredentialsPolicy == WebCore::StoredCredentialsPolicy::Use ? WebCore::CredentialPersistenceForSession : WebCore::CredentialPersistenceNone;
+        restartWithCredential(Credential(m_user, m_password, persistence));
+        m_user = String();
+        m_password = String();
+        return;
+    }
+
+    if (m_storedCredentialsPolicy == StoredCredentialsPolicy::Use) {
+        if (!m_initialCredential.isEmpty() || challenge.previousFailureCount()) {
+            // The stored credential wasn't accepted, stop using it. There is a race condition
+            // here, since a different credential might have already been stored by another
+            // NetworkDataTask, but the observable effect should be very minor, if any.
+            m_session->networkStorageSession().credentialStorage().remove(m_partition, challenge.protectionSpace());
+        }
+
+        if (!challenge.previousFailureCount()) {
+            auto credential = m_session->networkStorageSession().credentialStorage().get(m_partition, challenge.protectionSpace());
+            if (!credential.isEmpty() && credential != m_initialCredential) {
+                ASSERT(credential.persistence() == CredentialPersistenceNone);
+                if (challenge.failureResponse().isUnauthorized()) {
+                    // Store the credential back, possibly adding it as a default for this directory.
+                    m_session->networkStorageSession().credentialStorage().set(m_partition, credential, challenge.protectionSpace(), challenge.failureResponse().url());
+                }
+                restartWithCredential(credential);
+                return;
+            }
+        }
+    }
+
+    m_client->didReceiveChallenge(challenge, [this, protectedThis = makeRef(*this), challenge](AuthenticationChallengeDisposition disposition, const Credential& credential) {
+        if (m_state == State::Canceling || m_state == State::Completed)
+            return;
+
+        if (disposition == AuthenticationChallengeDisposition::Cancel) {
+            cancel();
+            m_client->didCompleteWithError(ResourceError::httpError(CURLE_COULDNT_RESOLVE_HOST, m_response.url()));
+            return;
+        }
+
+        if (disposition == AuthenticationChallengeDisposition::UseCredential && !credential.isEmpty()) {
+            if (m_storedCredentialsPolicy == StoredCredentialsPolicy::Use) {
+                if (credential.persistence() == CredentialPersistenceForSession || credential.persistence() == CredentialPersistencePermanent)
+                    m_session->networkStorageSession().credentialStorage().set(m_partition, credential, challenge.protectionSpace(), challenge.failureResponse().url());
+            }
+        }
+
+        restartWithCredential(credential);
+    });
+}
+
+void NetworkDataTaskCurl::restartWithCredential(const Credential& credential)
+{
+    if (m_curlRequest)
+        m_curlRequest->cancel();
+
+    m_curlRequest = createCurlRequest(m_currentRequest, ShouldPreprocess::No);
+    if (!credential.isEmpty())
+        m_curlRequest->setUserPass(credential.user(), credential.password());
+    m_curlRequest->start();
+
+    if (m_state != State::Suspended) {
+        m_state = State::Suspended;
+        resume();
+    }
+}
+
+void NetworkDataTaskCurl::appendCookieHeader(WebCore::ResourceRequest& request)
+{
+    const auto& storageSession = m_session->networkStorageSession();
+    const auto& cookieJar = storageSession.cookieStorage();
+    auto includeSecureCookies = request.url().protocolIs("https") ? IncludeSecureCookies::Yes : IncludeSecureCookies::No;
+    auto cookieHeaderField = cookieJar.cookieRequestHeaderFieldValue(storageSession, request.firstPartyForCookies(), request.url(), std::nullopt, std::nullopt, includeSecureCookies).first;
+    if (!cookieHeaderField.isEmpty())
+        request.addHTTPHeaderField(HTTPHeaderName::Cookie, cookieHeaderField);
+}
+
+void NetworkDataTaskCurl::handleCookieHeaders(const CurlResponse& response)
+{
+    static const auto setCookieHeader = "set-cookie: ";
+
+    const auto& storageSession = m_session->networkStorageSession();
+    const auto& cookieJar = storageSession.cookieStorage();
+    for (auto header : response.headers) {
+        if (header.startsWithIgnoringASCIICase(setCookieHeader)) {
+            String setCookieString = header.right(header.length() - strlen(setCookieHeader));
+            cookieJar.setCookiesFromHTTPResponse(storageSession, response.url, setCookieString);
+        }
+    }
+}
+
+} // namespace WebKit

Added: trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h (0 => 230551)


--- trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h	2018-04-12 00:53:26 UTC (rev 230551)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
+ */
+
+#pragma once
+
+#include "CurlRequestClient.h"
+#include "NetworkDataTask.h"
+#include <WebCore/NetworkLoadMetrics.h>
+#include <WebCore/ResourceResponse.h>
+
+namespace WebCore {
+class CurlRequest;
+}
+
+namespace WebKit {
+
+class NetworkDataTaskCurl final : public NetworkDataTask, public WebCore::CurlRequestClient {
+public:
+    static Ref<NetworkDataTask> create(NetworkSession& session, NetworkDataTaskClient& client, const WebCore::ResourceRequest& request, WebCore::StoredCredentialsPolicy storedCredentialsPolicy, WebCore::ContentSniffingPolicy shouldContentSniff, WebCore::ContentEncodingSniffingPolicy shouldContentEncodingSniff, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
+    {
+        return adoptRef(*new NetworkDataTaskCurl(session, client, request, storedCredentialsPolicy, shouldContentSniff, shouldContentEncodingSniff, shouldClearReferrerOnHTTPSToHTTPRedirect));
+    }
+
+    ~NetworkDataTaskCurl();
+
+    void ref() override { RefCounted<NetworkDataTask>::ref(); }
+    void deref() override { RefCounted<NetworkDataTask>::deref(); }
+
+private:
+    enum class ShouldPreprocess : bool {
+        No = false,
+        Yes = true
+    };
+
+    NetworkDataTaskCurl(NetworkSession&, NetworkDataTaskClient&, const WebCore::ResourceRequest&, WebCore::StoredCredentialsPolicy, WebCore::ContentSniffingPolicy, WebCore::ContentEncodingSniffingPolicy, bool shouldClearReferrerOnHTTPSToHTTPRedirect);
+
+    void suspend() override;
+    void cancel() override;
+    void resume() override;
+    void invalidateAndCancel() override;
+    NetworkDataTask::State state() const override;
+
+    Ref<WebCore::CurlRequest> createCurlRequest(const WebCore::ResourceRequest&, ShouldPreprocess);
+    void curlDidSendData(WebCore::CurlRequest&, unsigned long long, unsigned long long) override;
+    void curlDidReceiveResponse(WebCore::CurlRequest&, const WebCore::CurlResponse&) override;
+    void curlDidReceiveBuffer(WebCore::CurlRequest&, Ref<WebCore::SharedBuffer>&&) override;
+    void curlDidComplete(WebCore::CurlRequest&) override;
+    void curlDidFailWithError(WebCore::CurlRequest&, const WebCore::ResourceError&) override;
+
+    bool shouldRedirectAsGET(const WebCore::ResourceRequest&, bool crossOrigin);
+    void willPerformHTTPRedirection();
+
+    void tryHttpAuthentication(const WebCore::AuthenticationChallenge&);
+    void restartWithCredential(const WebCore::Credential&);
+
+    void appendCookieHeader(WebCore::ResourceRequest&);
+    void handleCookieHeaders(const WebCore::CurlResponse&);
+
+    State m_state { State::Suspended };
+
+    WebCore::ResourceRequest m_currentRequest;
+    RefPtr<WebCore::CurlRequest> m_curlRequest;
+    WebCore::ResourceResponse m_response;
+    unsigned m_redirectCount { 0 };
+    unsigned m_authFailureCount { 0 };
+};
+
+} // namespace WebKit

Modified: trunk/Source/WebKit/PlatformWin.cmake (230550 => 230551)


--- trunk/Source/WebKit/PlatformWin.cmake	2018-04-11 22:46:55 UTC (rev 230550)
+++ trunk/Source/WebKit/PlatformWin.cmake	2018-04-12 00:53:26 UTC (rev 230551)
@@ -119,6 +119,7 @@
         NetworkProcess/cache/NetworkCacheDataCurl.cpp
         NetworkProcess/cache/NetworkCacheIOChannelCurl.cpp
 
+        NetworkProcess/curl/NetworkDataTaskCurl.cpp
         NetworkProcess/curl/NetworkProcessCurl.cpp
         NetworkProcess/curl/RemoteNetworkingContextCurl.cpp
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to