<!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>[42483] trunk/WebCore</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/42483">42483</a></dd>
<dt>Author</dt> <dd>ap@webkit.org</dd>
<dt>Date</dt> <dd>2009-04-14 01:11:42 -0700 (Tue, 14 Apr 2009)</dd>
</dl>

<h3>Log Message</h3>
<pre>        Reviewed by Sam Weinig.

        &lt;rdar://problem/6698851&gt; Implement XMLHttpRequest withCredentials attribute

        Tests: http/tests/xmlhttprequest/cross-origin-authorization.html
               http/tests/xmlhttprequest/cross-origin-no-authorization.html

        * WebCore.xcodeproj/project.pbxproj: Made ThreadableLoader.h private, as enum definitions
        from it are now used in otehr private headers.

        * xml/XMLHttpRequest.h:
        * xml/XMLHttpRequest.idl:
        Added withCredentials attribute. When it is false (default), neither credentials nor cookies
        are sent with cross origin requests, When it is true, those are sent, but the server needs
        to allow handling results via Access-Control-Allow-Credentials header. It was always possible
        to send a cross-site request with credentials via IFRAME or IMG, so this just adds a way to
        read results, as long as the server reports that it's allowed.
        Having the default set to false ensures that requests won't fail unexpectedly because of
        stored credentials and cookies for other resources in the target protection space.

        * xml/XMLHttpRequest.cpp:
        (WebCore::XMLHttpRequest::loadRequestSynchronously): Allow stored credentials for same origin
        requests, and for cross origin ones that have withCredentials attribute set. Such code already
        existed for cookies (but it's simpler, because we could just set a ResourceRequest flag).
        (WebCore::XMLHttpRequest::loadRequestAsynchronously): Ditto.

        * platform/network/ResourceHandle.h: Added willSendRequest() - just like for other callbacks,
        is is easier to have code in the class. Also, loadResourceSynchronously() now takes a
        StoredCredentials option, matching async case.

        * platform/network/ResourceHandleClient.h:
        (WebCore::ResourceHandleClient::receivedCredential): Removed. This method could never be
        called, and no client used it.
        (WebCore::ResourceHandleClient::receivedRequestToContinueWithoutCredential): Ditto.

        * platform/network/ResourceHandleInternal.h:
        (WebCore::ResourceHandleInternal::ResourceHandleInternal): Split username and password out
        of request URL. We want to always get a callback for credentials to manage them in WebCore,
        so network back-end shouldn't see them too early.

        * platform/network/ResourceRequestBase.cpp:
        (WebCore::ResourceRequestBase::removeCredentials):
        * platform/network/ResourceRequestBase.h:
        Added a removeCredentials() method that removes login and password parts from request URL.

        * platform/network/mac/ResourceHandleMac.mm:
        (WebCoreCredentialStorage): Added a simple storage class for per-session credentials.
        (WebCore::ResourceHandle::loadResourceSynchronously): Pass allowStoredCredentials through.
        (WebCore::ResourceHandle::willSendRequest): On a redirect, credentials should be replaced.
        (WebCore::ResourceHandle::didReceiveAuthenticationChallenge): Try credentials from the URL
        and per-session credentials. Code was partially moved from Obj-C callback.
        (WebCore::ResourceHandle::receivedCredential): Intercept per-session credentials and store
        them in WebCore storage.
        (-[WebCoreResourceHandleAsDelegate connection:willSendRequest:redirectResponse:]): Don't
        store the redirected URL - we only needed credentials, which are now stored separately.
        (-[WebCoreResourceHandleAsDelegate connection:didReceiveAuthenticationChallenge:]): Removed
        code that was setting credentials from URL. First, the code is now in ResourceHandle, and
        also, it wasn't actually needed in Leopard release before this patch, see &lt;rdar://problem/5298142&gt;.
        (-[WebCoreSynchronousLoader dealloc]): Release credentials. Note that unlike ResourceHandle,
        this class still needs to track URL for checking whether a redirect is allowed. This is
        not a great solution, and we should unify client code to use the same checks in sync and
        async cases.
        (-[WebCoreSynchronousLoader connection:willSendRequest:redirectResponse:]): Just like in
        async case, put credentials aside to ensure that network back-end asks for them.
        (-[WebCoreSynchronousLoader connection:didReceiveAuthenticationChallenge:]): Use credentials
        from URL, or from WebCore storage.
        (-[WebCoreSynchronousLoader connectionShouldUseCredentialStorage:]): Don't use stored
        credentials when not allowed to.
        (+[WebCoreSynchronousLoader loadRequest:allowStoredCredentials:returningResponse:error:]):
        Put credentials aside to ensure that network back-end asks for them.

        * platform/network/cf/ResourceHandleCFNet.cpp:
        (WebCore::WebCoreCredentialStorage::set):
        (WebCore::WebCoreCredentialStorage::get):
        (WebCore::willSendRequest):
        (WebCore::ResourceHandle::start):
        (WebCore::ResourceHandle::willSendRequest):
        (WebCore::ResourceHandle::didReceiveAuthenticationChallenge):
        (WebCore::ResourceHandle::receivedCredential):
        (WebCore::ResourceHandle::loadResourceSynchronously):
        (WebCore::WebCoreSynchronousLoader::willSendRequest):
        (WebCore::WebCoreSynchronousLoader::didReceiveChallenge):
        (WebCore::WebCoreSynchronousLoader::shouldUseCredentialStorage):
        (WebCore::WebCoreSynchronousLoader::load):
        Same changes as in Mac case.

        * platform/network/curl/ResourceHandleCurl.cpp:
        (WebCore::ResourceHandle::loadResourceSynchronously):
        * platform/network/qt/ResourceHandleQt.cpp:
        (WebCore::ResourceHandle::loadResourceSynchronously):
        * platform/network/soup/ResourceHandleSoup.cpp:
        (WebCore::ResourceHandle::loadResourceSynchronously):
        Trying not to break the build.

        * dom/XMLTokenizerLibxml2.cpp: (WebCore::openFunc):
        * xml/XSLTProcessor.cpp: (WebCore::docLoaderFunc):
        Unconditionally allow stored credentials for these, as they only support same origin loads.

        * workers/WorkerContext.cpp: (WebCore::WorkerContext::importScripts):
        WorkerContext.importScripts() can be cross-origin, but sending credentials with it is no worse
        than sending them with &lt;script src=...&gt;, so this is also unconditionally allowed.

        * loader/DocumentThreadableLoader.cpp:
        (WebCore::DocumentThreadableLoader::loadResourceSynchronously): Pass through storedCredentials.
        (WebCore::DocumentThreadableLoader::create): Ditto.
        (WebCore::DocumentThreadableLoader::DocumentThreadableLoader): Save storedCredentials and
        sameOrigin flags foruse in callbacks.
        (WebCore::DocumentThreadableLoader::willSendRequest): Assert that loaders aren't all confused.
        (WebCore::DocumentThreadableLoader::didSendData): Ditto.
        (WebCore::DocumentThreadableLoader::didReceiveResponse): Ditto.
        (WebCore::DocumentThreadableLoader::didReceiveData): Ditto.
        (WebCore::DocumentThreadableLoader::didFinishLoading): Ditto.
        (WebCore::DocumentThreadableLoader::didFail): Ditto.
        (WebCore::DocumentThreadableLoader::getShouldUseCredentialStorage): Don't use credential
        storage if that's not allowed by the code that invoked DocumentThreadableLoader.
        (WebCore::DocumentThreadableLoader::didReceiveAuthenticationChallenge): Simulate a failure
        and cancel the request if we are about to ask the user for credentials for a cross-origin
        request, which is forbidden by CORS (and would have been very confusing if allowed).
        (WebCore::DocumentThreadableLoader::receivedCancellation): Assert that loaders aren't all confused.

        * loader/DocumentThreadableLoader.h: Updated for the new flags (storedCredentials and
        sameOrigin) that affect the loader. Eventually, we need to move all CORS logic from XHR here.

        * loader/ThreadableLoader.h: (StoredCredentials): Added another flag that affects loader
        behavior. We should combine all of these into a structure, and use it for sync requests, too.

        * loader/FrameLoader.cpp: (WebCore::FrameLoader::loadResourceSynchronously):
        * loader/FrameLoader.h:
        * loader/ThreadableLoader.cpp:
        (WebCore::ThreadableLoader::create):
        (WebCore::ThreadableLoader::loadResourceSynchronously):
        * loader/WorkerThreadableLoader.cpp:
        (WebCore::WorkerThreadableLoader::WorkerThreadableLoader):
        (WebCore::WorkerThreadableLoader::loadResourceSynchronously):
        (WebCore::WorkerThreadableLoader::MainThreadBridge::MainThreadBridge):
        (WebCore::WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader):
        * loader/WorkerThreadableLoader.h:
        (WebCore::WorkerThreadableLoader::create):
        Pass through storedCredentials.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebCoreChangeLog">trunk/WebCore/ChangeLog</a></li>
<li><a href="#trunkWebCoreWebCorexcodeprojprojectpbxproj">trunk/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkWebCoredomXMLTokenizerLibxml2cpp">trunk/WebCore/dom/XMLTokenizerLibxml2.cpp</a></li>
<li><a href="#trunkWebCoreloaderDocumentThreadableLoadercpp">trunk/WebCore/loader/DocumentThreadableLoader.cpp</a></li>
<li><a href="#trunkWebCoreloaderDocumentThreadableLoaderh">trunk/WebCore/loader/DocumentThreadableLoader.h</a></li>
<li><a href="#trunkWebCoreloaderFrameLoadercpp">trunk/WebCore/loader/FrameLoader.cpp</a></li>
<li><a href="#trunkWebCoreloaderFrameLoaderh">trunk/WebCore/loader/FrameLoader.h</a></li>
<li><a href="#trunkWebCoreloaderThreadableLoadercpp">trunk/WebCore/loader/ThreadableLoader.cpp</a></li>
<li><a href="#trunkWebCoreloaderThreadableLoaderh">trunk/WebCore/loader/ThreadableLoader.h</a></li>
<li><a href="#trunkWebCoreloaderWorkerThreadableLoadercpp">trunk/WebCore/loader/WorkerThreadableLoader.cpp</a></li>
<li><a href="#trunkWebCoreloaderWorkerThreadableLoaderh">trunk/WebCore/loader/WorkerThreadableLoader.h</a></li>
<li><a href="#trunkWebCoreplatformnetworkResourceHandleh">trunk/WebCore/platform/network/ResourceHandle.h</a></li>
<li><a href="#trunkWebCoreplatformnetworkResourceHandleClienth">trunk/WebCore/platform/network/ResourceHandleClient.h</a></li>
<li><a href="#trunkWebCoreplatformnetworkResourceHandleInternalh">trunk/WebCore/platform/network/ResourceHandleInternal.h</a></li>
<li><a href="#trunkWebCoreplatformnetworkResourceRequestBasecpp">trunk/WebCore/platform/network/ResourceRequestBase.cpp</a></li>
<li><a href="#trunkWebCoreplatformnetworkResourceRequestBaseh">trunk/WebCore/platform/network/ResourceRequestBase.h</a></li>
<li><a href="#trunkWebCoreplatformnetworkcfResourceHandleCFNetcpp">trunk/WebCore/platform/network/cf/ResourceHandleCFNet.cpp</a></li>
<li><a href="#trunkWebCoreplatformnetworkcurlResourceHandleCurlcpp">trunk/WebCore/platform/network/curl/ResourceHandleCurl.cpp</a></li>
<li><a href="#trunkWebCoreplatformnetworkmacResourceHandleMacmm">trunk/WebCore/platform/network/mac/ResourceHandleMac.mm</a></li>
<li><a href="#trunkWebCoreplatformnetworkqtResourceHandleQtcpp">trunk/WebCore/platform/network/qt/ResourceHandleQt.cpp</a></li>
<li><a href="#trunkWebCoreplatformnetworksoupResourceHandleSoupcpp">trunk/WebCore/platform/network/soup/ResourceHandleSoup.cpp</a></li>
<li><a href="#trunkWebCoreworkersWorkerContextcpp">trunk/WebCore/workers/WorkerContext.cpp</a></li>
<li><a href="#trunkWebCorexmlXMLHttpRequestcpp">trunk/WebCore/xml/XMLHttpRequest.cpp</a></li>
<li><a href="#trunkWebCorexmlXMLHttpRequesth">trunk/WebCore/xml/XMLHttpRequest.h</a></li>
<li><a href="#trunkWebCorexmlXMLHttpRequestidl">trunk/WebCore/xml/XMLHttpRequest.idl</a></li>
<li><a href="#trunkWebCorexmlXSLTProcessorcpp">trunk/WebCore/xml/XSLTProcessor.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/ChangeLog (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/ChangeLog        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/ChangeLog        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -1,3 +1,145 @@
</span><ins>+2009-04-13  Alexey Proskuryakov  &lt;ap@webkit.org&gt;
+
+        Reviewed by Sam Weinig.
+
+        &lt;rdar://problem/6698851&gt; Implement XMLHttpRequest withCredentials attribute
+
+        Tests: http/tests/xmlhttprequest/cross-origin-authorization.html
+               http/tests/xmlhttprequest/cross-origin-no-authorization.html
+
+        * WebCore.xcodeproj/project.pbxproj: Made ThreadableLoader.h private, as enum definitions
+        from it are now used in otehr private headers.
+
+        * xml/XMLHttpRequest.h:
+        * xml/XMLHttpRequest.idl:
+        Added withCredentials attribute. When it is false (default), neither credentials nor cookies
+        are sent with cross origin requests, When it is true, those are sent, but the server needs
+        to allow handling results via Access-Control-Allow-Credentials header. It was always possible
+        to send a cross-site request with credentials via IFRAME or IMG, so this just adds a way to
+        read results, as long as the server reports that it's allowed.
+        Having the default set to false ensures that requests won't fail unexpectedly because of
+        stored credentials and cookies for other resources in the target protection space.
+
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::loadRequestSynchronously): Allow stored credentials for same origin
+        requests, and for cross origin ones that have withCredentials attribute set. Such code already
+        existed for cookies (but it's simpler, because we could just set a ResourceRequest flag).
+        (WebCore::XMLHttpRequest::loadRequestAsynchronously): Ditto.
+
+        * platform/network/ResourceHandle.h: Added willSendRequest() - just like for other callbacks,
+        is is easier to have code in the class. Also, loadResourceSynchronously() now takes a
+        StoredCredentials option, matching async case.
+
+        * platform/network/ResourceHandleClient.h:
+        (WebCore::ResourceHandleClient::receivedCredential): Removed. This method could never be
+        called, and no client used it.
+        (WebCore::ResourceHandleClient::receivedRequestToContinueWithoutCredential): Ditto.
+
+        * platform/network/ResourceHandleInternal.h:
+        (WebCore::ResourceHandleInternal::ResourceHandleInternal): Split username and password out
+        of request URL. We want to always get a callback for credentials to manage them in WebCore,
+        so network back-end shouldn't see them too early.
+
+        * platform/network/ResourceRequestBase.cpp:
+        (WebCore::ResourceRequestBase::removeCredentials):
+        * platform/network/ResourceRequestBase.h:
+        Added a removeCredentials() method that removes login and password parts from request URL.
+
+        * platform/network/mac/ResourceHandleMac.mm:
+        (WebCoreCredentialStorage): Added a simple storage class for per-session credentials.
+        (WebCore::ResourceHandle::loadResourceSynchronously): Pass allowStoredCredentials through.
+        (WebCore::ResourceHandle::willSendRequest): On a redirect, credentials should be replaced.
+        (WebCore::ResourceHandle::didReceiveAuthenticationChallenge): Try credentials from the URL
+        and per-session credentials. Code was partially moved from Obj-C callback.
+        (WebCore::ResourceHandle::receivedCredential): Intercept per-session credentials and store
+        them in WebCore storage.
+        (-[WebCoreResourceHandleAsDelegate connection:willSendRequest:redirectResponse:]): Don't
+        store the redirected URL - we only needed credentials, which are now stored separately.
+        (-[WebCoreResourceHandleAsDelegate connection:didReceiveAuthenticationChallenge:]): Removed
+        code that was setting credentials from URL. First, the code is now in ResourceHandle, and
+        also, it wasn't actually needed in Leopard release before this patch, see &lt;rdar://problem/5298142&gt;.
+        (-[WebCoreSynchronousLoader dealloc]): Release credentials. Note that unlike ResourceHandle,
+        this class still needs to track URL for checking whether a redirect is allowed. This is
+        not a great solution, and we should unify client code to use the same checks in sync and
+        async cases.
+        (-[WebCoreSynchronousLoader connection:willSendRequest:redirectResponse:]): Just like in
+        async case, put credentials aside to ensure that network back-end asks for them.
+        (-[WebCoreSynchronousLoader connection:didReceiveAuthenticationChallenge:]): Use credentials
+        from URL, or from WebCore storage.
+        (-[WebCoreSynchronousLoader connectionShouldUseCredentialStorage:]): Don't use stored
+        credentials when not allowed to.
+        (+[WebCoreSynchronousLoader loadRequest:allowStoredCredentials:returningResponse:error:]):
+        Put credentials aside to ensure that network back-end asks for them.
+
+        * platform/network/cf/ResourceHandleCFNet.cpp:
+        (WebCore::WebCoreCredentialStorage::set):
+        (WebCore::WebCoreCredentialStorage::get):
+        (WebCore::willSendRequest):
+        (WebCore::ResourceHandle::start):
+        (WebCore::ResourceHandle::willSendRequest):
+        (WebCore::ResourceHandle::didReceiveAuthenticationChallenge):
+        (WebCore::ResourceHandle::receivedCredential):
+        (WebCore::ResourceHandle::loadResourceSynchronously):
+        (WebCore::WebCoreSynchronousLoader::willSendRequest):
+        (WebCore::WebCoreSynchronousLoader::didReceiveChallenge):
+        (WebCore::WebCoreSynchronousLoader::shouldUseCredentialStorage):
+        (WebCore::WebCoreSynchronousLoader::load):
+        Same changes as in Mac case.
+
+        * platform/network/curl/ResourceHandleCurl.cpp:
+        (WebCore::ResourceHandle::loadResourceSynchronously):
+        * platform/network/qt/ResourceHandleQt.cpp:
+        (WebCore::ResourceHandle::loadResourceSynchronously):
+        * platform/network/soup/ResourceHandleSoup.cpp:
+        (WebCore::ResourceHandle::loadResourceSynchronously):
+        Trying not to break the build.
+
+        * dom/XMLTokenizerLibxml2.cpp: (WebCore::openFunc):
+        * xml/XSLTProcessor.cpp: (WebCore::docLoaderFunc):
+        Unconditionally allow stored credentials for these, as they only support same origin loads.
+
+        * workers/WorkerContext.cpp: (WebCore::WorkerContext::importScripts):
+        WorkerContext.importScripts() can be cross-origin, but sending credentials with it is no worse
+        than sending them with &lt;script src=...&gt;, so this is also unconditionally allowed.
+
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::DocumentThreadableLoader::loadResourceSynchronously): Pass through storedCredentials.
+        (WebCore::DocumentThreadableLoader::create): Ditto.
+        (WebCore::DocumentThreadableLoader::DocumentThreadableLoader): Save storedCredentials and
+        sameOrigin flags foruse in callbacks.
+        (WebCore::DocumentThreadableLoader::willSendRequest): Assert that loaders aren't all confused.
+        (WebCore::DocumentThreadableLoader::didSendData): Ditto.
+        (WebCore::DocumentThreadableLoader::didReceiveResponse): Ditto.
+        (WebCore::DocumentThreadableLoader::didReceiveData): Ditto.
+        (WebCore::DocumentThreadableLoader::didFinishLoading): Ditto.
+        (WebCore::DocumentThreadableLoader::didFail): Ditto.
+        (WebCore::DocumentThreadableLoader::getShouldUseCredentialStorage): Don't use credential
+        storage if that's not allowed by the code that invoked DocumentThreadableLoader.
+        (WebCore::DocumentThreadableLoader::didReceiveAuthenticationChallenge): Simulate a failure
+        and cancel the request if we are about to ask the user for credentials for a cross-origin
+        request, which is forbidden by CORS (and would have been very confusing if allowed).
+        (WebCore::DocumentThreadableLoader::receivedCancellation): Assert that loaders aren't all confused.
+
+        * loader/DocumentThreadableLoader.h: Updated for the new flags (storedCredentials and
+        sameOrigin) that affect the loader. Eventually, we need to move all CORS logic from XHR here.
+
+        * loader/ThreadableLoader.h: (StoredCredentials): Added another flag that affects loader
+        behavior. We should combine all of these into a structure, and use it for sync requests, too.
+
+        * loader/FrameLoader.cpp: (WebCore::FrameLoader::loadResourceSynchronously):
+        * loader/FrameLoader.h:
+        * loader/ThreadableLoader.cpp:
+        (WebCore::ThreadableLoader::create):
+        (WebCore::ThreadableLoader::loadResourceSynchronously):
+        * loader/WorkerThreadableLoader.cpp:
+        (WebCore::WorkerThreadableLoader::WorkerThreadableLoader):
+        (WebCore::WorkerThreadableLoader::loadResourceSynchronously):
+        (WebCore::WorkerThreadableLoader::MainThreadBridge::MainThreadBridge):
+        (WebCore::WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader):
+        * loader/WorkerThreadableLoader.h:
+        (WebCore::WorkerThreadableLoader::create):
+        Pass through storedCredentials.
+
</ins><span class="cx"> 2009-04-13  David Hyatt  &lt;hyatt@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Reviewed by Cameron Zwarich.
</span></span></pre></div>
<a id="trunkWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/WebCore.xcodeproj/project.pbxproj (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/WebCore.xcodeproj/project.pbxproj        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/WebCore.xcodeproj/project.pbxproj        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -136,7 +136,7 @@
</span><span class="cx">                 0B8C56D40F28627F000502E1 /* HTTPHeaderMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B8C56D30F28627F000502E1 /* HTTPHeaderMap.cpp */; };
</span><span class="cx">                 0B9056190F2578BE0095FF6A /* DocumentThreadableLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B9056150F2578BE0095FF6A /* DocumentThreadableLoader.cpp */; };
</span><span class="cx">                 0B90561A0F2578BF0095FF6A /* DocumentThreadableLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B9056160F2578BE0095FF6A /* DocumentThreadableLoader.h */; settings = {ATTRIBUTES = (); }; };
</span><del>-                0B90561B0F2578BF0095FF6A /* ThreadableLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B9056170F2578BE0095FF6A /* ThreadableLoader.h */; settings = {ATTRIBUTES = (); }; };
</del><ins>+                0B90561B0F2578BF0095FF6A /* ThreadableLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B9056170F2578BE0095FF6A /* ThreadableLoader.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0B90561C0F2578BF0095FF6A /* ThreadableLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B9056180F2578BE0095FF6A /* ThreadableLoaderClient.h */; settings = {ATTRIBUTES = (); }; };
</span><span class="cx">                 0B90561E0F257E930095FF6A /* ThreadableLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B90561D0F257E930095FF6A /* ThreadableLoader.cpp */; };
</span><span class="cx">                 0B9056F80F2685F30095FF6A /* WorkerThreadableLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B9056F60F2685F30095FF6A /* WorkerThreadableLoader.cpp */; };
</span><span class="lines">@@ -4904,10 +4904,10 @@
</span><span class="cx">                 066C772F0AB603FD00238CC4 /* RenderFileUploadControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderFileUploadControl.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 06E81ED60AB5D5E900C87837 /* LocalCurrentGraphicsContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalCurrentGraphicsContext.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 06E81EEB0AB5DA9700C87837 /* LocalCurrentGraphicsContext.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = LocalCurrentGraphicsContext.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                070DD8F50F01868000727DEB /* mediaControls.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = mediaControls.css; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><ins>+                070DD8F50F01868000727DEB /* mediaControls.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mediaControls.css; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0735EE690F40C5E4004A2604 /* MediaPlayerProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlayerProxy.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 079F5E4B0F3BEBEA005E0782 /* MediaPlayerPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlayerPrivate.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                07AFE5900F1446BD00841617 /* mediaControlsQT.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = mediaControlsQT.css; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><ins>+                07AFE5900F1446BD00841617 /* mediaControlsQT.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mediaControlsQT.css; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 080081940ED3B2DD00C53BC0 /* WMLAnchorElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLAnchorElement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 080081950ED3B2DD00C53BC0 /* WMLAnchorElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLAnchorElement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0804BF6C0EE09C3B0006C000 /* WMLDoElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLDoElement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span></span></pre></div>
<a id="trunkWebCoredomXMLTokenizerLibxml2cpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/dom/XMLTokenizerLibxml2.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/dom/XMLTokenizerLibxml2.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/dom/XMLTokenizerLibxml2.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -409,7 +409,7 @@
</span><span class="cx">     // FIXME: We should restore the original global error handler as well.
</span><span class="cx"> 
</span><span class="cx">     if (docLoader-&gt;frame()) 
</span><del>-        docLoader-&gt;frame()-&gt;loader()-&gt;loadResourceSynchronously(url, error, response, data);
</del><ins>+        docLoader-&gt;frame()-&gt;loader()-&gt;loadResourceSynchronously(url, AllowStoredCredentials, error, response, data);
</ins><span class="cx"> 
</span><span class="cx">     globalDocLoader = docLoader;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebCoreloaderDocumentThreadableLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/loader/DocumentThreadableLoader.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/loader/DocumentThreadableLoader.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/loader/DocumentThreadableLoader.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-void DocumentThreadableLoader::loadResourceSynchronously(Document* document, const ResourceRequest&amp; request, ThreadableLoaderClient&amp; client)
</del><ins>+void DocumentThreadableLoader::loadResourceSynchronously(Document* document, const ResourceRequest&amp; request, ThreadableLoaderClient&amp; client, StoredCredentials storedCredentials)
</ins><span class="cx"> {
</span><span class="cx">     bool sameOriginRequest = document-&gt;securityOrigin()-&gt;canRequest(request.url());
</span><span class="cx"> 
</span><span class="lines">@@ -52,7 +52,7 @@
</span><span class="cx">     ResourceResponse response;
</span><span class="cx">     unsigned long identifier = std::numeric_limits&lt;unsigned long&gt;::max();
</span><span class="cx">     if (document-&gt;frame())
</span><del>-        identifier = document-&gt;frame()-&gt;loader()-&gt;loadResourceSynchronously(request, error, response, data);
</del><ins>+        identifier = document-&gt;frame()-&gt;loader()-&gt;loadResourceSynchronously(request, storedCredentials, error, response, data);
</ins><span class="cx"> 
</span><span class="cx">     // No exception for file:/// resources, see &lt;rdar://problem/4962298&gt;.
</span><span class="cx">     // Also, if we have an HTTP response, then it wasn't a network error in fact.
</span><span class="lines">@@ -77,18 +77,20 @@
</span><span class="cx">     client.didFinishLoading(identifier);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;DocumentThreadableLoader&gt; DocumentThreadableLoader::create(Document* document, ThreadableLoaderClient* client, const ResourceRequest&amp; request, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
</del><ins>+PassRefPtr&lt;DocumentThreadableLoader&gt; DocumentThreadableLoader::create(Document* document, ThreadableLoaderClient* client, const ResourceRequest&amp; request, LoadCallbacks callbacksSetting, ContentSniff contentSniff, StoredCredentials storedCredentials)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(document);
</span><del>-    RefPtr&lt;DocumentThreadableLoader&gt; loader = adoptRef(new DocumentThreadableLoader(document, client, request, callbacksSetting, contentSniff));
</del><ins>+    RefPtr&lt;DocumentThreadableLoader&gt; loader = adoptRef(new DocumentThreadableLoader(document, client, request, callbacksSetting, contentSniff, storedCredentials));
</ins><span class="cx">     if (!loader-&gt;m_loader)
</span><span class="cx">         loader = 0;
</span><span class="cx">     return loader.release();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-DocumentThreadableLoader::DocumentThreadableLoader(Document* document, ThreadableLoaderClient* client, const ResourceRequest&amp; request, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
</del><ins>+DocumentThreadableLoader::DocumentThreadableLoader(Document* document, ThreadableLoaderClient* client, const ResourceRequest&amp; request, LoadCallbacks callbacksSetting, ContentSniff contentSniff, StoredCredentials storedCredentials)
</ins><span class="cx">     : m_client(client)
</span><span class="cx">     , m_document(document)
</span><ins>+    , m_allowStoredCredentials(storedCredentials == AllowStoredCredentials)
+    , m_sameOriginRequest(document-&gt;securityOrigin()-&gt;canRequest(request.url()))
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(document);
</span><span class="cx">     ASSERT(client);
</span><span class="lines">@@ -112,9 +114,10 @@
</span><span class="cx">     m_client = 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DocumentThreadableLoader::willSendRequest(SubresourceLoader*, ResourceRequest&amp; request, const ResourceResponse&amp;)
</del><ins>+void DocumentThreadableLoader::willSendRequest(SubresourceLoader* loader, ResourceRequest&amp; request, const ResourceResponse&amp;)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_client);
</span><ins>+    ASSERT_UNUSED(loader, loader == m_loader);
</ins><span class="cx"> 
</span><span class="cx">     // FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests.
</span><span class="cx">     if (!m_document-&gt;securityOrigin()-&gt;canRequest(request.url())) {
</span><span class="lines">@@ -124,40 +127,72 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DocumentThreadableLoader::didSendData(SubresourceLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
</del><ins>+void DocumentThreadableLoader::didSendData(SubresourceLoader* loader, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_client);
</span><ins>+    ASSERT_UNUSED(loader, loader == m_loader);
+
</ins><span class="cx">     m_client-&gt;didSendData(bytesSent, totalBytesToBeSent);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DocumentThreadableLoader::didReceiveResponse(SubresourceLoader*, const ResourceResponse&amp; response)
</del><ins>+void DocumentThreadableLoader::didReceiveResponse(SubresourceLoader* loader, const ResourceResponse&amp; response)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_client);
</span><ins>+    ASSERT_UNUSED(loader, loader == m_loader);
+
</ins><span class="cx">     m_client-&gt;didReceiveResponse(response);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DocumentThreadableLoader::didReceiveData(SubresourceLoader*, const char* data, int lengthReceived)
</del><ins>+void DocumentThreadableLoader::didReceiveData(SubresourceLoader* loader, const char* data, int lengthReceived)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_client);
</span><ins>+    ASSERT_UNUSED(loader, loader == m_loader);
+
</ins><span class="cx">     m_client-&gt;didReceiveData(data, lengthReceived);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void DocumentThreadableLoader::didFinishLoading(SubresourceLoader* loader)
</span><span class="cx"> {
</span><del>-    ASSERT(loader);
</del><ins>+    ASSERT(loader == m_loader);
</ins><span class="cx">     ASSERT(m_client);
</span><span class="cx">     m_client-&gt;didFinishLoading(loader-&gt;identifier());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DocumentThreadableLoader::didFail(SubresourceLoader*, const ResourceError&amp; error)
</del><ins>+void DocumentThreadableLoader::didFail(SubresourceLoader* loader, const ResourceError&amp; error)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_client);
</span><ins>+    ASSERT_UNUSED(loader, loader == m_loader);
+
</ins><span class="cx">     m_client-&gt;didFail(error);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void DocumentThreadableLoader::receivedCancellation(SubresourceLoader*, const AuthenticationChallenge&amp; challenge)
</del><ins>+bool DocumentThreadableLoader::getShouldUseCredentialStorage(SubresourceLoader* loader, bool&amp; shouldUseCredentialStorage)
</ins><span class="cx"> {
</span><ins>+    ASSERT_UNUSED(loader, loader == m_loader);
+
+    if (!m_allowStoredCredentials) {
+        shouldUseCredentialStorage = false;
+        return true;
+    }
+
+    return false; // Only FrameLoaderClient can ultimately permit credential use.
+}
+
+void DocumentThreadableLoader::didReceiveAuthenticationChallenge(SubresourceLoader* loader, const AuthenticationChallenge&amp;)
+{
+    ASSERT(loader == m_loader);
+    // Users are not prompted for credentials for cross-origin requests.
+    if (!m_sameOriginRequest) {
+        RefPtr&lt;DocumentThreadableLoader&gt; protect(this);
+        m_client-&gt;didFail(loader-&gt;blockedError());
+        cancel();
+    }
+}
+
+void DocumentThreadableLoader::receivedCancellation(SubresourceLoader* loader, const AuthenticationChallenge&amp; challenge)
+{
</ins><span class="cx">     ASSERT(m_client);
</span><ins>+    ASSERT_UNUSED(loader, loader == m_loader);
</ins><span class="cx">     m_client-&gt;didReceiveAuthenticationCancellation(challenge.failureResponse());
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebCoreloaderDocumentThreadableLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/loader/DocumentThreadableLoader.h (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/loader/DocumentThreadableLoader.h        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/loader/DocumentThreadableLoader.h        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -44,8 +44,8 @@
</span><span class="cx"> 
</span><span class="cx">     class DocumentThreadableLoader : public RefCounted&lt;DocumentThreadableLoader&gt;, public ThreadableLoader, private SubresourceLoaderClient  {
</span><span class="cx">     public:
</span><del>-        static void loadResourceSynchronously(Document*, const ResourceRequest&amp;, ThreadableLoaderClient&amp;);
-        static PassRefPtr&lt;DocumentThreadableLoader&gt; create(Document*, ThreadableLoaderClient*, const ResourceRequest&amp;, LoadCallbacks, ContentSniff);
</del><ins>+        static void loadResourceSynchronously(Document*, const ResourceRequest&amp;, ThreadableLoaderClient&amp;, StoredCredentials);
+        static PassRefPtr&lt;DocumentThreadableLoader&gt; create(Document*, ThreadableLoaderClient*, const ResourceRequest&amp;, LoadCallbacks, ContentSniff, StoredCredentials);
</ins><span class="cx">         virtual ~DocumentThreadableLoader();
</span><span class="cx"> 
</span><span class="cx">         virtual void cancel();
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx">         virtual void derefThreadableLoader() { deref(); }
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        DocumentThreadableLoader(Document*, ThreadableLoaderClient*, const ResourceRequest&amp;, LoadCallbacks, ContentSniff);
</del><ins>+        DocumentThreadableLoader(Document*, ThreadableLoaderClient*, const ResourceRequest&amp;, LoadCallbacks, ContentSniff, StoredCredentials);
</ins><span class="cx">         virtual void willSendRequest(SubresourceLoader*, ResourceRequest&amp;, const ResourceResponse&amp; redirectResponse);
</span><span class="cx">         virtual void didSendData(SubresourceLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
</span><span class="cx"> 
</span><span class="lines">@@ -67,11 +67,15 @@
</span><span class="cx">         virtual void didFinishLoading(SubresourceLoader*);
</span><span class="cx">         virtual void didFail(SubresourceLoader*, const ResourceError&amp;);
</span><span class="cx"> 
</span><ins>+        virtual bool getShouldUseCredentialStorage(SubresourceLoader*, bool&amp; shouldUseCredentialStorage);
+        virtual void didReceiveAuthenticationChallenge(SubresourceLoader*, const AuthenticationChallenge&amp;);
</ins><span class="cx">         virtual void receivedCancellation(SubresourceLoader*, const AuthenticationChallenge&amp;);
</span><span class="cx"> 
</span><span class="cx">         RefPtr&lt;SubresourceLoader&gt; m_loader;
</span><span class="cx">         ThreadableLoaderClient* m_client;
</span><span class="cx">         Document* m_document;
</span><ins>+        bool m_allowStoredCredentials;
+        bool m_sameOriginRequest;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkWebCoreloaderFrameLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/loader/FrameLoader.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/loader/FrameLoader.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/loader/FrameLoader.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -3649,10 +3649,8 @@
</span><span class="cx">         loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, formState.release());    
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest&amp; request, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; data)
</del><ins>+unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest&amp; request, StoredCredentials storedCredentials, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; data)
</ins><span class="cx"> {
</span><del>-    // Since this is a subresource, we can load any URL (we ignore the return value).
-    // But we still want to know whether we should hide the referrer or not, so we call the canLoad method.
</del><span class="cx">     String referrer = m_outgoingReferrer;
</span><span class="cx">     if (shouldHideReferrer(request.url(), referrer))
</span><span class="cx">         referrer = String();
</span><span class="lines">@@ -3690,7 +3688,7 @@
</span><span class="cx">                 error = cannotShowURLError(newRequest);
</span><span class="cx">         } else {
</span><span class="cx"> #endif
</span><del>-            ResourceHandle::loadResourceSynchronously(newRequest, error, response, data, m_frame);
</del><ins>+            ResourceHandle::loadResourceSynchronously(newRequest, storedCredentials, error, response, data, m_frame);
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(OFFLINE_WEB_APPLICATIONS)
</span><span class="cx">             // If normal loading results in a redirect to a resource with another origin (indicative of a captive portal), or a 4xx or 5xx status code or equivalent,
</span></span></pre></div>
<a id="trunkWebCoreloaderFrameLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/loader/FrameLoader.h (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/loader/FrameLoader.h        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/loader/FrameLoader.h        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;CachePolicy.h&quot;
</span><span class="cx"> #include &quot;FrameLoaderTypes.h&quot;
</span><span class="cx"> #include &quot;ResourceRequest.h&quot;
</span><ins>+#include &quot;ThreadableLoader.h&quot;
</ins><span class="cx"> #include &quot;Timer.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -147,7 +148,7 @@
</span><span class="cx">         // Called by createWindow in JSDOMWindowBase.cpp, e.g. to fulfill a modal dialog creation
</span><span class="cx">         Frame* createWindow(FrameLoader* frameLoaderForFrameLookup, const FrameLoadRequest&amp;, const WindowFeatures&amp;, bool&amp; created);
</span><span class="cx"> 
</span><del>-        unsigned long loadResourceSynchronously(const ResourceRequest&amp;, ResourceError&amp;, ResourceResponse&amp;, Vector&lt;char&gt;&amp; data);
</del><ins>+        unsigned long loadResourceSynchronously(const ResourceRequest&amp;, StoredCredentials, ResourceError&amp;, ResourceResponse&amp;, Vector&lt;char&gt;&amp; data);
</ins><span class="cx"> 
</span><span class="cx">         bool canHandleRequest(const ResourceRequest&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebCoreloaderThreadableLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/loader/ThreadableLoader.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/loader/ThreadableLoader.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/loader/ThreadableLoader.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -40,33 +40,33 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;ThreadableLoader&gt; ThreadableLoader::create(ScriptExecutionContext* context, ThreadableLoaderClient* client, const ResourceRequest&amp; request, LoadCallbacks callbacksSetting, ContentSniff contentSniff) 
</del><ins>+PassRefPtr&lt;ThreadableLoader&gt; ThreadableLoader::create(ScriptExecutionContext* context, ThreadableLoaderClient* client, const ResourceRequest&amp; request, LoadCallbacks callbacksSetting, ContentSniff contentSniff, StoredCredentials storedCredentials) 
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(client);
</span><span class="cx">     ASSERT(context);
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WORKERS)
</span><span class="cx">     if (context-&gt;isWorkerContext())
</span><del>-        return WorkerThreadableLoader::create(static_cast&lt;WorkerContext*&gt;(context), client, WorkerRunLoop::defaultMode(), request, callbacksSetting, contentSniff);
</del><ins>+        return WorkerThreadableLoader::create(static_cast&lt;WorkerContext*&gt;(context), client, WorkerRunLoop::defaultMode(), request, callbacksSetting, contentSniff, storedCredentials);
</ins><span class="cx"> #endif // ENABLE(WORKERS)
</span><span class="cx"> 
</span><span class="cx">     ASSERT(context-&gt;isDocument());
</span><del>-    return DocumentThreadableLoader::create(static_cast&lt;Document*&gt;(context), client, request, callbacksSetting, contentSniff);
</del><ins>+    return DocumentThreadableLoader::create(static_cast&lt;Document*&gt;(context), client, request, callbacksSetting, contentSniff, storedCredentials);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ThreadableLoader::loadResourceSynchronously(ScriptExecutionContext* context, const ResourceRequest&amp; request, ThreadableLoaderClient&amp; client)
</del><ins>+void ThreadableLoader::loadResourceSynchronously(ScriptExecutionContext* context, const ResourceRequest&amp; request, ThreadableLoaderClient&amp; client, StoredCredentials storedCredentials)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(context);
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WORKERS)
</span><span class="cx">     if (context-&gt;isWorkerContext()) {
</span><del>-        WorkerThreadableLoader::loadResourceSynchronously(static_cast&lt;WorkerContext*&gt;(context), request, client);
</del><ins>+        WorkerThreadableLoader::loadResourceSynchronously(static_cast&lt;WorkerContext*&gt;(context), request, client, storedCredentials);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> #endif // ENABLE(WORKERS)
</span><span class="cx"> 
</span><span class="cx">     ASSERT(context-&gt;isDocument());
</span><del>-    DocumentThreadableLoader::loadResourceSynchronously(static_cast&lt;Document*&gt;(context), request, client);
</del><ins>+    DocumentThreadableLoader::loadResourceSynchronously(static_cast&lt;Document*&gt;(context), request, client, storedCredentials);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkWebCoreloaderThreadableLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/loader/ThreadableLoader.h (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/loader/ThreadableLoader.h        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/loader/ThreadableLoader.h        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -53,12 +53,17 @@
</span><span class="cx">         DoNotSniffContent
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    enum StoredCredentials {
+        AllowStoredCredentials,
+        DoNotAllowStoredCredentials
+    };
+
</ins><span class="cx">     // Useful for doing loader operations from any thread (not threadsafe, 
</span><span class="cx">     // just able to run on threads other than the main thread).
</span><span class="cx">     class ThreadableLoader : Noncopyable {
</span><span class="cx">     public:
</span><del>-        static void loadResourceSynchronously(ScriptExecutionContext*, const ResourceRequest&amp;, ThreadableLoaderClient&amp;);
-        static PassRefPtr&lt;ThreadableLoader&gt; create(ScriptExecutionContext*, ThreadableLoaderClient*, const ResourceRequest&amp;, LoadCallbacks, ContentSniff);
</del><ins>+        static void loadResourceSynchronously(ScriptExecutionContext*, const ResourceRequest&amp;, ThreadableLoaderClient&amp;, StoredCredentials);
+        static PassRefPtr&lt;ThreadableLoader&gt; create(ScriptExecutionContext*, ThreadableLoaderClient*, const ResourceRequest&amp;, LoadCallbacks, ContentSniff, StoredCredentials);
</ins><span class="cx"> 
</span><span class="cx">         virtual void cancel() = 0;
</span><span class="cx">         void ref() { refThreadableLoader(); }
</span></span></pre></div>
<a id="trunkWebCoreloaderWorkerThreadableLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/loader/WorkerThreadableLoader.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/loader/WorkerThreadableLoader.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/loader/WorkerThreadableLoader.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -55,11 +55,11 @@
</span><span class="cx"> 
</span><span class="cx"> // FIXME: The assumption that we can upcast worker object proxy to WorkerMessagingProxy will not be true in multi-process implementation.
</span><span class="cx"> WorkerThreadableLoader::WorkerThreadableLoader(WorkerContext* workerContext, ThreadableLoaderClient* client, const String&amp; taskMode, const ResourceRequest&amp; request, LoadCallbacks callbacksSetting,
</span><del>-                                               ContentSniff contentSniff)
</del><ins>+                                               ContentSniff contentSniff, StoredCredentials storedCredentials)
</ins><span class="cx">     : m_workerContext(workerContext)
</span><span class="cx">     , m_workerClientWrapper(ThreadableLoaderClientWrapper::create(client))
</span><span class="cx">     , m_bridge(*(new MainThreadBridge(m_workerClientWrapper, *(static_cast&lt;WorkerMessagingProxy*&gt;(m_workerContext-&gt;thread()-&gt;workerObjectProxy())), taskMode, request, callbacksSetting,
</span><del>-                                      contentSniff)))
</del><ins>+                                      contentSniff, storedCredentials)))
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -68,7 +68,7 @@
</span><span class="cx">     m_bridge.destroy();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WorkerThreadableLoader::loadResourceSynchronously(WorkerContext* workerContext, const ResourceRequest&amp; request, ThreadableLoaderClient&amp; client)
</del><ins>+void WorkerThreadableLoader::loadResourceSynchronously(WorkerContext* workerContext, const ResourceRequest&amp; request, ThreadableLoaderClient&amp; client, StoredCredentials storedCredentials)
</ins><span class="cx"> {
</span><span class="cx">     WorkerRunLoop&amp; runLoop = workerContext-&gt;thread()-&gt;runLoop();
</span><span class="cx"> 
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx">     mode.append(String::number(runLoop.createUniqueId()));
</span><span class="cx"> 
</span><span class="cx">     ContentSniff contentSniff = request.url().isLocalFile() ? SniffContent : DoNotSniffContent;
</span><del>-    RefPtr&lt;WorkerThreadableLoader&gt; loader = WorkerThreadableLoader::create(workerContext, &amp;client, mode, request, DoNotSendLoadCallbacks, contentSniff);
</del><ins>+    RefPtr&lt;WorkerThreadableLoader&gt; loader = WorkerThreadableLoader::create(workerContext, &amp;client, mode, request, DoNotSendLoadCallbacks, contentSniff, storedCredentials);
</ins><span class="cx"> 
</span><span class="cx">     MessageQueueWaitResult result = MessageQueueMessageReceived;
</span><span class="cx">     while (!loader-&gt;done() &amp;&amp; result != MessageQueueTerminated)
</span><span class="lines">@@ -93,20 +93,20 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WorkerThreadableLoader::MainThreadBridge::MainThreadBridge(PassRefPtr&lt;ThreadableLoaderClientWrapper&gt; workerClientWrapper, WorkerMessagingProxy&amp; messagingProxy, const String&amp; taskMode,
</span><del>-                                                           const ResourceRequest&amp; request, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
</del><ins>+                                                           const ResourceRequest&amp; request, LoadCallbacks callbacksSetting, ContentSniff contentSniff, StoredCredentials storedCredentials)
</ins><span class="cx">     : m_workerClientWrapper(workerClientWrapper)
</span><span class="cx">     , m_messagingProxy(messagingProxy)
</span><span class="cx">     , m_taskMode(taskMode.copy())
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_workerClientWrapper.get());
</span><del>-    m_messagingProxy.postTaskToWorkerObject(createCallbackTask(&amp;MainThreadBridge::mainThreadCreateLoader, this, request, callbacksSetting, contentSniff));
</del><ins>+    m_messagingProxy.postTaskToWorkerObject(createCallbackTask(&amp;MainThreadBridge::mainThreadCreateLoader, this, request, callbacksSetting, contentSniff, storedCredentials));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WorkerThreadableLoader::MainThreadBridge::~MainThreadBridge()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ScriptExecutionContext* context, MainThreadBridge* thisPtr, auto_ptr&lt;CrossThreadResourceRequestData&gt; requestData, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
</del><ins>+void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ScriptExecutionContext* context, MainThreadBridge* thisPtr, auto_ptr&lt;CrossThreadResourceRequestData&gt; requestData, LoadCallbacks callbacksSetting, ContentSniff contentSniff, StoredCredentials storedCredentials)
</ins><span class="cx"> {
</span><span class="cx">     // FIXME: This assert fails for nested workers.  Removing the assert would allow it to work,
</span><span class="cx">     // but then there would be one WorkerThreadableLoader in every intermediate worker simply
</span><span class="lines">@@ -125,7 +125,7 @@
</span><span class="cx">     // FIXME: If the a site requests a local resource, then this will return a non-zero value but the sync path
</span><span class="cx">     // will return a 0 value.  Either this should return 0 or the other code path should do a callback with
</span><span class="cx">     // a failure.
</span><del>-    thisPtr-&gt;m_mainThreadLoader = ThreadableLoader::create(context, thisPtr, *request, callbacksSetting, contentSniff);
</del><ins>+    thisPtr-&gt;m_mainThreadLoader = ThreadableLoader::create(context, thisPtr, *request, callbacksSetting, contentSniff, storedCredentials);
</ins><span class="cx">     ASSERT(thisPtr-&gt;m_mainThreadLoader);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebCoreloaderWorkerThreadableLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/loader/WorkerThreadableLoader.h (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/loader/WorkerThreadableLoader.h        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/loader/WorkerThreadableLoader.h        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -55,10 +55,10 @@
</span><span class="cx"> 
</span><span class="cx">     class WorkerThreadableLoader : public RefCounted&lt;WorkerThreadableLoader&gt;, public ThreadableLoader {
</span><span class="cx">     public:
</span><del>-        static void loadResourceSynchronously(WorkerContext*, const ResourceRequest&amp;, ThreadableLoaderClient&amp;);
-        static PassRefPtr&lt;WorkerThreadableLoader&gt; create(WorkerContext* workerContext, ThreadableLoaderClient* client, const String&amp; taskMode, const ResourceRequest&amp; request, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
</del><ins>+        static void loadResourceSynchronously(WorkerContext*, const ResourceRequest&amp;, ThreadableLoaderClient&amp;, StoredCredentials);
+        static PassRefPtr&lt;WorkerThreadableLoader&gt; create(WorkerContext* workerContext, ThreadableLoaderClient* client, const String&amp; taskMode, const ResourceRequest&amp; request, LoadCallbacks callbacksSetting, ContentSniff contentSniff, StoredCredentials storedCredentials)
</ins><span class="cx">         {
</span><del>-            return adoptRef(new WorkerThreadableLoader(workerContext, client, taskMode, request, callbacksSetting, contentSniff));
</del><ins>+            return adoptRef(new WorkerThreadableLoader(workerContext, client, taskMode, request, callbacksSetting, contentSniff, storedCredentials));
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         ~WorkerThreadableLoader();
</span><span class="lines">@@ -97,7 +97,7 @@
</span><span class="cx">         class MainThreadBridge : ThreadableLoaderClient {
</span><span class="cx">         public:
</span><span class="cx">             // All executed on the worker context's thread.
</span><del>-            MainThreadBridge(PassRefPtr&lt;ThreadableLoaderClientWrapper&gt;, WorkerMessagingProxy&amp;, const String&amp; taskMode, const ResourceRequest&amp;, LoadCallbacks, ContentSniff);
</del><ins>+            MainThreadBridge(PassRefPtr&lt;ThreadableLoaderClientWrapper&gt;, WorkerMessagingProxy&amp;, const String&amp; taskMode, const ResourceRequest&amp;, LoadCallbacks, ContentSniff, StoredCredentials);
</ins><span class="cx">             void cancel();
</span><span class="cx">             void destroy();
</span><span class="cx"> 
</span><span class="lines">@@ -109,7 +109,7 @@
</span><span class="cx">             static void mainThreadDestroy(ScriptExecutionContext*, MainThreadBridge*);
</span><span class="cx">             ~MainThreadBridge();
</span><span class="cx"> 
</span><del>-            static void mainThreadCreateLoader(ScriptExecutionContext*, MainThreadBridge*, std::auto_ptr&lt;CrossThreadResourceRequestData&gt;, LoadCallbacks, ContentSniff);
</del><ins>+            static void mainThreadCreateLoader(ScriptExecutionContext*, MainThreadBridge*, std::auto_ptr&lt;CrossThreadResourceRequestData&gt;, LoadCallbacks, ContentSniff, StoredCredentials);
</ins><span class="cx">             static void mainThreadCancel(ScriptExecutionContext*, MainThreadBridge*);
</span><span class="cx">             virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
</span><span class="cx">             virtual void didReceiveResponse(const ResourceResponse&amp;);
</span><span class="lines">@@ -133,7 +133,7 @@
</span><span class="cx">             String m_taskMode;
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        WorkerThreadableLoader(WorkerContext*, ThreadableLoaderClient*, const String&amp; taskMode, const ResourceRequest&amp;, LoadCallbacks, ContentSniff);
</del><ins>+        WorkerThreadableLoader(WorkerContext*, ThreadableLoaderClient*, const String&amp; taskMode, const ResourceRequest&amp;, LoadCallbacks, ContentSniff, StoredCredentials);
</ins><span class="cx"> 
</span><span class="cx">         RefPtr&lt;WorkerContext&gt; m_workerContext;
</span><span class="cx">         RefPtr&lt;ThreadableLoaderClientWrapper&gt; m_workerClientWrapper;
</span></span></pre></div>
<a id="trunkWebCoreplatformnetworkResourceHandleh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/platform/network/ResourceHandle.h (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/platform/network/ResourceHandle.h        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/platform/network/ResourceHandle.h        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AuthenticationChallenge.h&quot;
</span><span class="cx"> #include &quot;HTTPHeaderMap.h&quot;
</span><ins>+#include &quot;ThreadableLoader.h&quot;
</ins><span class="cx"> #include &lt;wtf/OwnPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if USE(SOUP)
</span><span class="lines">@@ -103,7 +104,7 @@
</span><span class="cx">     // FIXME: should not need the Frame
</span><span class="cx">     static PassRefPtr&lt;ResourceHandle&gt; create(const ResourceRequest&amp;, ResourceHandleClient*, Frame*, bool defersLoading, bool shouldContentSniff, bool mightDownloadFromHandle = false);
</span><span class="cx"> 
</span><del>-    static void loadResourceSynchronously(const ResourceRequest&amp;, ResourceError&amp;, ResourceResponse&amp;, Vector&lt;char&gt;&amp; data, Frame* frame);
</del><ins>+    static void loadResourceSynchronously(const ResourceRequest&amp;, StoredCredentials, ResourceError&amp;, ResourceResponse&amp;, Vector&lt;char&gt;&amp; data, Frame* frame);
</ins><span class="cx">     static bool willLoadFromCache(ResourceRequest&amp;);
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     static bool didSendBodyDataDelegateExists();
</span><span class="lines">@@ -112,6 +113,7 @@
</span><span class="cx">     ~ResourceHandle();
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC) || USE(CFNETWORK)
</span><ins>+    void willSendRequest(ResourceRequest&amp;, const ResourceResponse&amp; redirectResponse);
</ins><span class="cx">     bool shouldUseCredentialStorage();
</span><span class="cx"> #endif
</span><span class="cx"> #if PLATFORM(MAC) || USE(CFNETWORK) || USE(CURL)
</span></span></pre></div>
<a id="trunkWebCoreplatformnetworkResourceHandleClienth"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/platform/network/ResourceHandleClient.h (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/platform/network/ResourceHandleClient.h        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/platform/network/ResourceHandleClient.h        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -79,8 +79,6 @@
</span><span class="cx">         virtual bool shouldUseCredentialStorage(ResourceHandle*) { return false; }
</span><span class="cx">         virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&amp;) { }
</span><span class="cx">         virtual void didCancelAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&amp;) { }
</span><del>-        virtual void receivedCredential(ResourceHandle*, const AuthenticationChallenge&amp;, const Credential&amp;) { }
-        virtual void receivedRequestToContinueWithoutCredential(ResourceHandle*, const AuthenticationChallenge&amp;) { }
</del><span class="cx">         virtual void receivedCancellation(ResourceHandle*, const AuthenticationChallenge&amp;) { }
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)        
</span></span></pre></div>
<a id="trunkWebCoreplatformnetworkResourceHandleInternalh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/platform/network/ResourceHandleInternal.h (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/platform/network/ResourceHandleInternal.h        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/platform/network/ResourceHandleInternal.h        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -133,6 +133,10 @@
</span><span class="cx"> #endif
</span><span class="cx">             , m_failureTimer(loader, &amp;ResourceHandle::fireFailure)
</span><span class="cx">         {
</span><ins>+            const KURL&amp; url = m_request.url();
+            m_user = url.user();
+            m_pass = url.pass();
+            m_request.removeCredentials();
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         ~ResourceHandleInternal();
</span><span class="lines">@@ -141,6 +145,10 @@
</span><span class="cx">         ResourceHandleClient* m_client;
</span><span class="cx">         
</span><span class="cx">         ResourceRequest m_request;
</span><ins>+
+        // Suggested credentials for the current redirection step.
+        String m_user;
+        String m_pass;
</ins><span class="cx">         
</span><span class="cx">         int status;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebCoreplatformnetworkResourceRequestBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/platform/network/ResourceRequestBase.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/platform/network/ResourceRequestBase.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/platform/network/ResourceRequestBase.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -117,6 +117,16 @@
</span><span class="cx">     m_platformRequestUpdated = false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ResourceRequestBase::removeCredentials()
+{
+    updateResourceRequest(); 
+
+    m_url.setUser(String());
+    m_url.setPass(String());
+
+    m_platformRequestUpdated = false;
+}
+
</ins><span class="cx"> ResourceRequestCachePolicy ResourceRequestBase::cachePolicy() const
</span><span class="cx"> {
</span><span class="cx">     updateResourceRequest(); 
</span></span></pre></div>
<a id="trunkWebCoreplatformnetworkResourceRequestBaseh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/platform/network/ResourceRequestBase.h (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/platform/network/ResourceRequestBase.h        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/platform/network/ResourceRequestBase.h        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -63,6 +63,8 @@
</span><span class="cx">         const KURL&amp; url() const;
</span><span class="cx">         void setURL(const KURL&amp; url);
</span><span class="cx"> 
</span><ins>+        void removeCredentials();
+
</ins><span class="cx">         ResourceRequestCachePolicy cachePolicy() const;
</span><span class="cx">         void setCachePolicy(ResourceRequestCachePolicy cachePolicy);
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkWebCoreplatformnetworkcfResourceHandleCFNetcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/platform/network/cf/ResourceHandleCFNet.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/platform/network/cf/ResourceHandleCFNet.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/platform/network/cf/ResourceHandleCFNet.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -53,11 +53,33 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class WebCoreCredentialStorage {
+public:
+    static void set(CFURLProtectionSpaceRef protectionSpace, CFURLCredentialRef credential)
+    {
+        if (!m_storage)
+            m_storage = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
+        CFDictionarySetValue(m_storage, protectionSpace, credential);
+    }
+
+    static CFURLCredentialRef get(CFURLProtectionSpaceRef protectionSpace)
+    {
+        if (!m_storage)
+            return 0;
+        return (CFURLCredentialRef)CFDictionaryGetValue(m_storage, protectionSpace);
+    }
+
+private:
+    static CFMutableDictionaryRef m_storage;
+};
+
+CFMutableDictionaryRef WebCoreCredentialStorage::m_storage;
+
</ins><span class="cx"> static CFStringRef WebCoreSynchronousLoaderRunLoopMode = CFSTR(&quot;WebCoreSynchronousLoaderRunLoopMode&quot;);
</span><span class="cx"> 
</span><span class="cx"> class WebCoreSynchronousLoader {
</span><span class="cx"> public:
</span><del>-    static RetainPtr&lt;CFDataRef&gt; load(const ResourceRequest&amp;, ResourceResponse&amp;, ResourceError&amp;);
</del><ins>+    static RetainPtr&lt;CFDataRef&gt; load(const ResourceRequest&amp;, StoredCredentials, ResourceResponse&amp;, ResourceError&amp;);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WebCoreSynchronousLoader(ResourceResponse&amp; response, ResourceError&amp; error)
</span><span class="lines">@@ -73,9 +95,13 @@
</span><span class="cx">     static void didFinishLoading(CFURLConnectionRef, const void* clientInfo);
</span><span class="cx">     static void didFail(CFURLConnectionRef, CFErrorRef, const void* clientInfo);
</span><span class="cx">     static void didReceiveChallenge(CFURLConnectionRef, CFURLAuthChallengeRef, const void* clientInfo);
</span><ins>+    static Boolean shouldUseCredentialStorage(CFURLConnectionRef, const void* clientInfo);
</ins><span class="cx"> 
</span><span class="cx">     bool m_isDone;
</span><span class="cx">     RetainPtr&lt;CFURLRef&gt; m_url;
</span><ins>+    RetainPtr&lt;CFStringRef&gt; m_user;
+    RetainPtr&lt;CFStringRef&gt; m_pass;
+    bool m_allowStoredCredentials;
</ins><span class="cx">     ResourceResponse&amp; m_response;
</span><span class="cx">     RetainPtr&lt;CFMutableDataRef&gt; m_data;
</span><span class="cx">     ResourceError&amp; m_error;
</span><span class="lines">@@ -106,8 +132,7 @@
</span><span class="cx">     LOG(Network, &quot;CFNet - willSendRequest(conn=%p, handle=%p) (%s)&quot;, conn, handle, handle-&gt;request().url().string().utf8().data());
</span><span class="cx"> 
</span><span class="cx">     ResourceRequest request(cfRequest);
</span><del>-    if (handle-&gt;client())
-        handle-&gt;client()-&gt;willSendRequest(handle, request, cfRedirectResponse);
</del><ins>+    handle-&gt;willSendRequest(request, cfRedirectResponse);
</ins><span class="cx"> 
</span><span class="cx">     cfRequest = request.cfURLRequest();
</span><span class="cx"> 
</span><span class="lines">@@ -330,7 +355,7 @@
</span><span class="cx"> 
</span><span class="cx">     RetainPtr&lt;CFURLRequestRef&gt; request(AdoptCF, makeFinalRequest(d-&gt;m_request, d-&gt;m_shouldContentSniff));
</span><span class="cx"> 
</span><del>-    CFURLConnectionClient_V3 client = { 3, this, 0, 0, 0, willSendRequest, didReceiveResponse, didReceiveData, NULL, didFinishLoading, didFail, willCacheResponse, didReceiveChallenge, didSendBodyData, shouldUseCredentialStorageCallback, 0};
</del><ins>+    CFURLConnectionClient_V3 client = { 3, this, 0, 0, 0, WebCore::willSendRequest, didReceiveResponse, didReceiveData, NULL, didFinishLoading, didFail, willCacheResponse, didReceiveChallenge, didSendBodyData, shouldUseCredentialStorageCallback, 0};
</ins><span class="cx"> 
</span><span class="cx">     d-&gt;m_connection.adoptCF(CFURLConnectionCreate(0, request.get(), reinterpret_cast&lt;CFURLConnectionClient*&gt;(&amp;client)));
</span><span class="cx"> 
</span><span class="lines">@@ -362,6 +387,16 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ResourceHandle::willSendRequest(ResourceRequest&amp; request, const ResourceResponse&amp; redirectResponse)
+{
+    const KURL&amp; url = request.url();
+    d-&gt;m_user = url.user();
+    d-&gt;m_pass = url.pass();
+    request.removeCredentials();
+
+    client()-&gt;willSendRequest(this, request, redirectResponse);
+}
+
</ins><span class="cx"> bool ResourceHandle::shouldUseCredentialStorage()
</span><span class="cx"> {
</span><span class="cx">     LOG(Network, &quot;CFNet - shouldUseCredentialStorage()&quot;);
</span><span class="lines">@@ -379,7 +414,29 @@
</span><span class="cx">     // Since CFURLConnection networking relies on keeping a reference to the original CFURLAuthChallengeRef,
</span><span class="cx">     // we make sure that is actually present
</span><span class="cx">     ASSERT(challenge.cfURLAuthChallengeRef());
</span><del>-        
</del><ins>+
+    if (!d-&gt;m_user.isNull() &amp;&amp; !d-&gt;m_pass.isNull()) {
+        RetainPtr&lt;CFStringRef&gt; user(AdoptCF, d-&gt;m_user.createCFString());
+        RetainPtr&lt;CFStringRef&gt; pass(AdoptCF, d-&gt;m_pass.createCFString());
+        RetainPtr&lt;CFURLCredentialRef&gt; credential(AdoptCF,
+            CFURLCredentialCreate(kCFAllocatorDefault, user.get(), pass.get(), 0, kCFURLCredentialPersistenceNone));
+        WebCoreCredentialStorage::set(CFURLAuthChallengeGetProtectionSpace(challenge.cfURLAuthChallengeRef()), credential.get());
+        CFURLConnectionUseCredential(d-&gt;m_connection.get(), credential.get(), challenge.cfURLAuthChallengeRef());
+        d-&gt;m_user = String();
+        d-&gt;m_pass = String();
+        // FIXME: Per the specification, the user shouldn't be asked for credentials if there were incorrect ones provided explicitly.
+        return;
+    }
+
+    if (!challenge.previousFailureCount() &amp;&amp; (!client() || client()-&gt;shouldUseCredentialStorage(this))) {
+        CFURLCredentialRef credential = WebCoreCredentialStorage::get(CFURLAuthChallengeGetProtectionSpace(challenge.cfURLAuthChallengeRef()));
+        if (credential) {
+            ASSERT(CFURLCredentialGetPersistence(credential) == kCFURLCredentialPersistenceNone);
+            CFURLConnectionUseCredential(d-&gt;m_connection.get(), credential, challenge.cfURLAuthChallengeRef());
+            return;
+        }
+    }
+
</ins><span class="cx">     d-&gt;m_currentCFChallenge = challenge.cfURLAuthChallengeRef();
</span><span class="cx">     d-&gt;m_currentWebChallenge = AuthenticationChallenge(d-&gt;m_currentCFChallenge, this);
</span><span class="cx">     
</span><span class="lines">@@ -395,9 +452,17 @@
</span><span class="cx">     if (challenge != d-&gt;m_currentWebChallenge)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    CFURLCredentialRef cfCredential = createCF(credential);
-    CFURLConnectionUseCredential(d-&gt;m_connection.get(), cfCredential, challenge.cfURLAuthChallengeRef());
-    CFRelease(cfCredential);
</del><ins>+    if (credential.persistence() == CredentialPersistenceForSession) {
+        // Manage per-session credentials internally, because once NSURLCredentialPersistencePerSession is used, there is no way
+        // to ignore it for a particular request (short of removing it altogether).
+        Credential webCredential(credential.user(), credential.password(), CredentialPersistenceNone);
+        RetainPtr&lt;CFURLCredentialRef&gt; cfCredential(AdoptCF, createCF(webCredential));
+        WebCoreCredentialStorage::set(CFURLAuthChallengeGetProtectionSpace(challenge.cfURLAuthChallengeRef()), cfCredential.get());
+        CFURLConnectionUseCredential(d-&gt;m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef());
+    } else {
+        RetainPtr&lt;CFURLCredentialRef&gt; cfCredential(AdoptCF, createCF(credential));
+        CFURLConnectionUseCredential(d-&gt;m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef());
+    }
</ins><span class="cx"> 
</span><span class="cx">     clearAuthentication();
</span><span class="cx"> }
</span><span class="lines">@@ -436,11 +501,11 @@
</span><span class="cx">     return d-&gt;m_connection.releaseRef();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceHandle::loadResourceSynchronously(const ResourceRequest&amp; request, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; vector, Frame*)
</del><ins>+void ResourceHandle::loadResourceSynchronously(const ResourceRequest&amp; request, StoredCredentials storedCredentials, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; vector, Frame*)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!request.isEmpty());
</span><span class="cx"> 
</span><del>-    RetainPtr&lt;CFDataRef&gt; data = WebCoreSynchronousLoader::load(request, response, error);
</del><ins>+    RetainPtr&lt;CFDataRef&gt; data = WebCoreSynchronousLoader::load(request, storedCredentials, response, error);
</ins><span class="cx"> 
</span><span class="cx">     if (!error.isNull()) {
</span><span class="cx">         response = ResourceResponse(request.url(), String(), 0, String(), String());
</span><span class="lines">@@ -518,6 +583,17 @@
</span><span class="cx"> 
</span><span class="cx">     loader-&gt;m_url = CFURLRequestGetURL(cfRequest);
</span><span class="cx"> 
</span><ins>+    if (cfRedirectResponse) {
+        // Take user/pass out of the URL.
+        loader-&gt;m_user.adoptCF(CFURLCopyUserName(loader-&gt;m_url.get()));
+        loader-&gt;m_pass.adoptCF(CFURLCopyPassword(loader-&gt;m_url.get()));
+        if (loader-&gt;m_user || loader-&gt;m_pass) {
+            ResourceRequest requestWithoutCredentials = cfRequest;
+            requestWithoutCredentials.removeCredentials();
+            return requestWithoutCredentials.createCFURLRequest();
+        }
+    }
+
</ins><span class="cx">     CFRetain(cfRequest);
</span><span class="cx">     return cfRequest;
</span><span class="cx"> }
</span><span class="lines">@@ -561,20 +637,52 @@
</span><span class="cx"> {
</span><span class="cx">     WebCoreSynchronousLoader* loader = static_cast&lt;WebCoreSynchronousLoader*&gt;(const_cast&lt;void*&gt;(clientInfo));
</span><span class="cx"> 
</span><del>-    // FIXME: Mac uses credentials from URL here, should we do the same?
</del><ins>+    if (loader-&gt;m_user &amp;&amp; loader-&gt;m_pass) {
+        RetainPtr&lt;CFURLCredentialRef&gt; credential(AdoptCF,
+            CFURLCredentialCreate(kCFAllocatorDefault, loader-&gt;m_user.get(), loader-&gt;m_pass.get(), 0, kCFURLCredentialPersistenceNone));
+        WebCoreCredentialStorage::set(CFURLAuthChallengeGetProtectionSpace(challenge), credential.get());
+        CFURLConnectionUseCredential(conn, credential.get(), challenge);
+        loader-&gt;m_user = 0;
+        loader-&gt;m_pass = 0;
+        return;
+    }
+    if (!CFURLAuthChallengeGetPreviousFailureCount(challenge) &amp;&amp; m_allowStoredCredentials) {
+        CFURLCredentialRef credential = WebCoreCredentialStorage::get(CFURLAuthChallengeGetProtectionSpace(challenge));
+        if (credential) {
+            ASSERT(CFURLCredentialGetPersistence(credential) == kCFURLCredentialPersistenceNone);
+            CFURLConnectionUseCredential(conn, credential, challenge);
+            return;
+        }
+    }
+    // FIXME: The user should be asked for credentials, as in async case.
</ins><span class="cx">     CFURLConnectionUseCredential(conn, 0, challenge);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RetainPtr&lt;CFDataRef&gt; WebCoreSynchronousLoader::load(const ResourceRequest&amp; request, ResourceResponse&amp; response, ResourceError&amp; error)
</del><ins>+Boolean WebCoreSynchronousLoader::shouldUseCredentialStorage(CFURLConnectionRef, const void* clientInfo)
</ins><span class="cx"> {
</span><ins>+    WebCoreSynchronousLoader* loader = static_cast&lt;WebCoreSynchronousLoader*&gt;(const_cast&lt;void*&gt;(clientInfo));
+
+    // FIXME: We should ask FrameLoaderClient whether using credential storage is globally forbidden.
+    return loader-&gt;m_allowStoredCredentials;
+}
+
+RetainPtr&lt;CFDataRef&gt; WebCoreSynchronousLoader::load(const ResourceRequest&amp; request, StoredCredentials storedCredentials, ResourceResponse&amp; response, ResourceError&amp; error)
+{
</ins><span class="cx">     ASSERT(response.isNull());
</span><span class="cx">     ASSERT(error.isNull());
</span><span class="cx"> 
</span><span class="cx">     WebCoreSynchronousLoader loader(response, error);
</span><span class="cx"> 
</span><ins>+    KURL url = request.url();
+
+    // Take user/pass out of the URL.
+    loader.m_user.adoptCF(url.user().createCFString());
+    loader.m_pass.adoptCF(url.pass().createCFString());
+    loader.m_allowStoredCredentials = (storedCredentials == AllowStoredCredentials);
+    request.removeCredentials();
</ins><span class="cx">     RetainPtr&lt;CFURLRequestRef&gt; cfRequest(AdoptCF, makeFinalRequest(request, true));
</span><span class="cx"> 
</span><del>-    CFURLConnectionClient_V3 client = { 3, &amp;loader, 0, 0, 0, willSendRequest, didReceiveResponse, didReceiveData, 0, didFinishLoading, didFail, 0, didReceiveChallenge, 0, 0, 0 };
</del><ins>+    CFURLConnectionClient_V3 client = { 3, &amp;loader, 0, 0, 0, willSendRequest, didReceiveResponse, didReceiveData, 0, didFinishLoading, didFail, 0, didReceiveChallenge, 0, shouldUseCredentialStorage, 0 };
</ins><span class="cx"> 
</span><span class="cx">     RetainPtr&lt;CFURLConnectionRef&gt; connection(AdoptCF, CFURLConnectionCreate(kCFAllocatorDefault, cfRequest.get(), reinterpret_cast&lt;CFURLConnectionClient*&gt;(&amp;client)));
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebCoreplatformnetworkcurlResourceHandleCurlcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/platform/network/curl/ResourceHandleCurl.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/platform/network/curl/ResourceHandleCurl.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/platform/network/curl/ResourceHandleCurl.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -191,7 +191,7 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceHandle::loadResourceSynchronously(const ResourceRequest&amp; request, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; data, Frame*)
</del><ins>+void ResourceHandle::loadResourceSynchronously(const ResourceRequest&amp; request, StoredCredentials storedCredentials, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; data, Frame*)
</ins><span class="cx"> {
</span><span class="cx">     WebCoreSynchronousLoader syncLoader;
</span><span class="cx">     ResourceHandle handle(request, &amp;syncLoader, true, false, true);
</span></span></pre></div>
<a id="trunkWebCoreplatformnetworkmacResourceHandleMacmm"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/platform/network/mac/ResourceHandleMac.mm (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/platform/network/mac/ResourceHandleMac.mm        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/platform/network/mac/ResourceHandleMac.mm        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -48,12 +48,29 @@
</span><span class="cx"> 
</span><span class="cx"> using namespace WebCore;
</span><span class="cx"> 
</span><ins>+class WebCoreCredentialStorage {
+public:
+    static void set(NSURLCredential *credential, NSURLProtectionSpace *protectionSpace)
+    {
+        if (!m_storage)
+            m_storage = [[NSMutableDictionary alloc] init];
+        [m_storage setObject:credential forKey:protectionSpace];
+    }
+
+    static NSURLCredential *get(NSURLProtectionSpace *protectionSpace)
+    {
+        return static_cast&lt;NSURLCredential *&gt;([m_storage objectForKey:protectionSpace]);
+    }
+
+private:
+    static NSMutableDictionary* m_storage;
+};
+
+NSMutableDictionary* WebCoreCredentialStorage::m_storage;
+
</ins><span class="cx"> @interface WebCoreResourceHandleAsDelegate : NSObject &lt;NSURLAuthenticationChallengeSender&gt;
</span><span class="cx"> {
</span><span class="cx">     ResourceHandle* m_handle;
</span><del>-#ifndef BUILDING_ON_TIGER
-    NSURL *m_url;
-#endif
</del><span class="cx"> }
</span><span class="cx"> - (id)initWithHandle:(ResourceHandle*)handle;
</span><span class="cx"> - (void)detachHandle;
</span><span class="lines">@@ -67,12 +84,15 @@
</span><span class="cx"> 
</span><span class="cx"> @interface WebCoreSynchronousLoader : NSObject {
</span><span class="cx">     NSURL *m_url;
</span><ins>+    NSString *m_user;
+    NSString *m_pass;
+    BOOL m_allowStoredCredentials;
</ins><span class="cx">     NSURLResponse *m_response;
</span><span class="cx">     NSMutableData *m_data;
</span><span class="cx">     NSError *m_error;
</span><span class="cx">     BOOL m_isDone;
</span><span class="cx"> }
</span><del>-+ (NSData *)loadRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;
</del><ins>++ (NSData *)loadRequest:(NSURLRequest *)request allowStoredCredentials:(BOOL)allowStoredCredentials returningResponse:(NSURLResponse **)response error:(NSError **)error;
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> static NSString *WebCoreSynchronousLoaderRunLoopMode = @&quot;WebCoreSynchronousLoaderRunLoopMode&quot;;
</span><span class="lines">@@ -324,7 +344,7 @@
</span><span class="cx">     return nsURLResponse;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceHandle::loadResourceSynchronously(const ResourceRequest&amp; request, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; data, Frame*)
</del><ins>+void ResourceHandle::loadResourceSynchronously(const ResourceRequest&amp; request, StoredCredentials storedCredentials, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; data, Frame*)
</ins><span class="cx"> {
</span><span class="cx">     NSError *nsError = nil;
</span><span class="cx">     
</span><span class="lines">@@ -336,8 +356,9 @@
</span><span class="cx">     BEGIN_BLOCK_OBJC_EXCEPTIONS;
</span><span class="cx">     
</span><span class="cx"> #ifndef BUILDING_ON_TIGER
</span><del>-    result = [WebCoreSynchronousLoader loadRequest:request.nsURLRequest() returningResponse:&amp;nsURLResponse error:&amp;nsError];
</del><ins>+    result = [WebCoreSynchronousLoader loadRequest:request.nsURLRequest() allowStoredCredentials:(storedCredentials == AllowStoredCredentials) returningResponse:&amp;nsURLResponse error:&amp;nsError];
</ins><span class="cx"> #else
</span><ins>+    UNUSED_PARAM(storedCredentials);
</ins><span class="cx">     result = [NSURLConnection sendSynchronousRequest:request.nsURLRequest() returningResponse:&amp;nsURLResponse error:&amp;nsError];
</span><span class="cx"> #endif
</span><span class="cx">     END_BLOCK_OBJC_EXCEPTIONS;
</span><span class="lines">@@ -365,6 +386,16 @@
</span><span class="cx">     error = nsError;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ResourceHandle::willSendRequest(ResourceRequest&amp; request, const ResourceResponse&amp; redirectResponse)
+{
+    const KURL&amp; url = request.url();
+    d-&gt;m_user = url.user();
+    d-&gt;m_pass = url.pass();
+    request.removeCredentials();
+
+    client()-&gt;willSendRequest(this, request, redirectResponse);
+}
+
</ins><span class="cx"> bool ResourceHandle::shouldUseCredentialStorage()
</span><span class="cx"> {
</span><span class="cx">     if (client())
</span><span class="lines">@@ -380,7 +411,29 @@
</span><span class="cx">     // Since NSURLConnection networking relies on keeping a reference to the original NSURLAuthenticationChallenge,
</span><span class="cx">     // we make sure that is actually present
</span><span class="cx">     ASSERT(challenge.nsURLAuthenticationChallenge());
</span><del>-        
</del><ins>+
+    if (!d-&gt;m_user.isNull() &amp;&amp; !d-&gt;m_pass.isNull()) {
+        NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:d-&gt;m_user
+                                                                   password:d-&gt;m_pass
+                                                                persistence:NSURLCredentialPersistenceNone];
+        WebCoreCredentialStorage::set(credential, [mac(challenge) protectionSpace]);
+        [challenge.sender() useCredential:credential forAuthenticationChallenge:mac(challenge)];
+        [credential release];
+        // FIXME: Per the specification, the user shouldn't be asked for credentials if there were incorrect ones provided explicitly.
+        d-&gt;m_user = String();
+        d-&gt;m_pass = String();
+        return;
+    }
+
+    if (!challenge.previousFailureCount() &amp;&amp; (!client() || client()-&gt;shouldUseCredentialStorage(this))) {
+        NSURLCredential *credential = WebCoreCredentialStorage::get([mac(challenge) protectionSpace]);
+        if (credential) {
+            ASSERT([credential persistence] == NSURLCredentialPersistenceNone);
+            [challenge.sender() useCredential:credential forAuthenticationChallenge:mac(challenge)];
+            return;
+        }
+    }
+
</ins><span class="cx">     d-&gt;m_currentMacChallenge = challenge.nsURLAuthenticationChallenge();
</span><span class="cx">     NSURLAuthenticationChallenge *webChallenge = [[NSURLAuthenticationChallenge alloc] initWithAuthenticationChallenge:d-&gt;m_currentMacChallenge 
</span><span class="cx">                                                                                        sender:(id&lt;NSURLAuthenticationChallengeSender&gt;)delegate()];
</span><span class="lines">@@ -407,7 +460,14 @@
</span><span class="cx">     if (challenge != d-&gt;m_currentWebChallenge)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    [[d-&gt;m_currentMacChallenge sender] useCredential:mac(credential) forAuthenticationChallenge:d-&gt;m_currentMacChallenge];
</del><ins>+    if (credential.persistence() == CredentialPersistenceForSession) {
+        // Manage per-session credentials internally, because once NSURLCredentialPersistencePerSession is used, there is no way
+        // to ignore it for a particular request (short of removing it altogether).
+        Credential webCredential(credential.user(), credential.password(), CredentialPersistenceNone);
+        WebCoreCredentialStorage::set(mac(webCredential), [d-&gt;m_currentMacChallenge protectionSpace]);
+        [[d-&gt;m_currentMacChallenge sender] useCredential:mac(webCredential) forAuthenticationChallenge:d-&gt;m_currentMacChallenge];
+    } else
+        [[d-&gt;m_currentMacChallenge sender] useCredential:mac(credential) forAuthenticationChallenge:d-&gt;m_currentMacChallenge];
</ins><span class="cx"> 
</span><span class="cx">     clearAuthentication();
</span><span class="cx"> }
</span><span class="lines">@@ -445,14 +505,6 @@
</span><span class="cx">     return self;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#ifndef BUILDING_ON_TIGER
-- (void)dealloc
-{
-    [m_url release];
-    [super dealloc];
-}
-#endif
-
</del><span class="cx"> - (void)detachHandle
</span><span class="cx"> {
</span><span class="cx">     m_handle = 0;
</span><span class="lines">@@ -474,12 +526,7 @@
</span><span class="cx">     
</span><span class="cx">     CallbackGuard guard;
</span><span class="cx">     ResourceRequest request = newRequest;
</span><del>-    m_handle-&gt;client()-&gt;willSendRequest(m_handle, request, redirectResponse);
-#ifndef BUILDING_ON_TIGER
-    NSURL *copy = [[request.nsURLRequest() URL] copy];
-    [m_url release];
-    m_url = copy;
-#endif
</del><ins>+    m_handle-&gt;willSendRequest(request, redirectResponse);
</ins><span class="cx"> 
</span><span class="cx">     if (!ResourceHandle::didSendBodyDataDelegateExists()) {
</span><span class="cx">         // The client may change the request's body stream, in which case we have to re-associate
</span><span class="lines">@@ -509,22 +556,6 @@
</span><span class="cx"> - (void)connection:(NSURLConnection *)unusedConnection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
</span><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(unusedConnection);
</span><del>-
-#ifndef BUILDING_ON_TIGER
-    if ([challenge previousFailureCount] == 0) {
-        NSString *user = [m_url user];
-        NSString *password = [m_url password];
-
-        if (user &amp;&amp; password) {
-            NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:user
-                                                                     password:password
-                                                                  persistence:NSURLCredentialPersistenceForSession];
-            [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
-            [credential release];
-            return;
-        }
-    }
-#endif
</del><span class="cx">     
</span><span class="cx">     if (!m_handle)
</span><span class="cx">         return;
</span><span class="lines">@@ -717,6 +748,8 @@
</span><span class="cx"> - (void)dealloc
</span><span class="cx"> {
</span><span class="cx">     [m_url release];
</span><ins>+    [m_user release];
+    [m_pass release];
</ins><span class="cx">     [m_response release];
</span><span class="cx">     [m_data release];
</span><span class="cx">     [m_error release];
</span><span class="lines">@@ -724,10 +757,9 @@
</span><span class="cx">     [super dealloc];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (NSURLRequest *)connection:(NSURLConnection *)unusedConnection willSendRequest:(NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)unusedRedirectResponse
</del><ins>+- (NSURLRequest *)connection:(NSURLConnection *)unusedConnection willSendRequest:(NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse
</ins><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(unusedConnection);
</span><del>-    UNUSED_PARAM(unusedRedirectResponse);
</del><span class="cx"> 
</span><span class="cx">     // FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests.
</span><span class="cx">     if (m_url &amp;&amp; !protocolHostAndPortAreEqual(m_url, [newRequest URL])) {
</span><span class="lines">@@ -740,27 +772,52 @@
</span><span class="cx">     [m_url release];
</span><span class="cx">     m_url = copy;
</span><span class="cx"> 
</span><ins>+    if (redirectResponse) {
+        // Take user/pass out of the URL.
+        m_user = [[m_url user] copy];
+        m_pass = [[m_url password] copy];
+        if (m_user || m_pass) {
+            ResourceRequest requestWithoutCredentials = newRequest;
+            requestWithoutCredentials.removeCredentials();
+            return requestWithoutCredentials.nsURLRequest();
+        }
+    }
+
</ins><span class="cx">     return newRequest;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)unusedConnection
+{
+    UNUSED_PARAM(unusedConnection);
+
+    // FIXME: We should ask FrameLoaderClient whether using credential storage is globally forbidden.
+    return m_allowStoredCredentials;
+}
+
</ins><span class="cx"> - (void)connection:(NSURLConnection *)unusedConnection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
</span><span class="cx"> {
</span><span class="cx">     UNUSED_PARAM(unusedConnection);
</span><span class="cx"> 
</span><del>-    if ([challenge previousFailureCount] == 0) {
-        NSString *user = [m_url user];
-        NSString *password = [m_url password];
-        
-        if (user &amp;&amp; password) {
-            NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:user
-                                                                     password:password
-                                                                  persistence:NSURLCredentialPersistenceForSession];
</del><ins>+    if (m_user &amp;&amp; m_pass) {
+        NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:m_user
+                                                                   password:m_pass
+                                                                persistence:NSURLCredentialPersistenceNone];
+        WebCoreCredentialStorage::set(credential, [challenge protectionSpace]);
+        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
+        [credential release];
+        m_user = 0;
+        m_pass = 0;
+        return;
+    }
+    if ([challenge previousFailureCount] == 0 &amp;&amp; m_allowStoredCredentials) {
+        NSURLCredential *credential = WebCoreCredentialStorage::get([challenge protectionSpace]);
+        ASSERT([credential persistence] == NSURLCredentialPersistenceNone);
+        if (credential) {
</ins><span class="cx">             [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
</span><del>-            [credential release];
</del><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-    
</del><ins>+    // FIXME: The user should be asked for credentials, as in async case.
</ins><span class="cx">     [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -816,11 +873,22 @@
</span><span class="cx">     return [[m_error retain] autorelease];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-+ (NSData *)loadRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
</del><ins>++ (NSData *)loadRequest:(NSURLRequest *)request allowStoredCredentials:(BOOL)allowStoredCredentials returningResponse:(NSURLResponse **)response error:(NSError **)error
</ins><span class="cx"> {
</span><span class="cx">     WebCoreSynchronousLoader *delegate = [[WebCoreSynchronousLoader alloc] init];
</span><del>-    
-    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegate startImmediately:NO];
</del><ins>+
+    NSURL *url = [request URL];
+    delegate-&gt;m_user = [[url user] copy];
+    delegate-&gt;m_pass = [[url password] copy];
+    delegate-&gt;m_allowStoredCredentials = allowStoredCredentials;
+    NSURLConnection *connection;
+    if (delegate-&gt;m_user || delegate-&gt;m_pass) {
+        ResourceRequest requestWithoutCredentials = request;
+        requestWithoutCredentials.removeCredentials();
+        connection = [[NSURLConnection alloc] initWithRequest:requestWithoutCredentials.nsURLRequest() delegate:delegate startImmediately:NO];
+    } else
+        connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegate startImmediately:NO];
+
</ins><span class="cx">     [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:WebCoreSynchronousLoaderRunLoopMode];
</span><span class="cx">     [connection start];
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkWebCoreplatformnetworkqtResourceHandleQtcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/platform/network/qt/ResourceHandleQt.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/platform/network/qt/ResourceHandleQt.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/platform/network/qt/ResourceHandleQt.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -171,7 +171,7 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceHandle::loadResourceSynchronously(const ResourceRequest&amp; request, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; data, Frame* frame)
</del><ins>+void ResourceHandle::loadResourceSynchronously(const ResourceRequest&amp; request, StoredCredentials /*storedCredentials*/, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; data, Frame* frame)
</ins><span class="cx"> {
</span><span class="cx">     WebCoreSynchronousLoader syncLoader;
</span><span class="cx">     ResourceHandle handle(request, &amp;syncLoader, true, false, true);
</span></span></pre></div>
<a id="trunkWebCoreplatformnetworksoupResourceHandleSoupcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/platform/network/soup/ResourceHandleSoup.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/platform/network/soup/ResourceHandleSoup.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/platform/network/soup/ResourceHandleSoup.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -644,7 +644,7 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceHandle::loadResourceSynchronously(const ResourceRequest&amp; request, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; data, Frame* frame)
</del><ins>+void ResourceHandle::loadResourceSynchronously(const ResourceRequest&amp; request, StoredCredentials /*storedCredentials*/, ResourceError&amp; error, ResourceResponse&amp; response, Vector&lt;char&gt;&amp; data, Frame* frame)
</ins><span class="cx"> {
</span><span class="cx">     WebCoreSynchronousLoader syncLoader(error, response, data);
</span><span class="cx">     ResourceHandle handle(request, &amp;syncLoader, true, false, true);
</span></span></pre></div>
<a id="trunkWebCoreworkersWorkerContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/workers/WorkerContext.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/workers/WorkerContext.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/workers/WorkerContext.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -247,7 +247,7 @@
</span><span class="cx">         request.setHTTPMethod(&quot;GET&quot;);
</span><span class="cx">         request.setHTTPOrigin(securityOrigin);
</span><span class="cx">         WorkerImportScriptsClient client(scriptExecutionContext(), *it, callerURL, callerLine);
</span><del>-        ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), request, client);
</del><ins>+        ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), request, client, AllowStoredCredentials);
</ins><span class="cx">         
</span><span class="cx">         // If the fetching attempt failed, throw a NETWORK_ERR exception and abort all these steps.
</span><span class="cx">         if (client.failed()) {
</span></span></pre></div>
<a id="trunkWebCorexmlXMLHttpRequestcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/xml/XMLHttpRequest.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/xml/XMLHttpRequest.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/xml/XMLHttpRequest.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -635,7 +635,9 @@
</span><span class="cx"> 
</span><span class="cx">     m_loader = 0;
</span><span class="cx">     m_exceptionCode = 0;
</span><del>-    ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), request, *this);
</del><ins>+    StoredCredentials storedCredentials = (m_sameOriginRequest || m_includeCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
+
+    ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), request, *this, storedCredentials);
</ins><span class="cx">     if (!m_exceptionCode &amp;&amp; m_error)
</span><span class="cx">         m_exceptionCode = XMLHttpRequestException::NETWORK_ERR;
</span><span class="cx">     ec = m_exceptionCode;
</span><span class="lines">@@ -653,11 +655,12 @@
</span><span class="cx">     // for local files otherwise, &lt;rdar://problem/5671813&gt;.
</span><span class="cx">     LoadCallbacks callbacks = m_inPreflight ? DoNotSendLoadCallbacks : SendLoadCallbacks;
</span><span class="cx">     ContentSniff contentSniff = request.url().isLocalFile() ? SniffContent : DoNotSniffContent;
</span><ins>+    StoredCredentials storedCredentials = (m_sameOriginRequest || m_includeCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
</ins><span class="cx"> 
</span><span class="cx">     if (m_upload)
</span><span class="cx">         request.setReportUploadProgress(true);
</span><span class="cx"> 
</span><del>-    m_loader = ThreadableLoader::create(scriptExecutionContext(), this, request, callbacks, contentSniff);
</del><ins>+    m_loader = ThreadableLoader::create(scriptExecutionContext(), this, request, callbacks, contentSniff, storedCredentials);
</ins><span class="cx"> 
</span><span class="cx">     if (m_loader) {
</span><span class="cx">         // Neither this object nor the JavaScript wrapper should be deleted while
</span></span></pre></div>
<a id="trunkWebCorexmlXMLHttpRequesth"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/xml/XMLHttpRequest.h (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/xml/XMLHttpRequest.h        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/xml/XMLHttpRequest.h        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -63,6 +63,8 @@
</span><span class="cx">     String statusText(ExceptionCode&amp;) const;
</span><span class="cx">     int status(ExceptionCode&amp;) const;
</span><span class="cx">     State readyState() const;
</span><ins>+    bool withCredentials() const { return m_includeCredentials; }
+    void setWithCredentials(bool value) { m_includeCredentials = value; }
</ins><span class="cx">     void open(const String&amp; method, const KURL&amp;, bool async, ExceptionCode&amp;);
</span><span class="cx">     void open(const String&amp; method, const KURL&amp;, bool async, const String&amp; user, ExceptionCode&amp;);
</span><span class="cx">     void open(const String&amp; method, const KURL&amp;, bool async, const String&amp; user, const String&amp; password, ExceptionCode&amp;);
</span><span class="lines">@@ -195,7 +197,7 @@
</span><span class="cx">     RefPtr&lt;FormData&gt; m_requestEntityBody;
</span><span class="cx">     String m_mimeTypeOverride;
</span><span class="cx">     bool m_async;
</span><del>-    bool m_includeCredentials; // FIXME: Currently, setting this flag is not implemented, so it is always false.
</del><ins>+    bool m_includeCredentials;
</ins><span class="cx"> 
</span><span class="cx">     RefPtr&lt;ThreadableLoader&gt; m_loader;
</span><span class="cx">     State m_state;
</span></span></pre></div>
<a id="trunkWebCorexmlXMLHttpRequestidl"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/xml/XMLHttpRequest.idl (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/xml/XMLHttpRequest.idl        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/xml/XMLHttpRequest.idl        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -53,6 +53,7 @@
</span><span class="cx">         readonly attribute unsigned short readyState;
</span><span class="cx"> 
</span><span class="cx">         // request
</span><ins>+        attribute boolean withCredentials;
</ins><span class="cx">         // void open(in DOMString method, in DOMString url);
</span><span class="cx">         // void open(in DOMString method, in DOMString url, in boolean async);
</span><span class="cx">         // void open(in DOMString method, in DOMString url, in boolean async, in DOMString user);
</span></span></pre></div>
<a id="trunkWebCorexmlXSLTProcessorcpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/xml/XSLTProcessor.cpp (42482 => 42483)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/xml/XSLTProcessor.cpp        2009-04-14 07:19:34 UTC (rev 42482)
+++ trunk/WebCore/xml/XSLTProcessor.cpp        2009-04-14 08:11:42 UTC (rev 42483)
</span><span class="lines">@@ -128,7 +128,7 @@
</span><span class="cx"> 
</span><span class="cx">             bool requestAllowed = globalDocLoader-&gt;frame() &amp;&amp; globalDocLoader-&gt;doc()-&gt;securityOrigin()-&gt;canRequest(url);
</span><span class="cx">             if (requestAllowed) {
</span><del>-                globalDocLoader-&gt;frame()-&gt;loader()-&gt;loadResourceSynchronously(url, error, response, data);
</del><ins>+                globalDocLoader-&gt;frame()-&gt;loader()-&gt;loadResourceSynchronously(url, AllowStoredCredentials, error, response, data);
</ins><span class="cx">                 requestAllowed = globalDocLoader-&gt;doc()-&gt;securityOrigin()-&gt;canRequest(response.url());
</span><span class="cx">             }
</span><span class="cx">             if (!requestAllowed) {
</span></span></pre>
</div>
</div>

</body>
</html>