<!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>[168596] trunk/Source/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/168596">168596</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-05-11 00:01:15 -0700 (Sun, 11 May 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>WinCairo crashes on acid3 test
https://bugs.webkit.org/show_bug.cgi?id=131364

Patch by peavo@outlook.com &lt;peavo@outlook.com&gt; on 2014-05-11
Reviewed by Brent Fulgham.

When the 304 (Not-modified) response is received, the Curl backend should look up the cached response,
and call the client method didReceiveResponse with the cached response, instead of the 304 response.
Otherwise the response will contain an empty MIME type, which causes the request to be cancelled, and the client deleted.
When the Curl cache manager then accesses the client afterwards, it is deleted, and we crash.

* platform/network/curl/CurlCacheManager.cpp:
(WebCore::CurlCacheManager::didReceiveResponse): Return early if request is cancelled.
(WebCore::CurlCacheManager::getCachedResponse): Added method to get cached response.
* platform/network/curl/CurlCacheManager.h: Ditto.
* platform/network/curl/ResourceHandleManager.cpp:
(WebCore::headerCallback): When 304 response is received, look up cached response, and use it.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcurlCurlCacheManagercpp">trunk/Source/WebCore/platform/network/curl/CurlCacheManager.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcurlCurlCacheManagerh">trunk/Source/WebCore/platform/network/curl/CurlCacheManager.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcurlResourceHandleManagercpp">trunk/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (168595 => 168596)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-05-11 05:30:54 UTC (rev 168595)
+++ trunk/Source/WebCore/ChangeLog        2014-05-11 07:01:15 UTC (rev 168596)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2014-05-11  peavo@outlook.com  &lt;peavo@outlook.com&gt;
+
+        WinCairo crashes on acid3 test
+        https://bugs.webkit.org/show_bug.cgi?id=131364
+
+        Reviewed by Brent Fulgham.
+
+        When the 304 (Not-modified) response is received, the Curl backend should look up the cached response,
+        and call the client method didReceiveResponse with the cached response, instead of the 304 response.
+        Otherwise the response will contain an empty MIME type, which causes the request to be cancelled, and the client deleted.
+        When the Curl cache manager then accesses the client afterwards, it is deleted, and we crash.
+
+        * platform/network/curl/CurlCacheManager.cpp:
+        (WebCore::CurlCacheManager::didReceiveResponse): Return early if request is cancelled.
+        (WebCore::CurlCacheManager::getCachedResponse): Added method to get cached response.
+        * platform/network/curl/CurlCacheManager.h: Ditto.
+        * platform/network/curl/ResourceHandleManager.cpp:
+        (WebCore::headerCallback): When 304 response is received, look up cached response, and use it.
+
</ins><span class="cx"> 2014-05-10  Tim Horton  &lt;timothy_horton@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [WKWebView _updateScrollViewBackground] churns UI-and-CGColors while repainting
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcurlCurlCacheManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/curl/CurlCacheManager.cpp (168595 => 168596)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/curl/CurlCacheManager.cpp        2014-05-11 05:30:54 UTC (rev 168595)
+++ trunk/Source/WebCore/platform/network/curl/CurlCacheManager.cpp        2014-05-11 07:01:15 UTC (rev 168596)
</span><span class="lines">@@ -196,6 +196,10 @@
</span><span class="cx">     if (m_disabled)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    ResourceHandleInternal* d = job-&gt;getInternal();
+    if (d-&gt;m_cancelled)
+        return;
+
</ins><span class="cx">     String url = job-&gt;firstRequest().url().string();
</span><span class="cx"> 
</span><span class="cx">     if (response.httpStatusCode() == 304) {
</span><span class="lines">@@ -247,6 +251,16 @@
</span><span class="cx">     return m_index.find(url)-&gt;value-&gt;requestHeaders();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool CurlCacheManager::getCachedResponse(const String&amp; url, ResourceResponse&amp; response)
+{
+    HashMap&lt;String, std::unique_ptr&lt;CurlCacheEntry&gt;&gt;::iterator it = m_index.find(url);
+    if (it != m_index.end()) {
+        it-&gt;value-&gt;setResponseFromCachedHeaders(response);
+        return true;
+    }
+    return false;
+}
+
</ins><span class="cx"> void CurlCacheManager::didReceiveData(const String&amp; url, const char* data, size_t size)
</span><span class="cx"> {
</span><span class="cx">     if (m_disabled)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcurlCurlCacheManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/curl/CurlCacheManager.h (168595 => 168596)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/curl/CurlCacheManager.h        2014-05-11 05:30:54 UTC (rev 168595)
+++ trunk/Source/WebCore/platform/network/curl/CurlCacheManager.h        2014-05-11 07:01:15 UTC (rev 168596)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool isCached(const String&amp;);
</span><span class="cx">     HTTPHeaderMap&amp; requestHeaders(const String&amp;); // Load headers
</span><ins>+    bool getCachedResponse(const String&amp; url, ResourceResponse&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void didReceiveResponse(ResourceHandle*, ResourceResponse&amp;);
</span><span class="cx">     void didReceiveData(const String&amp;, const char*, size_t); // Save data
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcurlResourceHandleManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp (168595 => 168596)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp        2014-05-11 05:30:54 UTC (rev 168595)
+++ trunk/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp        2014-05-11 07:01:15 UTC (rev 168596)
</span><span class="lines">@@ -532,7 +532,11 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (client) {
</span><del>-            client-&gt;didReceiveResponse(job, d-&gt;m_response); 
</del><ins>+            if (httpCode == 304) {
+                const String&amp; url = job-&gt;firstRequest().url().string();
+                CurlCacheManager::getInstance().getCachedResponse(url, d-&gt;m_response);
+            }
+            client-&gt;didReceiveResponse(job, d-&gt;m_response);
</ins><span class="cx">             CurlCacheManager::getInstance().didReceiveResponse(job, d-&gt;m_response);
</span><span class="cx">         }
</span><span class="cx">         d-&gt;m_response.setResponseFired(true);
</span></span></pre>
</div>
</div>

</body>
</html>