[Curl] Respond with requested authentication scheme for authentication challenge.
authorBasuke.Suzuki@sony.com <Basuke.Suzuki@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Sep 2018 18:19:34 +0000 (18:19 +0000)
committerBasuke.Suzuki@sony.com <Basuke.Suzuki@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Sep 2018 18:19:34 +0000 (18:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=189318

Reviewed by Alex Christensen.

Source/WebCore:

Curl port depends on libcurl's authentication handling by enabling CURLAUTH_ANY. With this
mode, the round-trip communication between the client and the server is handled by libcurl
internally. That's okay for many cases. But when initial request has a credentials
(i.e. XMLHttpRequest), there's no valid chance to store credential to the storage because
the returned response is not 401.

Passes following tests:
- http/tests/websocket/tests/hybi/httponly-cookie.pl
- http/tests/websocket/tests/hybi/secure-cookie-insecure-connection.pl
- http/tests/websocket/tests/hybi/secure-cookie-secure-connection.pl
- http/tests/xmlhttprequest/basic-auth-default.html
- http/tests/xmlhttprequest/cross-origin-authorization.html
- http/tests/xmlhttprequest/logout.html
- http/tests/xmlhttprequest/null-auth.php
- http/tests/xmlhttprequest/re-login-async.html
- http/tests/xmlhttprequest/re-login.html
- http/tests/xmlhttprequest/redirect-credentials-responseURL.html
- http/tests/xmlhttprequest/remember-bad-password.html

* platform/network/ResourceHandle.h:
* platform/network/curl/CurlContext.cpp:
(WebCore::CurlHandle::setHttpAuthUserPass):
(WebCore::CurlHandle::enableHttpAuthentication): Deleted.
* platform/network/curl/CurlContext.h:
* platform/network/curl/CurlRequest.cpp:
(WebCore::CurlRequest::setAuthenticationScheme):
(WebCore::CurlRequest::setupTransfer):
* platform/network/curl/CurlRequest.h:
* platform/network/curl/ResourceHandleCurl.cpp:
(WebCore::ResourceHandle::start):
(WebCore::ResourceHandle::didReceiveAuthenticationChallenge):
(WebCore::ResourceHandle::receivedCredential):
(WebCore::ResourceHandle::getCredential):
(WebCore::ResourceHandle::restartRequestWithCredential):
(WebCore::ResourceHandle::platformLoadResourceSynchronously):
(WebCore::ResourceHandle::continueAfterWillSendRequest):

Source/WebKit:

Curl port depends on libcurl's authentication handling by enabling CURLAUTH_ANY. With this
mode, the round-trip communication between the client and the server is handled by libcurl
internally. That's okay for many cases. But when initial request has a credentials
(i.e. XMLHttpRequest), there's no valid chance to store credential to the storage because
the returned response is not 401.

* NetworkProcess/curl/NetworkDataTaskCurl.cpp:
(WebKit::NetworkDataTaskCurl::NetworkDataTaskCurl):
(WebKit::NetworkDataTaskCurl::willPerformHTTPRedirection):
(WebKit::NetworkDataTaskCurl::tryHttpAuthentication):
(WebKit::NetworkDataTaskCurl::tryProxyAuthentication):
(WebKit::NetworkDataTaskCurl::restartWithCredential):
* NetworkProcess/curl/NetworkDataTaskCurl.h:

LayoutTests:

* platform/wincairo/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236073 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/wincairo/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/platform/network/ResourceHandle.h
Source/WebCore/platform/network/curl/CurlContext.cpp
Source/WebCore/platform/network/curl/CurlContext.h
Source/WebCore/platform/network/curl/CurlRequest.cpp
Source/WebCore/platform/network/curl/CurlRequest.h
Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp
Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h

index 78f3d90..7dd3b8a 100644 (file)
@@ -1,3 +1,12 @@
+2018-09-17  Basuke Suzuki  <Basuke.Suzuki@sony.com>
+
+        [Curl] Respond with requested authentication scheme for authentication challenge.
+        https://bugs.webkit.org/show_bug.cgi?id=189318
+
+        Reviewed by Alex Christensen.
+
+        * platform/wincairo/TestExpectations:
+
 2018-09-17  Antoine Quint  <graouts@apple.com>
 
         [Web Animations] Positive delays of accelerated animations are not respected
index f066602..68f6240 100644 (file)
@@ -921,10 +921,7 @@ http/tests/websocket/tests/hybi/contentextensions [ Failure ]
 http/tests/websocket/tests/hybi/contentextensions/block-cookies.php [ Pass Failure ]
 http/tests/websocket/tests/hybi/contentextensions/block-cookies-worker.php [ Pass Failure ]
 http/tests/websocket/tests/hybi/deflate-frame-parameter.html [ Failure ]
-http/tests/websocket/tests/hybi/httponly-cookie.pl [ Pass Failure ]
 http/tests/websocket/tests/hybi/inspector [ Skip ]
-http/tests/websocket/tests/hybi/secure-cookie-insecure-connection.pl [ Pass Failure ]
-http/tests/websocket/tests/hybi/secure-cookie-secure-connection.pl [ Pass Failure ]
 http/tests/websocket/tests/hybi/upgrade-simple-ws.html [ Pass Failure ]
 http/tests/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party.html [ Pass Failure ]
 http/tests/websocket/tests/hybi/websocket-blocked-from-setting-cookie-as-third-party.html [ Pass Failure ]
@@ -946,28 +943,20 @@ http/tests/xmlhttprequest/access-control-preflight-credential-async.html [ Pass
 http/tests/xmlhttprequest/access-control-preflight-credential-sync.html [ Pass Failure ]
 http/tests/xmlhttprequest/access-control-preflight-not-successful.html [ Failure ]
 http/tests/xmlhttprequest/auth-reject-protection-space.html [ Failure ]
-http/tests/xmlhttprequest/basic-auth-default.html [ Failure ]
 http/tests/xmlhttprequest/basic-auth-nopassword.html [ Failure ]
 http/tests/xmlhttprequest/basic-auth-nouser.html [ Failure ]
 http/tests/xmlhttprequest/cache-override.html [ Pass Failure ]
 http/tests/xmlhttprequest/cookies.html [ Pass Failure ]
 http/tests/xmlhttprequest/cross-origin-authorization-with-embedder.html [ Failure ]
-http/tests/xmlhttprequest/cross-origin-authorization.html [ Failure ]
 http/tests/xmlhttprequest/cross-origin-cookie-storage.html [ Failure ]
 http/tests/xmlhttprequest/cross-origin-no-authorization.html [ Pass Failure ]
-http/tests/xmlhttprequest/logout.html [ Failure ]
-http/tests/xmlhttprequest/null-auth.php [ Pass Failure ]
 http/tests/xmlhttprequest/xmlhttprequest-overridemimetype-content-type-header.html [ Pass Failure ]
-http/tests/xmlhttprequest/re-login-async.html [ Failure ]
-http/tests/xmlhttprequest/re-login.html [ Failure ]
 http/tests/xmlhttprequest/range-test.html [ Pass Failure ]
-http/tests/xmlhttprequest/redirect-credentials-responseURL.html [ Failure ]
 http/tests/xmlhttprequest/redirect-cross-origin-post-sync.html [ Failure ]
 http/tests/xmlhttprequest/redirect-cross-origin-sync.html [ Failure ]
 http/tests/xmlhttprequest/redirect-cross-origin-tripmine.html [ Failure ]
 http/tests/xmlhttprequest/redirections-and-user-headers.html [ Failure ]
 http/tests/xmlhttprequest/referer.html [ Pass Failure ]
-http/tests/xmlhttprequest/remember-bad-password.html [ Failure ]
 http/tests/xmlhttprequest/response-access-on-error.html [ Failure ]
 http/tests/xmlhttprequest/response-empty-arraybuffer.html [ Pass Failure ]
 http/tests/xmlhttprequest/upload-onload-event.html [ Failure ]
index 0f047ef..c53f3ff 100644 (file)
@@ -1,3 +1,47 @@
+2018-09-17  Basuke Suzuki  <Basuke.Suzuki@sony.com>
+
+        [Curl] Respond with requested authentication scheme for authentication challenge.
+        https://bugs.webkit.org/show_bug.cgi?id=189318
+
+        Reviewed by Alex Christensen.
+
+        Curl port depends on libcurl's authentication handling by enabling CURLAUTH_ANY. With this
+        mode, the round-trip communication between the client and the server is handled by libcurl
+        internally. That's okay for many cases. But when initial request has a credentials
+        (i.e. XMLHttpRequest), there's no valid chance to store credential to the storage because
+        the returned response is not 401.
+
+        Passes following tests:
+        - http/tests/websocket/tests/hybi/httponly-cookie.pl
+        - http/tests/websocket/tests/hybi/secure-cookie-insecure-connection.pl
+        - http/tests/websocket/tests/hybi/secure-cookie-secure-connection.pl
+        - http/tests/xmlhttprequest/basic-auth-default.html
+        - http/tests/xmlhttprequest/cross-origin-authorization.html
+        - http/tests/xmlhttprequest/logout.html
+        - http/tests/xmlhttprequest/null-auth.php
+        - http/tests/xmlhttprequest/re-login-async.html
+        - http/tests/xmlhttprequest/re-login.html
+        - http/tests/xmlhttprequest/redirect-credentials-responseURL.html
+        - http/tests/xmlhttprequest/remember-bad-password.html
+
+        * platform/network/ResourceHandle.h:
+        * platform/network/curl/CurlContext.cpp:
+        (WebCore::CurlHandle::setHttpAuthUserPass):
+        (WebCore::CurlHandle::enableHttpAuthentication): Deleted.
+        * platform/network/curl/CurlContext.h:
+        * platform/network/curl/CurlRequest.cpp:
+        (WebCore::CurlRequest::setAuthenticationScheme):
+        (WebCore::CurlRequest::setupTransfer):
+        * platform/network/curl/CurlRequest.h:
+        * platform/network/curl/ResourceHandleCurl.cpp:
+        (WebCore::ResourceHandle::start):
+        (WebCore::ResourceHandle::didReceiveAuthenticationChallenge):
+        (WebCore::ResourceHandle::receivedCredential):
+        (WebCore::ResourceHandle::getCredential):
+        (WebCore::ResourceHandle::restartRequestWithCredential):
+        (WebCore::ResourceHandle::platformLoadResourceSynchronously):
+        (WebCore::ResourceHandle::continueAfterWillSendRequest):
+
 2018-09-17  Youenn Fablet  <youenn@apple.com>
 
         Enable VCP for iOS and reenable it for MacOS
index 90b0fda..01a86e3 100644 (file)
@@ -263,8 +263,8 @@ private:
 
     bool shouldRedirectAsGET(const ResourceRequest&, bool crossOrigin);
 
-    std::optional<std::pair<String, String>> getCredential(ResourceRequest&, bool);
-    void restartRequestWithCredential(const String& user, const String& password);
+    std::optional<Credential> getCredential(const ResourceRequest&, bool);
+    void restartRequestWithCredential(const ProtectionSpace&, const Credential&);
 
     void handleDataURL();
 #endif
index d36478e..9c87807 100644 (file)
@@ -514,15 +514,11 @@ void CurlHandle::enableAllowedProtocols()
     curl_easy_setopt(m_handle, CURLOPT_PROTOCOLS, allowedProtocols);
 }
 
-void CurlHandle::enableHttpAuthentication(long option)
-{
-    curl_easy_setopt(m_handle, CURLOPT_HTTPAUTH, option);
-}
-
-void CurlHandle::setHttpAuthUserPass(const String& user, const String& password)
+void CurlHandle::setHttpAuthUserPass(const String& user, const String& password, long authType)
 {
     curl_easy_setopt(m_handle, CURLOPT_USERNAME, user.utf8().data());
     curl_easy_setopt(m_handle, CURLOPT_PASSWORD, password.utf8().data());
+    curl_easy_setopt(m_handle, CURLOPT_HTTPAUTH, authType);
 }
 
 void CurlHandle::setCACertPath(const char* path)
index 8a94520..7d9711c 100644 (file)
@@ -251,8 +251,7 @@ public:
     void enableAcceptEncoding();
     void enableAllowedProtocols();
 
-    void enableHttpAuthentication(long);
-    void setHttpAuthUserPass(const String&, const String&);
+    void setHttpAuthUserPass(const String&, const String&, long authType = CURLAUTH_ANY);
 
     void setCACertPath(const char*);
     void setSslVerifyPeer(VerifyPeer);
index 2d8aff2..7f11234 100644 (file)
@@ -57,6 +57,31 @@ void CurlRequest::invalidateClient()
     m_messageQueue = nullptr;
 }
 
+void CurlRequest::setAuthenticationScheme(ProtectionSpaceAuthenticationScheme scheme)
+{
+    switch (scheme) {
+    case ProtectionSpaceAuthenticationSchemeHTTPBasic:
+        m_authType = CURLAUTH_BASIC;
+        break;
+
+    case ProtectionSpaceAuthenticationSchemeHTTPDigest:
+        m_authType = CURLAUTH_DIGEST;
+        break;
+
+    case ProtectionSpaceAuthenticationSchemeNTLM:
+        m_authType = CURLAUTH_NTLM;
+        break;
+
+    case ProtectionSpaceAuthenticationSchemeNegotiate:
+        m_authType = CURLAUTH_NEGOTIATE;
+        break;
+
+    default:
+        m_authType = CURLAUTH_ANY;
+        break;
+    }
+}
+
 void CurlRequest::setUserPass(const String& user, const String& password)
 {
     ASSERT(isMainThread());
@@ -186,8 +211,7 @@ CURL* CurlRequest::setupTransfer()
     }
 
     if (!m_user.isEmpty() || !m_password.isEmpty()) {
-        m_curlHandle->enableHttpAuthentication(CURLAUTH_ANY);
-        m_curlHandle->setHttpAuthUserPass(m_user, m_password);
+        m_curlHandle->setHttpAuthUserPass(m_user, m_password, m_authType);
     }
 
     m_curlHandle->setHeaderCallbackFunction(didReceiveHeaderCallback, this);
index 958c777..88ee2ee 100644 (file)
@@ -34,6 +34,7 @@
 #include "CurlSSLVerifier.h"
 #include "FileSystem.h"
 #include "NetworkLoadMetrics.h"
+#include "ProtectionSpace.h"
 #include "ResourceRequest.h"
 #include <wtf/MessageQueue.h>
 #include <wtf/MonotonicTime.h>
@@ -67,6 +68,7 @@ public:
     virtual ~CurlRequest() = default;
 
     void invalidateClient();
+    WEBCORE_EXPORT void setAuthenticationScheme(ProtectionSpaceAuthenticationScheme);
     WEBCORE_EXPORT void setUserPass(const String&, const String&);
     void setStartTime(const MonotonicTime& startTime) { m_requestStartTime = startTime; }
 
@@ -165,6 +167,7 @@ private:
     ResourceRequest m_request;
     String m_user;
     String m_password;
+    unsigned long m_authType { CURLAUTH_ANY };
     bool m_shouldSuspend { false };
     bool m_enableMultipart { false };
 
index 99fe1c1..a4bceb8 100644 (file)
@@ -85,8 +85,10 @@ bool ResourceHandle::start()
 
     d->m_curlRequest = createCurlRequest(WTFMove(request));
 
-    if (auto credential = getCredential(d->m_firstRequest, false))
-        d->m_curlRequest->setUserPass(credential->first, credential->second);
+    if (auto credential = getCredential(d->m_firstRequest, false)) {
+        d->m_curlRequest->setUserPass(credential->user(), credential->password());
+        d->m_curlRequest->setAuthenticationScheme(ProtectionSpaceAuthenticationSchemeHTTPBasic);
+    }
 
     d->m_curlRequest->setStartTime(d->m_startTime);
     d->m_curlRequest->start();
@@ -231,7 +233,7 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
             urlToStore = challenge.failureResponse().url();
         CredentialStorage::defaultCredentialStorage().set(partition, credential, challenge.protectionSpace(), urlToStore);
 
-        restartRequestWithCredential(credential.user(), credential.password());
+        restartRequestWithCredential(challenge.protectionSpace(), credential);
 
         d->m_user = String();
         d->m_pass = String();
@@ -256,7 +258,7 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
                     CredentialStorage::defaultCredentialStorage().set(partition, credential, challenge.protectionSpace(), challenge.failureResponse().url());
                 }
 
-                restartRequestWithCredential(credential.user(), credential.password());
+                restartRequestWithCredential(challenge.protectionSpace(), credential);
                 return;
             }
         }
@@ -291,7 +293,7 @@ void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge
         }
     }
 
-    restartRequestWithCredential(credential.user(), credential.password());
+    restartRequestWithCredential(challenge.protectionSpace(), credential);
 
     clearAuthentication();
 }
@@ -333,13 +335,15 @@ void ResourceHandle::receivedChallengeRejection(const AuthenticationChallenge&)
     ASSERT_NOT_REACHED();
 }
 
-std::optional<std::pair<String, String>> ResourceHandle::getCredential(ResourceRequest& request, bool redirect)
+std::optional<Credential> ResourceHandle::getCredential(const ResourceRequest& request, bool redirect)
 {
     // m_user/m_pass are credentials given manually, for instance, by the arguments passed to XMLHttpRequest.open().
-    String partition = request.cachePartition();
+    Credential credential { d->m_user, d->m_pass, CredentialPersistenceNone };
 
     if (shouldUseCredentialStorage()) {
-        if (d->m_user.isEmpty() && d->m_pass.isEmpty()) {
+        String partition = request.cachePartition();
+
+        if (credential.isEmpty()) {
             // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication, 
             // try and reuse the credential preemptively, as allowed by RFC 2617.
             d->m_initialCredential = CredentialStorage::defaultCredentialStorage().get(partition, request.url());
@@ -348,25 +352,17 @@ std::optional<std::pair<String, String>> ResourceHandle::getCredential(ResourceR
             // before sending a request. This makes it possible to implement logout by sending an
             // XMLHttpRequest with known incorrect credentials, and aborting it immediately (so that
             // an authentication dialog doesn't pop up).
-            CredentialStorage::defaultCredentialStorage().set(partition, Credential(d->m_user, d->m_pass, CredentialPersistenceNone), request.url());
+            CredentialStorage::defaultCredentialStorage().set(partition, credential, request.url());
         }
     }
 
-    String user = d->m_user;
-    String password = d->m_pass;
-
-    if (!d->m_initialCredential.isEmpty()) {
-        user = d->m_initialCredential.user();
-        password = d->m_initialCredential.password();
-    }
-
-    if (user.isEmpty() && password.isEmpty())
-        return std::nullopt;
+    if (!d->m_initialCredential.isEmpty())
+        return d->m_initialCredential;
 
-    return std::pair<String, String>(user, password);
+    return std::nullopt;
 }
 
-void ResourceHandle::restartRequestWithCredential(const String& user, const String& password)
+void ResourceHandle::restartRequestWithCredential(const ProtectionSpace& protectionSpace, const Credential& credential)
 {
     ASSERT(isMainThread());
 
@@ -377,7 +373,8 @@ void ResourceHandle::restartRequestWithCredential(const String& user, const Stri
     d->m_curlRequest->cancel();
 
     d->m_curlRequest = createCurlRequest(WTFMove(previousRequest), RequestStatus::ReusedRequest);
-    d->m_curlRequest->setUserPass(user, password);
+    d->m_curlRequest->setAuthenticationScheme(protectionSpace.authenticationScheme());
+    d->m_curlRequest->setUserPass(credential.user(), credential.password());
     d->m_curlRequest->setStartTime(d->m_startTime);
     d->m_curlRequest->start();
 }
@@ -385,8 +382,11 @@ void ResourceHandle::restartRequestWithCredential(const String& user, const Stri
 void ResourceHandle::platformLoadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentialsPolicy storedCredentialsPolicy, ResourceError& error, ResourceResponse& response, Vector<char>& data)
 {
     ASSERT(isMainThread());
+    ASSERT(!request.isEmpty());
 
     SynchronousLoaderClient client;
+    client.setAllowStoredCredentials(storedCredentialsPolicy == StoredCredentialsPolicy::Use);
+
     bool defersLoading = false;
     bool shouldContentSniff = true;
     bool shouldContentEncodingSniff = true;
@@ -401,6 +401,12 @@ void ResourceHandle::platformLoadResourceSynchronously(NetworkingContext* contex
 
     auto requestCopy = handle->firstRequest();
     handle->d->m_curlRequest = handle->createCurlRequest(WTFMove(requestCopy));
+
+    if (auto credential = handle->getCredential(handle->d->m_firstRequest, false)) {
+        handle->d->m_curlRequest->setUserPass(credential->user(), credential->password());
+        handle->d->m_curlRequest->setAuthenticationScheme(ProtectionSpaceAuthenticationSchemeHTTPBasic);
+    }
+
     handle->d->m_curlRequest->setStartTime(handle->d->m_startTime);
     handle->d->m_curlRequest->start();
 
@@ -518,7 +524,7 @@ void ResourceHandle::continueAfterWillSendRequest(ResourceRequest&& request)
     d->m_curlRequest = createCurlRequest(WTFMove(request));
 
     if (shouldForwardCredential && credential)
-        d->m_curlRequest->setUserPass(credential->first, credential->second);
+        d->m_curlRequest->setUserPass(credential->user(), credential->password());
 
     d->m_curlRequest->setStartTime(d->m_startTime);
     d->m_curlRequest->start();
index 766af6b..59d20db 100644 (file)
@@ -1,3 +1,24 @@
+2018-09-17  Basuke Suzuki  <Basuke.Suzuki@sony.com>
+
+        [Curl] Respond with requested authentication scheme for authentication challenge.
+        https://bugs.webkit.org/show_bug.cgi?id=189318
+
+        Reviewed by Alex Christensen.
+
+        Curl port depends on libcurl's authentication handling by enabling CURLAUTH_ANY. With this
+        mode, the round-trip communication between the client and the server is handled by libcurl
+        internally. That's okay for many cases. But when initial request has a credentials
+        (i.e. XMLHttpRequest), there's no valid chance to store credential to the storage because
+        the returned response is not 401.
+
+        * NetworkProcess/curl/NetworkDataTaskCurl.cpp:
+        (WebKit::NetworkDataTaskCurl::NetworkDataTaskCurl):
+        (WebKit::NetworkDataTaskCurl::willPerformHTTPRedirection):
+        (WebKit::NetworkDataTaskCurl::tryHttpAuthentication):
+        (WebKit::NetworkDataTaskCurl::tryProxyAuthentication):
+        (WebKit::NetworkDataTaskCurl::restartWithCredential):
+        * NetworkProcess/curl/NetworkDataTaskCurl.h:
+
 2018-09-17  Woodrow Wang  <woodrow_wang@apple.com>
 
         Clear pending resource load statistics' writes after tests
index 183b219..4d50467 100644 (file)
@@ -64,8 +64,10 @@ NetworkDataTaskCurl::NetworkDataTaskCurl(NetworkSession& session, NetworkDataTas
     }
 
     m_curlRequest = createCurlRequest(WTFMove(request));
-    if (!m_initialCredential.isEmpty())
+    if (!m_initialCredential.isEmpty()) {
         m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
+        m_curlRequest->setAuthenticationScheme(ProtectionSpaceAuthenticationSchemeHTTPBasic);
+    }
     m_curlRequest->setStartTime(m_startTime);
     m_curlRequest->start();
 }
@@ -311,8 +313,10 @@ void NetworkDataTaskCurl::willPerformHTTPRedirection()
 
         auto requestCopy = newRequest;
         m_curlRequest = createCurlRequest(WTFMove(requestCopy));
-        if (didChangeCredential && !m_initialCredential.isEmpty())
+        if (didChangeCredential && !m_initialCredential.isEmpty()) {
             m_curlRequest->setUserPass(m_initialCredential.user(), m_initialCredential.password());
+            m_curlRequest->setAuthenticationScheme(ProtectionSpaceAuthenticationSchemeHTTPBasic);
+        }
         m_curlRequest->setStartTime(m_startTime);
         m_curlRequest->start();
 
@@ -327,7 +331,7 @@ void NetworkDataTaskCurl::tryHttpAuthentication(AuthenticationChallenge&& challe
 {
     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));
+        restartWithCredential(challenge.protectionSpace(), Credential(m_user, m_password, persistence));
         m_user = String();
         m_password = String();
         return;
@@ -349,7 +353,7 @@ void NetworkDataTaskCurl::tryHttpAuthentication(AuthenticationChallenge&& challe
                     // 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);
+                restartWithCredential(challenge.protectionSpace(), credential);
                 return;
             }
         }
@@ -377,7 +381,7 @@ void NetworkDataTaskCurl::tryHttpAuthentication(AuthenticationChallenge&& challe
                     m_session->networkStorageSession().credentialStorage().set(m_partition, credential, challenge.protectionSpace(), challenge.failureResponse().url());
             }
 
-            restartWithCredential(credential);
+            restartWithCredential(challenge.protectionSpace(), credential);
             return;
         }
 
@@ -405,7 +409,7 @@ void NetworkDataTaskCurl::tryProxyAuthentication(WebCore::AuthenticationChalleng
             CurlContext::singleton().setDefaultProxyAuthMethod();
 
             auto requestCredential = m_curlRequest ? Credential(m_curlRequest->user(), m_curlRequest->password(), CredentialPersistenceNone) : Credential();
-            restartWithCredential(requestCredential);
+            restartWithCredential(challenge.protectionSpace(), requestCredential);
             return;
         }
 
@@ -413,7 +417,7 @@ void NetworkDataTaskCurl::tryProxyAuthentication(WebCore::AuthenticationChalleng
     });
 }
 
-void NetworkDataTaskCurl::restartWithCredential(const Credential& credential)
+void NetworkDataTaskCurl::restartWithCredential(const ProtectionSpace& protectionSpace, const Credential& credential)
 {
     ASSERT(m_curlRequest);
 
@@ -421,6 +425,7 @@ void NetworkDataTaskCurl::restartWithCredential(const Credential& credential)
     m_curlRequest->cancel();
 
     m_curlRequest = createCurlRequest(WTFMove(previousRequest), RequestStatus::ReusedRequest);
+    m_curlRequest->setAuthenticationScheme(protectionSpace.authenticationScheme());
     m_curlRequest->setUserPass(credential.user(), credential.password());
     m_curlRequest->setStartTime(m_startTime);
     m_curlRequest->start();
index 25c1a83..cb97360 100644 (file)
@@ -28,6 +28,7 @@
 #include "CurlRequestClient.h"
 #include "NetworkDataTask.h"
 #include <WebCore/NetworkLoadMetrics.h>
+#include <WebCore/ProtectionSpace.h>
 #include <WebCore/ResourceResponse.h>
 
 namespace WebCore {
@@ -76,7 +77,7 @@ private:
 
     void tryHttpAuthentication(WebCore::AuthenticationChallenge&&);
     void tryProxyAuthentication(WebCore::AuthenticationChallenge&&);
-    void restartWithCredential(const WebCore::Credential&);
+    void restartWithCredential(const WebCore::ProtectionSpace&, const WebCore::Credential&);
 
     void appendCookieHeader(WebCore::ResourceRequest&);
     void handleCookieHeaders(const WebCore::CurlResponse&);