With multipart/replaced (e.g. motion JPEG), m_bufferedDataForCache grows unbounded...
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Jul 2015 16:44:37 +0000 (16:44 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Jul 2015 16:44:37 +0000 (16:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=146630
<rdar://problem/21677340>

Reviewed by Chris Dumez.

* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::didReceiveResponseAsync):

    Don't buffer multipart/x-mixed-replace. We never want to cache these.

(WebKit::NetworkResourceLoader::didReceiveBuffer):

    Limit the maximum size of the cache buffer to 10MB. This prevents unbounded memory growth if the resource
    keeps streaming. It also prevents giant entries from pushing other data out of the cache.

(WebKit::NetworkResourceLoader::didFinishLoading):

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

Source/WebKit2/ChangeLog
Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp

index d426570..82c95e7 100644 (file)
@@ -1,3 +1,23 @@
+2015-07-06  Antti Koivisto  <antti@apple.com>
+
+        With multipart/replaced (e.g. motion JPEG), m_bufferedDataForCache grows unbounded in Networking process
+        https://bugs.webkit.org/show_bug.cgi?id=146630
+        <rdar://problem/21677340>
+
+        Reviewed by Chris Dumez.
+
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::NetworkResourceLoader::didReceiveResponseAsync):
+
+            Don't buffer multipart/x-mixed-replace. We never want to cache these.
+
+        (WebKit::NetworkResourceLoader::didReceiveBuffer):
+
+            Limit the maximum size of the cache buffer to 10MB. This prevents unbounded memory growth if the resource
+            keeps streaming. It also prevents giant entries from pushing other data out of the cache.
+
+        (WebKit::NetworkResourceLoader::didFinishLoading):
+
 2015-07-06  Zan Dobersek  <zdobersek@igalia.com>
 
         [GTK] Guard X11-specific code in webkitWebViewBaseDidRelaunchWebProcess()
index 74ea37a..203ae21 100644 (file)
@@ -244,6 +244,9 @@ void NetworkResourceLoader::didReceiveResponseAsync(ResourceHandle* handle, cons
 
     bool shouldSendDidReceiveResponse = true;
 #if ENABLE(NETWORK_CACHE)
+    if (m_response.isMultipart())
+        m_bufferedDataForCache = nullptr;
+
     if (m_cacheEntryForValidation) {
         bool validationSucceeded = m_response.httpStatusCode() == 304; // 304 Not Modified
         if (validationSucceeded)
@@ -288,8 +291,14 @@ void NetworkResourceLoader::didReceiveBuffer(ResourceHandle* handle, PassRefPtr<
 #if ENABLE(NETWORK_CACHE)
     ASSERT(!m_cacheEntryForValidation);
 
-    if (m_bufferedDataForCache)
-        m_bufferedDataForCache->append(buffer.get());
+    if (m_bufferedDataForCache) {
+        // Prevent memory growth in case of streaming data.
+        const size_t maximumCacheBufferSize = 10 * 1014 * 1024;
+        if (m_bufferedDataForCache->size() + buffer->size() <= maximumCacheBufferSize)
+            m_bufferedDataForCache->append(buffer.get());
+        else
+            m_bufferedDataForCache = nullptr;
+    }
 #endif
     // FIXME: At least on OS X Yosemite we always get -1 from the resource handle.
     unsigned encodedDataLength = reportedEncodedDataLength >= 0 ? reportedEncodedDataLength : buffer->size();
@@ -327,7 +336,7 @@ void NetworkResourceLoader::didFinishLoading(ResourceHandle* handle, double fini
         }
 
         bool isPrivate = sessionID().isEphemeral();
-        if (hasCacheableRedirect && !isPrivate) {
+        if (m_bufferedDataForCache && hasCacheableRedirect && !isPrivate) {
             // Keep the connection alive.
             RefPtr<NetworkConnectionToWebProcess> connection(connectionToWebProcess());
             RefPtr<NetworkResourceLoader> loader(this);