<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[197526] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/197526">197526</a></dd>
<dt>Author</dt> <dd>achristensen@apple.com</dd>
<dt>Date</dt> <dd>2016-03-03 16:21:34 -0800 (Thu, 03 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Use CredentialStorage with NetworkSession
https://bugs.webkit.org/show_bug.cgi?id=154939

Reviewed by Darin Adler.

Source/WebCore:

This makes the credential-based http tests pass when using NetworkSession.

* platform/network/CredentialBase.h:
(WebCore::CredentialBase::encodingRequiresPlatformData):
* platform/network/CredentialStorage.h:
WEBCORE_EXPORT more things that are newly used in WebKit2.

Source/WebKit2:

* config.h:
Added compile-time flag to help us be able to keep track and remove this code when we can.
* NetworkProcess/NetworkDataTask.h:
(WebKit::NetworkDataTask::pendingDownloadLocation):
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::clearCachedCredentials):
(WebKit::NetworkProcess::ensurePrivateBrowsingSession):
* NetworkProcess/NetworkSession.h:
(WebKit::NetworkSession::sessionID):
* NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
(WebKit::applyBasicAuthorizationHeader):
(WebKit::NetworkDataTask::NetworkDataTask):
Use a credential storage and preemptively apply basic authentication headers if we have credentials from the storage.
This is analogous to code in ResourceHandle::createNSURLConnection.
        
(WebKit::NetworkDataTask::didReceiveChallenge):
Make this look more like ResourceHandle::didReceiveAuthenticationChallenge.
The call to tryPasswordBasedAuthentication was moved from the delegate callback to here.
        
(WebKit::NetworkDataTask::willPerformHTTPRedirection):
Use credentials from the credential storage if they exist.  This is analogous to code in ResourceHandle::willSendRequest.
        
(WebKit::NetworkDataTask::tryPasswordBasedAuthentication):
Use credentials from the credential storage if they exist.  This is analogous to code in ResourceHandle::tryHandlePasswordBasedAuthentication.
        
* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(-[WKNetworkSessionDelegate URLSession:task:didReceiveChallenge:completionHandler:]):
If we are given a credential with CredentialPersistenceForSession, put it in the credential storage and give 
CFNetwork a credential with CredentialPersistenceNone so it won't automatically be used again until the credential
storage says its ok to use again.  This gives us the ability to clear session credentials when logout credentials are used.
This is analogous to code in ResourceHandle::receivedCredential.
        
(WebKit::NetworkSession::defaultSession):
(WebKit::NetworkSession::NetworkSession):
(WebKit::NetworkSession::~NetworkSession):
(WebKit::NetworkSession::dataTaskForIdentifier):
(WebKit::NetworkSession::clearCredentials): Deleted.
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::clearCachedCredentials):
(WebKit::WebProcess::focusedWebPage):
We no longer need to clear credentials from the NSURLSessions because we don't store session credentials in them.
Instead, calling CredentialStorage.clearCredentials is sufficient.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkCredentialBaseh">trunk/Source/WebCore/platform/network/CredentialBase.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkCredentialStorageh">trunk/Source/WebCore/platform/network/CredentialStorage.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkDataTaskh">trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkProcesscpp">trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkSessionh">trunk/Source/WebKit2/NetworkProcess/NetworkSession.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscocoaNetworkDataTaskCocoamm">trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscocoaNetworkSessionCocoamm">trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcesscpp">trunk/Source/WebKit2/WebProcess/WebProcess.cpp</a></li>
<li><a href="#trunkSourceWebKit2configh">trunk/Source/WebKit2/config.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (197525 => 197526)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-03-03 23:57:13 UTC (rev 197525)
+++ trunk/Source/WebCore/ChangeLog        2016-03-04 00:21:34 UTC (rev 197526)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-03-03  Alex Christensen  &lt;achristensen@webkit.org&gt;
+
+        Use CredentialStorage with NetworkSession
+        https://bugs.webkit.org/show_bug.cgi?id=154939
+
+        Reviewed by Darin Adler.
+
+        This makes the credential-based http tests pass when using NetworkSession.
+
+        * platform/network/CredentialBase.h:
+        (WebCore::CredentialBase::encodingRequiresPlatformData):
+        * platform/network/CredentialStorage.h:
+        WEBCORE_EXPORT more things that are newly used in WebKit2.
+
</ins><span class="cx"> 2016-03-03  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Subpixel rendering: Make collapsed borders painting subpixel aware.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkCredentialBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/CredentialBase.h (197525 => 197526)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/CredentialBase.h        2016-03-03 23:57:13 UTC (rev 197525)
+++ trunk/Source/WebCore/platform/network/CredentialBase.h        2016-03-04 00:21:34 UTC (rev 197526)
</span><span class="lines">@@ -51,7 +51,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool encodingRequiresPlatformData() const { return false; }
</span><span class="cx"> 
</span><del>-    static bool compare(const Credential&amp;, const Credential&amp;);
</del><ins>+    WEBCORE_EXPORT static bool compare(const Credential&amp;, const Credential&amp;);
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     WEBCORE_EXPORT CredentialBase();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkCredentialStorageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/CredentialStorage.h (197525 => 197526)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/CredentialStorage.h        2016-03-03 23:57:13 UTC (rev 197525)
+++ trunk/Source/WebCore/platform/network/CredentialStorage.h        2016-03-04 00:21:34 UTC (rev 197526)
</span><span class="lines">@@ -43,9 +43,9 @@
</span><span class="cx">     WEBCORE_EXPORT static CredentialStorage&amp; defaultCredentialStorage();
</span><span class="cx"> 
</span><span class="cx">     // WebCore session credential storage.
</span><del>-    void set(const Credential&amp;, const ProtectionSpace&amp;, const URL&amp;);
</del><ins>+    WEBCORE_EXPORT void set(const Credential&amp;, const ProtectionSpace&amp;, const URL&amp;);
</ins><span class="cx">     WEBCORE_EXPORT Credential get(const ProtectionSpace&amp;);
</span><del>-    void remove(const ProtectionSpace&amp;);
</del><ins>+    WEBCORE_EXPORT void remove(const ProtectionSpace&amp;);
</ins><span class="cx"> 
</span><span class="cx">     // OS persistent storage.
</span><span class="cx">     WEBCORE_EXPORT Credential getFromPersistentStorage(const ProtectionSpace&amp;);
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx"> 
</span><span class="cx">     // These methods work for authentication schemes that support sending credentials without waiting for a request. E.g., for HTTP Basic authentication scheme
</span><span class="cx">     // a client should assume that all paths at or deeper than the depth of a known protected resource share are within the same protection space.
</span><del>-    bool set(const Credential&amp;, const URL&amp;); // Returns true if the URL corresponds to a known protection space, so credentials could be updated.
</del><ins>+    WEBCORE_EXPORT bool set(const Credential&amp;, const URL&amp;); // Returns true if the URL corresponds to a known protection space, so credentials could be updated.
</ins><span class="cx">     WEBCORE_EXPORT Credential get(const URL&amp;);
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (197525 => 197526)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-03-03 23:57:13 UTC (rev 197525)
+++ trunk/Source/WebKit2/ChangeLog        2016-03-04 00:21:34 UTC (rev 197526)
</span><span class="lines">@@ -1,3 +1,53 @@
</span><ins>+2016-03-03  Alex Christensen  &lt;achristensen@webkit.org&gt;
+
+        Use CredentialStorage with NetworkSession
+        https://bugs.webkit.org/show_bug.cgi?id=154939
+
+        Reviewed by Darin Adler.
+
+        * config.h:
+        Added compile-time flag to help us be able to keep track and remove this code when we can.
+        * NetworkProcess/NetworkDataTask.h:
+        (WebKit::NetworkDataTask::pendingDownloadLocation):
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::clearCachedCredentials):
+        (WebKit::NetworkProcess::ensurePrivateBrowsingSession):
+        * NetworkProcess/NetworkSession.h:
+        (WebKit::NetworkSession::sessionID):
+        * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
+        (WebKit::applyBasicAuthorizationHeader):
+        (WebKit::NetworkDataTask::NetworkDataTask):
+        Use a credential storage and preemptively apply basic authentication headers if we have credentials from the storage.
+        This is analogous to code in ResourceHandle::createNSURLConnection.
+        
+        (WebKit::NetworkDataTask::didReceiveChallenge):
+        Make this look more like ResourceHandle::didReceiveAuthenticationChallenge.
+        The call to tryPasswordBasedAuthentication was moved from the delegate callback to here.
+        
+        (WebKit::NetworkDataTask::willPerformHTTPRedirection):
+        Use credentials from the credential storage if they exist.  This is analogous to code in ResourceHandle::willSendRequest.
+        
+        (WebKit::NetworkDataTask::tryPasswordBasedAuthentication):
+        Use credentials from the credential storage if they exist.  This is analogous to code in ResourceHandle::tryHandlePasswordBasedAuthentication.
+        
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (-[WKNetworkSessionDelegate URLSession:task:didReceiveChallenge:completionHandler:]):
+        If we are given a credential with CredentialPersistenceForSession, put it in the credential storage and give 
+        CFNetwork a credential with CredentialPersistenceNone so it won't automatically be used again until the credential
+        storage says its ok to use again.  This gives us the ability to clear session credentials when logout credentials are used.
+        This is analogous to code in ResourceHandle::receivedCredential.
+        
+        (WebKit::NetworkSession::defaultSession):
+        (WebKit::NetworkSession::NetworkSession):
+        (WebKit::NetworkSession::~NetworkSession):
+        (WebKit::NetworkSession::dataTaskForIdentifier):
+        (WebKit::NetworkSession::clearCredentials): Deleted.
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::clearCachedCredentials):
+        (WebKit::WebProcess::focusedWebPage):
+        We no longer need to clear credentials from the NSURLSessions because we don't store session credentials in them.
+        Instead, calling CredentialStorage.clearCredentials is sufficient.
+
</ins><span class="cx"> 2016-03-03  Andy Estes  &lt;aestes@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Adopt CFNetwork storage partitioning SPI
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkDataTaskh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h (197525 => 197526)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h        2016-03-03 23:57:13 UTC (rev 197525)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkDataTask.h        2016-03-04 00:21:34 UTC (rev 197526)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #define NetworkDataTask_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;SandboxExtension.h&quot;
</span><ins>+#include &lt;WebCore/Credential.h&gt;
</ins><span class="cx"> #include &lt;WebCore/FrameLoaderTypes.h&gt;
</span><span class="cx"> #include &lt;WebCore/ResourceHandleTypes.h&gt;
</span><span class="cx"> #include &lt;WebCore/ResourceLoaderOptions.h&gt;
</span><span class="lines">@@ -122,12 +123,13 @@
</span><span class="cx">     const String&amp; pendingDownloadLocation() { return m_pendingDownloadLocation; }
</span><span class="cx">     WebCore::ResourceRequest currentRequest();
</span><span class="cx">     String suggestedFilename();
</span><del>-    bool tryPasswordBasedAuthentication(const WebCore::AuthenticationChallenge&amp;, ChallengeCompletionHandler);
</del><span class="cx">     void willPerformHTTPRedirection(const WebCore::ResourceResponse&amp;, WebCore::ResourceRequest&amp;&amp;, RedirectCompletionHandler);
</span><span class="cx">     void transferSandboxExtensionToDownload(Download&amp;);
</span><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     NetworkDataTask(NetworkSession&amp;, NetworkDataTaskClient&amp;, const WebCore::ResourceRequest&amp;, WebCore::StoredCredentials, WebCore::ContentSniffingPolicy, bool shouldClearReferrerOnHTTPSToHTTPRedirect);
</span><ins>+
+    bool tryPasswordBasedAuthentication(const WebCore::AuthenticationChallenge&amp;, ChallengeCompletionHandler);
</ins><span class="cx">     
</span><span class="cx">     enum FailureType {
</span><span class="cx">         NoFailure,
</span><span class="lines">@@ -145,6 +147,9 @@
</span><span class="cx">     DownloadID m_pendingDownloadID;
</span><span class="cx">     String m_user;
</span><span class="cx">     String m_password;
</span><ins>+#if USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
+    WebCore::Credential m_initialCredential;
+#endif
</ins><span class="cx">     WebCore::StoredCredentials m_storedCredentials;
</span><span class="cx">     String m_lastHTTPMethod;
</span><span class="cx">     String m_pendingDownloadLocation;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp (197525 => 197526)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp        2016-03-03 23:57:13 UTC (rev 197525)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp        2016-03-04 00:21:34 UTC (rev 197526)
</span><span class="lines">@@ -273,7 +273,7 @@
</span><span class="cx"> void NetworkProcess::clearCachedCredentials()
</span><span class="cx"> {
</span><span class="cx">     NetworkStorageSession::defaultStorageSession().credentialStorage().clearCredentials();
</span><del>-#if USE(NETWORK_SESSION)
</del><ins>+#if USE(NETWORK_SESSION) &amp;&amp; !USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
</ins><span class="cx">     NetworkSession::defaultSession().clearCredentials();
</span><span class="cx"> #endif
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkSessionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkSession.h (197525 => 197526)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkSession.h        2016-03-03 23:57:13 UTC (rev 197525)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkSession.h        2016-03-04 00:21:34 UTC (rev 197526)
</span><span class="lines">@@ -53,9 +53,12 @@
</span><span class="cx">     NetworkSession(Type, WebCore::SessionID, CustomProtocolManager*);
</span><span class="cx">     ~NetworkSession();
</span><span class="cx"> 
</span><ins>+    WebCore::SessionID sessionID() { return m_sessionID; }
</ins><span class="cx">     static void setCustomProtocolManager(CustomProtocolManager*);
</span><span class="cx">     static NetworkSession&amp; defaultSession();
</span><ins>+#if !USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
</ins><span class="cx">     void clearCredentials();
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx">     NetworkDataTask* dataTaskForIdentifier(NetworkDataTask::TaskIdentifier, WebCore::StoredCredentials);
</span><span class="cx"> 
</span><span class="lines">@@ -64,6 +67,7 @@
</span><span class="cx">     DownloadID takeDownloadID(NetworkDataTask::TaskIdentifier);
</span><span class="cx">     
</span><span class="cx"> private:
</span><ins>+    WebCore::SessionID m_sessionID;
</ins><span class="cx">     HashMap&lt;NetworkDataTask::TaskIdentifier, NetworkDataTask*&gt; m_dataTaskMapWithCredentials;
</span><span class="cx">     HashMap&lt;NetworkDataTask::TaskIdentifier, NetworkDataTask*&gt; m_dataTaskMapWithoutCredentials;
</span><span class="cx">     HashMap&lt;NetworkDataTask::TaskIdentifier, DownloadID&gt; m_downloadMap;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscocoaNetworkDataTaskCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm (197525 => 197526)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm        2016-03-03 23:57:13 UTC (rev 197525)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm        2016-03-04 00:21:34 UTC (rev 197526)
</span><span class="lines">@@ -31,18 +31,27 @@
</span><span class="cx"> #import &quot;Download.h&quot;
</span><span class="cx"> #import &quot;DownloadProxyMessages.h&quot;
</span><span class="cx"> #import &quot;NetworkProcess.h&quot;
</span><ins>+#import &quot;SessionTracker.h&quot;
</ins><span class="cx"> #import &quot;WebCoreArgumentCoders.h&quot;
</span><span class="cx"> #import &lt;WebCore/AuthenticationChallenge.h&gt;
</span><span class="cx"> #import &lt;WebCore/CFNetworkSPI.h&gt;
</span><span class="cx"> #import &lt;WebCore/NetworkStorageSession.h&gt;
</span><span class="cx"> #import &lt;WebCore/ResourceRequest.h&gt;
</span><span class="cx"> #import &lt;wtf/MainThread.h&gt;
</span><ins>+#import &lt;wtf/text/Base64.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> @interface NSURLSessionTask ()
</span><span class="cx"> @property (readwrite, copy) NSString *_pathToDownloadTaskFile;
</span><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><ins>+#if USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
+static void applyBasicAuthorizationHeader(WebCore::ResourceRequest&amp; request, const WebCore::Credential&amp; credential)
+{
+    String authenticationHeader = &quot;Basic &quot; + base64Encode(String(credential.user() + &quot;:&quot; + credential.password()).utf8());
+    request.setHTTPHeaderField(WebCore::HTTPHeaderName::Authorization, authenticationHeader);
+}
+#endif
</ins><span class="cx"> 
</span><span class="cx"> NetworkDataTask::NetworkDataTask(NetworkSession&amp; session, NetworkDataTaskClient&amp; client, const WebCore::ResourceRequest&amp; requestWithCredentials, WebCore::StoredCredentials storedCredentials, WebCore::ContentSniffingPolicy shouldContentSniff, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
</span><span class="cx">     : m_failureTimer(*this, &amp;NetworkDataTask::failureTimerFired)
</span><span class="lines">@@ -66,10 +75,31 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     auto request = requestWithCredentials;
</span><del>-    m_user = request.url().user();
-    m_password = request.url().pass();
-    request.removeCredentials();
</del><ins>+    auto url = request.url();
+    if (storedCredentials == WebCore::AllowStoredCredentials &amp;&amp; url.protocolIsInHTTPFamily()) {
+        m_user = url.user();
+        m_password = url.pass();
+        request.removeCredentials();
+        url = request.url();
</ins><span class="cx">     
</span><ins>+#if USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
+        if (auto storageSession = SessionTracker::storageSession(m_session.sessionID())) {
+            if (m_user.isEmpty() &amp;&amp; m_password.isEmpty())
+                m_initialCredential = storageSession-&gt;credentialStorage().get(url);
+            else
+                storageSession-&gt;credentialStorage().set(WebCore::Credential(m_user, m_password, WebCore::CredentialPersistenceNone), url);
+        } else
+            RELEASE_ASSERT_NOT_REACHED();
+#endif
+    }
+
+#if USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
+    if (!m_initialCredential.isEmpty()) {
+        // FIXME: Support Digest authentication, and Proxy-Authorization.
+        applyBasicAuthorizationHeader(request, m_initialCredential);
+    }
+#endif
+    
</ins><span class="cx">     NSURLRequest *nsRequest = request.nsURLRequest(WebCore::UpdateHTTPBody);
</span><span class="cx">     if (shouldContentSniff == WebCore::DoNotSniffContent) {
</span><span class="cx">         NSMutableURLRequest *mutableRequest = [[nsRequest mutableCopy] autorelease];
</span><span class="lines">@@ -116,6 +146,16 @@
</span><span class="cx"> 
</span><span class="cx"> void NetworkDataTask::didReceiveChallenge(const WebCore::AuthenticationChallenge&amp; challenge, ChallengeCompletionHandler completionHandler)
</span><span class="cx"> {
</span><ins>+    // Proxy authentication is handled by CFNetwork internally. We can get here if the user cancels
+    // CFNetwork authentication dialog, and we shouldn't ask the client to display another one in that case.
+    if (challenge.protectionSpace().isProxy()) {
+        completionHandler(AuthenticationChallengeDisposition::UseCredential, { });
+        return;
+    }
+
+    if (tryPasswordBasedAuthentication(challenge, completionHandler))
+        return;
+
</ins><span class="cx">     if (m_client)
</span><span class="cx">         m_client-&gt;didReceiveChallenge(challenge, completionHandler);
</span><span class="cx"> }
</span><span class="lines">@@ -172,6 +212,23 @@
</span><span class="cx">         // we want to strip here because the redirect is cross-origin.
</span><span class="cx">         request.clearHTTPAuthorization();
</span><span class="cx">         request.clearHTTPOrigin();
</span><ins>+#if USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
+    } else {
+        // 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() &amp;&amp; m_password.isEmpty() &amp;&amp; !redirectResponse.isNull()) {
+            if (auto storageSession = SessionTracker::storageSession(m_session.sessionID())) {
+                auto credential = storageSession-&gt;credentialStorage().get(request.url());
+                if (!credential.isEmpty()) {
+                    m_initialCredential = credential;
+
+                    // FIXME: Support Digest authentication, and Proxy-Authorization.
+                    applyBasicAuthorizationHeader(request, m_initialCredential);
+                }
+            } else
+                RELEASE_ASSERT_NOT_REACHED();
+        }
+#endif
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     if (m_client)
</span><span class="lines">@@ -230,7 +287,34 @@
</span><span class="cx">         m_password = String();
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><del>-    
</del><ins>+
+#if USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
+    if (m_storedCredentials == WebCore::AllowStoredCredentials) {
+        if (auto storageSession = SessionTracker::storageSession(m_session.sessionID())) {
+            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 ResourceHandle,
+                // but the observable effect should be very minor, if any.
+                storageSession-&gt;credentialStorage().remove(challenge.protectionSpace());
+            }
+
+            if (!challenge.previousFailureCount()) {
+                auto credential = storageSession-&gt;credentialStorage().get(challenge.protectionSpace());
+                if (!credential.isEmpty() &amp;&amp; credential != m_initialCredential) {
+                    ASSERT(credential.persistence() == WebCore::CredentialPersistenceNone);
+                    if (challenge.failureResponse().httpStatusCode() == 401) {
+                        // Store the credential back, possibly adding it as a default for this directory.
+                        storageSession-&gt;credentialStorage().set(credential, challenge.protectionSpace(), challenge.failureResponse().url());
+                    }
+                    completionHandler(AuthenticationChallengeDisposition::UseCredential, credential);
+                    return true;
+                }
+            }
+        } else
+            RELEASE_ASSERT_NOT_REACHED();
+    }
+#endif
+
</ins><span class="cx">     if (!challenge.proposedCredential().isEmpty() &amp;&amp; !challenge.previousFailureCount()) {
</span><span class="cx">         completionHandler(AuthenticationChallengeDisposition::UseCredential, challenge.proposedCredential());
</span><span class="cx">         return true;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscocoaNetworkSessionCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm (197525 => 197526)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm        2016-03-03 23:57:13 UTC (rev 197525)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm        2016-03-04 00:21:34 UTC (rev 197526)
</span><span class="lines">@@ -119,16 +119,30 @@
</span><span class="cx"> {
</span><span class="cx">     auto storedCredentials = session.configuration.URLCredentialStorage ? WebCore::StoredCredentials::AllowStoredCredentials : WebCore::StoredCredentials::DoNotAllowStoredCredentials;
</span><span class="cx">     if (auto* networkDataTask = _session-&gt;dataTaskForIdentifier(task.taskIdentifier, storedCredentials)) {
</span><ins>+        WebCore::AuthenticationChallenge authenticationChallenge(challenge);
</ins><span class="cx">         auto completionHandlerCopy = Block_copy(completionHandler);
</span><del>-        auto challengeCompletionHandler = [completionHandlerCopy](WebKit::AuthenticationChallengeDisposition disposition, const WebCore::Credential&amp; credential)
</del><ins>+        auto sessionID = _session-&gt;sessionID();
+        auto challengeCompletionHandler = [completionHandlerCopy, sessionID, authenticationChallenge](WebKit::AuthenticationChallengeDisposition disposition, const WebCore::Credential&amp; credential)
</ins><span class="cx">         {
</span><del>-            completionHandlerCopy(toNSURLSessionAuthChallengeDisposition(disposition), credential.nsCredential());
</del><ins>+#if !USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
+            UNUSED_PARAM(sessionID);
+            UNUSED_PARAM(authenticationChallenge);
+#else
+            if (credential.persistence() == WebCore::CredentialPersistenceForSession &amp;&amp; authenticationChallenge.protectionSpace().authenticationScheme() != WebCore::ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested) {
+
+                WebCore::Credential nonPersistentCredential(credential.user(), credential.password(), WebCore::CredentialPersistenceNone);
+                WebCore::URL urlToStore;
+                if (authenticationChallenge.failureResponse().httpStatusCode() == 401)
+                    urlToStore = authenticationChallenge.failureResponse().url();
+                if (auto storageSession = WebKit::SessionTracker::storageSession(sessionID))
+                    storageSession-&gt;credentialStorage().set(nonPersistentCredential, authenticationChallenge.protectionSpace(), urlToStore);
+
+                completionHandlerCopy(toNSURLSessionAuthChallengeDisposition(disposition), nonPersistentCredential.nsCredential());
+            } else
+#endif
+                completionHandlerCopy(toNSURLSessionAuthChallengeDisposition(disposition), credential.nsCredential());
</ins><span class="cx">             Block_release(completionHandlerCopy);
</span><span class="cx">         };
</span><del>-        
-        if (networkDataTask-&gt;tryPasswordBasedAuthentication(challenge, challengeCompletionHandler))
-            return;
-        
</del><span class="cx">         networkDataTask-&gt;didReceiveChallenge(challenge, challengeCompletionHandler);
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -243,6 +257,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> NetworkSession::NetworkSession(Type type, WebCore::SessionID sessionID, CustomProtocolManager* customProtocolManager)
</span><ins>+    : m_sessionID(sessionID)
</ins><span class="cx"> {
</span><span class="cx">     m_sessionDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this]);
</span><span class="cx"> 
</span><span class="lines">@@ -272,6 +287,7 @@
</span><span class="cx">     [m_sessionWithoutCredentialStorage invalidateAndCancel];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if !USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
</ins><span class="cx"> void NetworkSession::clearCredentials()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_dataTaskMapWithCredentials.isEmpty());
</span><span class="lines">@@ -279,6 +295,7 @@
</span><span class="cx">     ASSERT(m_downloadMap.isEmpty());
</span><span class="cx">     m_sessionWithCredentialStorage = [NSURLSession sessionWithConfiguration:m_sessionWithCredentialStorage.get().configuration delegate:static_cast&lt;id&gt;(m_sessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx"> NetworkDataTask* NetworkSession::dataTaskForIdentifier(NetworkDataTask::TaskIdentifier taskIdentifier, WebCore::StoredCredentials storedCredentials)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (197525 => 197526)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2016-03-03 23:57:13 UTC (rev 197525)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2016-03-04 00:21:34 UTC (rev 197526)
</span><span class="lines">@@ -505,7 +505,7 @@
</span><span class="cx"> void WebProcess::clearCachedCredentials()
</span><span class="cx"> {
</span><span class="cx">     NetworkStorageSession::defaultStorageSession().credentialStorage().clearCredentials();
</span><del>-#if USE(NETWORK_SESSION)
</del><ins>+#if USE(NETWORK_SESSION) &amp;&amp; !USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
</ins><span class="cx">     NetworkSession::defaultSession().clearCredentials();
</span><span class="cx"> #endif
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2configh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/config.h (197525 => 197526)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/config.h        2016-03-03 23:57:13 UTC (rev 197525)
+++ trunk/Source/WebKit2/config.h        2016-03-04 00:21:34 UTC (rev 197526)
</span><span class="lines">@@ -76,7 +76,12 @@
</span><span class="cx"> #ifndef USE_NETWORK_SESSION
</span><span class="cx"> #define USE_NETWORK_SESSION 0
</span><span class="cx"> #endif
</span><ins>+
+// FIXME: We should work towards not using CredentialStorage in WebKit2 to not have problems with digest authentication.
+#ifndef USE_CREDENTIAL_STORAGE_WITH_NETWORK_SESSION
+#define USE_CREDENTIAL_STORAGE_WITH_NETWORK_SESSION 1
</ins><span class="cx"> #endif
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx"> #ifndef HAVE_SEC_ACCESS_CONTROL
</span><span class="cx"> #if PLATFORM(IOS) || PLATFORM(MAC)
</span></span></pre>
</div>
</div>

</body>
</html>