Diff
Modified: trunk/LayoutTests/ChangeLog (228900 => 228901)
--- trunk/LayoutTests/ChangeLog 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/LayoutTests/ChangeLog 2018-02-21 22:37:27 UTC (rev 228901)
@@ -1,5 +1,27 @@
2018-02-21 Youenn Fablet <[email protected]>
+ Move AppCache loading to the NetworkProcess
+ https://bugs.webkit.org/show_bug.cgi?id=178540
+ <rdar://problem/37119346>
+
+ Reviewed by Alex Christensen.
+
+ There is no guarantee that aborting in an event handler will be executed before some loads finish,
+ as the events are fired asynchronously.
+ Making tests less flaky by waiting some time before fnishing some loads.
+
+ * http/tests/appcache/abort-cache-onchecking.html:
+ * http/tests/appcache/resource-redirect-2-expected.txt:
+ * http/tests/appcache/resources/abort-cache-onchecking-resource-404.manifest:
+ * http/tests/appcache/resources/abort-cache-onchecking.manifest: Removed.
+ * http/tests/appcache/resources/abort-cache-onchecking.manifest.php: Added.
+ * http/tests/appcache/resources/abort-cache-ondownloading.manifest:
+ * http/tests/appcache/resources/abort-cache-ondownloading.text: Removed.
+ * http/tests/appcache/resources/abort-cache-ondownloading.text.php: Added.
+ * http/tests/appcache/resources/not-exist.vob.php: Added.
+
+2018-02-21 Youenn Fablet <[email protected]>
+
Use ResourceLoader to load appcache manifest
https://bugs.webkit.org/show_bug.cgi?id=182861
Modified: trunk/LayoutTests/http/tests/appcache/abort-cache-onchecking.html (228900 => 228901)
--- trunk/LayoutTests/http/tests/appcache/abort-cache-onchecking.html 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/LayoutTests/http/tests/appcache/abort-cache-onchecking.html 2018-02-21 22:37:27 UTC (rev 228901)
@@ -1,4 +1,4 @@
-<html manifest="resources/abort-cache-onchecking.manifest">
+<html manifest="resources/abort-cache-onchecking.manifest.php">
<script>
if (window.testRunner) {
testRunner.dumpAsText()
Modified: trunk/LayoutTests/http/tests/appcache/resource-redirect-2-expected.txt (228900 => 228901)
--- trunk/LayoutTests/http/tests/appcache/resource-redirect-2-expected.txt 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/LayoutTests/http/tests/appcache/resource-redirect-2-expected.txt 2018-02-21 22:37:27 UTC (rev 228901)
@@ -1,5 +1,5 @@
CONSOLE MESSAGE: line 1: ApplicationCache is deprecated. Please use ServiceWorkers instead.
-CONSOLE MESSAGE: Application Cache update failed, because http://127.0.0.1:8000/appcache/resources/resource-redirect-2.php could not be fetched.
+CONSOLE MESSAGE: Application Cache update failed, because http://127.0.0.1:8000/appcache/resources/resource-redirect-2.php was redirected.
Test that a redirect makes resource caching fail.
Should say SUCCESS:
Modified: trunk/LayoutTests/http/tests/appcache/resources/abort-cache-onchecking-resource-404.manifest (228900 => 228901)
--- trunk/LayoutTests/http/tests/appcache/resources/abort-cache-onchecking-resource-404.manifest 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/LayoutTests/http/tests/appcache/resources/abort-cache-onchecking-resource-404.manifest 2018-02-21 22:37:27 UTC (rev 228901)
@@ -1,2 +1,2 @@
CACHE MANIFEST
-not-exist.vob
\ No newline at end of file
+not-exist.vob.php
Deleted: trunk/LayoutTests/http/tests/appcache/resources/abort-cache-onchecking.manifest (228900 => 228901)
--- trunk/LayoutTests/http/tests/appcache/resources/abort-cache-onchecking.manifest 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/LayoutTests/http/tests/appcache/resources/abort-cache-onchecking.manifest 2018-02-21 22:37:27 UTC (rev 228901)
@@ -1,2 +0,0 @@
-CACHE MANIFEST
-abort-cache-onchecking.text
\ No newline at end of file
Added: trunk/LayoutTests/http/tests/appcache/resources/abort-cache-onchecking.manifest.php (0 => 228901)
--- trunk/LayoutTests/http/tests/appcache/resources/abort-cache-onchecking.manifest.php (rev 0)
+++ trunk/LayoutTests/http/tests/appcache/resources/abort-cache-onchecking.manifest.php 2018-02-21 22:37:27 UTC (rev 228901)
@@ -0,0 +1,5 @@
+<?php
+sleep(1000);
+print("CACHE MANIFEST\n");
+print("abort-cache-onchecking.text");
+?>
Modified: trunk/LayoutTests/http/tests/appcache/resources/abort-cache-ondownloading.manifest (228900 => 228901)
--- trunk/LayoutTests/http/tests/appcache/resources/abort-cache-ondownloading.manifest 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/LayoutTests/http/tests/appcache/resources/abort-cache-ondownloading.manifest 2018-02-21 22:37:27 UTC (rev 228901)
@@ -1,2 +1,2 @@
CACHE MANIFEST
-abort-cache-ondownloading.text
\ No newline at end of file
+abort-cache-ondownloading.text.php
Deleted: trunk/LayoutTests/http/tests/appcache/resources/abort-cache-ondownloading.text (228900 => 228901)
--- trunk/LayoutTests/http/tests/appcache/resources/abort-cache-ondownloading.text 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/LayoutTests/http/tests/appcache/resources/abort-cache-ondownloading.text 2018-02-21 22:37:27 UTC (rev 228901)
@@ -1,2 +0,0 @@
-test for applicationCache.abort
-
Added: trunk/LayoutTests/http/tests/appcache/resources/abort-cache-ondownloading.text.php (0 => 228901)
--- trunk/LayoutTests/http/tests/appcache/resources/abort-cache-ondownloading.text.php (rev 0)
+++ trunk/LayoutTests/http/tests/appcache/resources/abort-cache-ondownloading.text.php 2018-02-21 22:37:27 UTC (rev 228901)
@@ -0,0 +1,5 @@
+<?php
+sleep(1000);
+print("test for applicationCache.abort");
+?>
+
Added: trunk/LayoutTests/http/tests/appcache/resources/not-exist.vob.php (0 => 228901)
--- trunk/LayoutTests/http/tests/appcache/resources/not-exist.vob.php (rev 0)
+++ trunk/LayoutTests/http/tests/appcache/resources/not-exist.vob.php 2018-02-21 22:37:27 UTC (rev 228901)
@@ -0,0 +1,5 @@
+<?php
+sleep(1000);
+header('http/1.1 404 Not Found');
+print("File not found\n");
+?>
Modified: trunk/Source/WebCore/ChangeLog (228900 => 228901)
--- trunk/Source/WebCore/ChangeLog 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/ChangeLog 2018-02-21 22:37:27 UTC (rev 228901)
@@ -1,3 +1,54 @@
+2018-02-21 Youenn Fablet <[email protected]>
+
+ Move AppCache loading to the NetworkProcess
+ https://bugs.webkit.org/show_bug.cgi?id=178540
+ <rdar://problem/37119346>
+
+ Reviewed by Alex Christensen.
+
+ Covered by existing tests.
+
+ Use ApplicationResourceLoader for cache entry loading.
+ Remove all ResourceHandle use from ApplicationCacheGroup.
+ Renamed m_loader in m_manifestLoader and added a new m_entryLoader to load cache entries.
+
+ Updated ApplicationCacheResourceLoader to handle different types of CachedResource.
+ This allows in particular to handle redirections based on the resource type and create the ApplicationCacheResource with the right type.
+ Use Include as credentials mode as per specification.
+
+ Add a new ApplicationCache ResourceResonse::Source.
+ This allows fixing an assertion and should allow better inspector support if needs be.
+
+ * inspector/agents/InspectorNetworkAgent.cpp:
+ (WebCore::responseSource):
+ * loader/ResourceLoader.cpp:
+ (WebCore::logResourceResponseSource):
+ * loader/SubstituteResource.h:
+ (WebCore::SubstituteResource::resourceResponse):
+ * loader/appcache/ApplicationCacheGroup.cpp:
+ (WebCore::ApplicationCacheGroup::stopLoading):
+ (WebCore::ApplicationCacheGroup::update):
+ (WebCore::ApplicationCacheGroup::didFinishLoading):
+ (WebCore::ApplicationCacheGroup::didFinishLoadingEntry):
+ (WebCore::ApplicationCacheGroup::didFail):
+ (WebCore::ApplicationCacheGroup::didFailLoadingEntry):
+ (WebCore::ApplicationCacheGroup::checkIfLoadIsComplete):
+ (WebCore::ApplicationCacheGroup::startLoadingEntry):
+ * loader/appcache/ApplicationCacheGroup.h:
+ * loader/appcache/ApplicationCacheResource.cpp:
+ (WebCore::ApplicationCacheResource::ApplicationCacheResource):
+ * loader/appcache/ApplicationCacheResourceLoader.cpp:
+ (WebCore::ApplicationCacheResourceLoader::create):
+ (WebCore::ApplicationCacheResourceLoader::ApplicationCacheResourceLoader):
+ (WebCore::ApplicationCacheResourceLoader::responseReceived):
+ (WebCore::ApplicationCacheResourceLoader::redirectReceived):
+ * loader/appcache/ApplicationCacheResourceLoader.h:
+ * platform/network/ResourceResponseBase.h:
+ * platform/network/cocoa/ResourceResponseCocoa.mm:
+ (WebCore::ResourceResponse::platformCertificateInfo const):
+ * testing/Internals.cpp:
+ (WebCore::responseSourceToString):
+
2018-02-21 Zalan Bujtas <[email protected]>
[RenderTreeBuilder] Move RenderBoxModelObject::willBeRemoved() mutation logic to RenderTreeBuilder
Modified: trunk/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp (228900 => 228901)
--- trunk/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp 2018-02-21 22:37:27 UTC (rev 228901)
@@ -269,6 +269,8 @@
static Inspector::Protocol::Network::Response::Source responseSource(ResourceResponse::Source source)
{
switch (source) {
+ case ResourceResponse::Source::ApplicationCache:
+ // FIXME: Add support for ApplicationCache in inspector.
case ResourceResponse::Source::Unknown:
return Inspector::Protocol::Network::Response::Source::Unknown;
case ResourceResponse::Source::Network:
Modified: trunk/Source/WebCore/loader/ResourceLoader.cpp (228900 => 228901)
--- trunk/Source/WebCore/loader/ResourceLoader.cpp 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/loader/ResourceLoader.cpp 2018-02-21 22:37:27 UTC (rev 228901)
@@ -437,6 +437,7 @@
break;
case ResourceResponse::Source::MemoryCache:
case ResourceResponse::Source::MemoryCacheAfterValidation:
+ case ResourceResponse::Source::ApplicationCache:
case ResourceResponse::Source::Unknown:
return;
}
Modified: trunk/Source/WebCore/loader/SubstituteResource.h (228900 => 228901)
--- trunk/Source/WebCore/loader/SubstituteResource.h 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/loader/SubstituteResource.h 2018-02-21 22:37:27 UTC (rev 228901)
@@ -49,6 +49,8 @@
{
}
+ ResourceResponse& resourceResponse() { return m_response; }
+
private:
URL m_url;
ResourceResponse m_response;
Modified: trunk/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp (228900 => 228901)
--- trunk/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/loader/appcache/ApplicationCacheGroup.cpp 2018-02-21 22:37:27 UTC (rev 228901)
@@ -46,7 +46,6 @@
#include "NetworkLoadMetrics.h"
#include "Page.h"
#include "ProgressTracker.h"
-#include "ResourceHandle.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#include <wtf/CompletionHandler.h>
@@ -315,22 +314,16 @@
void ApplicationCacheGroup::stopLoading()
{
- if (m_loader) {
- m_loader->cancel();
- m_loader = nullptr;
+ if (m_manifestLoader) {
+ m_manifestLoader->cancel();
+ m_manifestLoader = nullptr;
}
- if (m_currentHandle) {
- ASSERT(!m_loader);
- ASSERT(m_cacheBeingUpdated);
+ if (m_entryLoader) {
+ m_entryLoader->cancel();
+ m_entryLoader = nullptr;
+ }
- ASSERT(m_currentHandle->client() == this);
- m_currentHandle->clearClient();
-
- m_currentHandle->cancel();
- m_currentHandle = nullptr;
- }
-
// FIXME: Resetting just a tiny part of the state in this function is confusing. Callers have to take care of a lot more.
m_cacheBeingUpdated = nullptr;
m_pendingEntries.clear();
@@ -432,9 +425,9 @@
postListenerTask(eventNames().checkingEvent, documentLoader);
}
- ASSERT(!m_loader);
+ ASSERT(!m_manifestLoader);
+ ASSERT(!m_entryLoader);
ASSERT(!m_manifestResource);
- ASSERT(!m_currentHandle);
ASSERT(!m_currentResource);
ASSERT(m_completionType == None);
@@ -445,7 +438,7 @@
m_currentResourceIdentifier = m_frame->page()->progress().createUniqueIdentifier();
InspectorInstrumentation::willSendRequest(m_frame, m_currentResourceIdentifier, m_frame->loader().documentLoader(), request, ResourceResponse { });
- m_loader = ApplicationCacheResourceLoader::create(documentLoader.cachedResourceLoader(), WTFMove(request), [this] (auto&& resourceOrError) {
+ m_manifestLoader = ApplicationCacheResourceLoader::create(ApplicationCacheResource::Type::Manifest, documentLoader.cachedResourceLoader(), WTFMove(request), [this] (auto&& resourceOrError) {
// 'this' is only valid if returned value is not Error::Abort.
if (!resourceOrError.has_value()) {
auto error = resourceOrError.error();
@@ -453,7 +446,7 @@
return;
if (error == ApplicationCacheResourceLoader::Error::CannotCreateResource) {
// FIXME: We should get back the error from ApplicationCacheResourceLoader level.
- InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, ResourceError { ResourceError::Type::General });
+ InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, ResourceError { ResourceError::Type::AccessControl });
this->cacheUpdateFailed();
return;
}
@@ -497,142 +490,37 @@
cacheUpdateFailed();
}
-RefPtr<ResourceHandle> ApplicationCacheGroup::createResourceHandle(const URL& url, ApplicationCacheResource* newestCachedResource)
+void ApplicationCacheGroup::didFinishLoadingEntry(const URL& entryURL)
{
- ResourceRequest request(url);
- m_frame->loader().applyUserAgentIfNeeded(request);
- request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "max-age=0");
+ // FIXME: We should have NetworkLoadMetrics for ApplicationCache loads.
+ NetworkLoadMetrics emptyMetrics;
+ InspectorInstrumentation::didFinishLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, emptyMetrics, nullptr);
- if (newestCachedResource) {
- const String& lastModified = newestCachedResource->response().httpHeaderField(HTTPHeaderName::LastModified);
- const String& eTag = newestCachedResource->response().httpHeaderField(HTTPHeaderName::ETag);
- if (!lastModified.isEmpty() || !eTag.isEmpty()) {
- if (!lastModified.isEmpty())
- request.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified);
- if (!eTag.isEmpty())
- request.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag);
- }
- }
-
- bool defersLoading = false;
- bool shouldContentSniff = true;
- bool shouldContentEncodingSniff = true;
- RefPtr<ResourceHandle> handle = ResourceHandle::create(m_frame->loader().networkingContext(), request, this, defersLoading, shouldContentSniff, shouldContentEncodingSniff);
-
- // Because willSendRequest only gets called during redirects, we initialize
- // the identifier and the first willSendRequest here.
- m_currentResourceIdentifier = m_frame->page()->progress().createUniqueIdentifier();
- ResourceResponse redirectResponse = ResourceResponse();
- InspectorInstrumentation::willSendRequest(m_frame, m_currentResourceIdentifier, m_frame->loader().documentLoader(), request, redirectResponse);
- return handle;
-}
-
-void ApplicationCacheGroup::didReceiveResponseAsync(ResourceHandle* handle, ResourceResponse&& response, CompletionHandler<void()>&& completionHandler)
-{
- ASSERT(m_frame);
- InspectorInstrumentation::didReceiveResourceResponse(*m_frame, m_currentResourceIdentifier, m_frame->loader().documentLoader(), response, nullptr);
-
- ASSERT(handle == m_currentHandle);
-
- URL url(handle->firstRequest().url());
- url.removeFragmentIdentifier();
+ ASSERT(m_pendingEntries.contains(entryURL));
- ASSERT(!m_currentResource);
- ASSERT(m_pendingEntries.contains(url));
+ auto type = m_pendingEntries.take(entryURL);
- unsigned type = m_pendingEntries.get(url);
-
- // If this is an initial cache attempt, we should not get master resources delivered here.
- if (!m_newestCache)
- ASSERT(!(type & ApplicationCacheResource::Master));
+ ASSERT(m_cacheBeingUpdated);
- if (m_newestCache && response.httpStatusCode() == 304) { // Not modified.
- ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(url);
- if (newestCachedResource) {
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, &newestCachedResource->data(), newestCachedResource->path()));
- m_pendingEntries.remove(m_currentHandle->firstRequest().url());
- m_currentHandle->cancel();
- m_currentHandle = nullptr;
- // Load the next resource, if any.
- startLoadingEntry();
- completionHandler();
- return;
+ // Did we received a 304?
+ if (!m_currentResource) {
+ if (m_newestCache) {
+ ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(entryURL);
+ if (newestCachedResource) {
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(entryURL, newestCachedResource->response(), type, &newestCachedResource->data(), newestCachedResource->path()));
+ m_entryLoader = nullptr;
+ startLoadingEntry();
+ return;
+ }
}
// The server could return 304 for an unconditional request - in this case, we handle the response as a normal error.
- }
-
- if (response.httpStatusCode() / 100 != 2 || response.url() != m_currentHandle->firstRequest().url()) {
- if ((type & ApplicationCacheResource::Explicit) || (type & ApplicationCacheResource::Fallback)) {
- m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, "Application Cache update failed, because " + m_currentHandle->firstRequest().url().stringCenterEllipsizedToLength() +
- ((response.httpStatusCode() / 100 != 2) ? " could not be fetched." : " was redirected."));
- // Note that cacheUpdateFailed() can cause the cache group to be deleted.
- cacheUpdateFailed();
- } else if (response.httpStatusCode() == 404 || response.httpStatusCode() == 410) {
- // Skip this resource. It is dropped from the cache.
- m_currentHandle->cancel();
- m_currentHandle = nullptr;
- m_pendingEntries.remove(url);
- // Load the next resource, if any.
- startLoadingEntry();
- } else {
- // Copy the resource and its metadata from the newest application cache in cache group whose completeness flag is complete, and act
- // as if that was the fetched resource, ignoring the resource obtained from the network.
- ASSERT(m_newestCache);
- ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(handle->firstRequest().url());
- ASSERT(newestCachedResource);
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, &newestCachedResource->data(), newestCachedResource->path()));
- m_pendingEntries.remove(m_currentHandle->firstRequest().url());
- m_currentHandle->cancel();
- m_currentHandle = nullptr;
- // Load the next resource, if any.
- startLoadingEntry();
- }
- completionHandler();
+ m_entryLoader = nullptr;
+ startLoadingEntry();
return;
}
-
- m_currentResource = ApplicationCacheResource::create(url, response, type);
- completionHandler();
-}
-void ApplicationCacheGroup::willSendRequestAsync(ResourceHandle*, ResourceRequest&& request, ResourceResponse&&, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
-{
- completionHandler(WTFMove(request));
-}
-
-#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
-void ApplicationCacheGroup::canAuthenticateAgainstProtectionSpaceAsync(ResourceHandle* handle, const ProtectionSpace&)
-{
- handle->continueCanAuthenticateAgainstProtectionSpace(false);
-}
-#endif
-
-void ApplicationCacheGroup::didReceiveData(ResourceHandle* handle, const char* data, unsigned length, int encodedDataLength)
-{
- UNUSED_PARAM(encodedDataLength);
- ASSERT_UNUSED(handle, handle == m_currentHandle);
-
- InspectorInstrumentation::didReceiveData(m_frame, m_currentResourceIdentifier, 0, length, 0);
-
- ASSERT(m_currentResource);
- m_currentResource->data().append(data, length);
-}
-
-void ApplicationCacheGroup::didFinishLoading(ResourceHandle* handle)
-{
- // FIXME: We should have NetworkLoadMetrics for ApplicationCache loads.
- NetworkLoadMetrics emptyMetrics;
- InspectorInstrumentation::didFinishLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, emptyMetrics, nullptr);
-
- ASSERT(m_currentHandle == handle);
- ASSERT(m_pendingEntries.contains(handle->firstRequest().url()));
-
- m_pendingEntries.remove(handle->firstRequest().url());
-
- ASSERT(m_cacheBeingUpdated);
-
m_cacheBeingUpdated->addResource(m_currentResource.releaseNonNull());
- m_currentHandle = nullptr;
+ m_entryLoader = nullptr;
// While downloading check to see if we have exceeded the available quota.
// We can stop immediately if we have already previously failed
@@ -650,14 +538,15 @@
startLoadingEntry();
}
-void ApplicationCacheGroup::didFail(ResourceHandle* handle, const ResourceError& error)
+void ApplicationCacheGroup::didFailLoadingEntry(ApplicationCacheResourceLoader::Error error, const URL& entryURL)
{
- InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, error);
+ // FIXME: We should get back the error from ApplicationCacheResourceLoader level.
+ ResourceError resourceError { error == ApplicationCacheResourceLoader::Error::CannotCreateResource ? ResourceError::Type::AccessControl : ResourceError::Type::General };
- ASSERT(handle == m_currentHandle);
+ InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, resourceError);
- unsigned type = m_currentResource ? m_currentResource->type() : m_pendingEntries.get(handle->firstRequest().url());
- URL url(handle->firstRequest().url());
+ unsigned type = m_entryLoader->type();
+ URL url(entryURL);
url.removeFragmentIdentifier();
ASSERT(!m_currentResource || !m_pendingEntries.contains(url));
@@ -665,19 +554,27 @@
m_pendingEntries.remove(url);
if ((type & ApplicationCacheResource::Explicit) || (type & ApplicationCacheResource::Fallback)) {
- m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, "Application Cache update failed, because " + url.stringCenterEllipsizedToLength() + " could not be fetched.");
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, "Application Cache update failed, because " + url.stringCenterEllipsizedToLength() + (m_entryLoader->hasRedirection() ? " was redirected." : " could not be fetched."));
// Note that cacheUpdateFailed() can cause the cache group to be deleted.
cacheUpdateFailed();
- } else {
- // Copy the resource and its metadata from the newest application cache in cache group whose completeness flag is complete, and act
- // as if that was the fetched resource, ignoring the resource obtained from the network.
- ASSERT(m_newestCache);
- ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(url);
- ASSERT(newestCachedResource);
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, &newestCachedResource->data(), newestCachedResource->path()));
- // Load the next resource, if any.
+ return;
+ }
+
+ if (error == ApplicationCacheResourceLoader::Error::NotFound) {
+ // Skip this resource. It is dropped from the cache.
+ m_pendingEntries.remove(url);
startLoadingEntry();
+ return;
}
+
+ // Copy the resource and its metadata from the newest application cache in cache group whose completeness flag is complete, and act
+ // as if that was the fetched resource, ignoring the resource obtained from the network.
+ ASSERT(m_newestCache);
+ ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(url);
+ ASSERT(newestCachedResource);
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, &newestCachedResource->data(), newestCachedResource->path()));
+ // Load the next resource, if any.
+ startLoadingEntry();
}
void ApplicationCacheGroup::didFinishLoadingManifest()
@@ -691,7 +588,7 @@
return;
}
- m_loader = nullptr;
+ m_manifestLoader = nullptr;
// Check if the manifest was not modified.
if (isUpgradeAttempt) {
@@ -761,23 +658,23 @@
{
ASSERT(error != ApplicationCacheResourceLoader::Error::Abort && error != ApplicationCacheResourceLoader::Error::CannotCreateResource);
- InspectorInstrumentation::didReceiveResourceResponse(*m_frame, m_currentResourceIdentifier, m_frame->loader().documentLoader(), m_loader->resource()->response(), nullptr);
+ InspectorInstrumentation::didReceiveResourceResponse(*m_frame, m_currentResourceIdentifier, m_frame->loader().documentLoader(), m_manifestLoader->resource()->response(), nullptr);
switch (error) {
case ApplicationCacheResourceLoader::Error::NetworkError:
cacheUpdateFailed();
break;
case ApplicationCacheResourceLoader::Error::NotFound:
- InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_loader->resource()->resourceRequest()));
- m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because the manifest had a ", String::number(m_loader->resource()->response().httpStatusCode()), " response."));
+ InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_manifestLoader->resource()->resourceRequest()));
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because the manifest had a ", String::number(m_manifestLoader->resource()->response().httpStatusCode()), " response."));
manifestNotFound();
break;
case ApplicationCacheResourceLoader::Error::NotOK:
- InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_loader->resource()->resourceRequest()));
- m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because the manifest had a ", String::number(m_loader->resource()->response().httpStatusCode()), " response."));
+ InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_manifestLoader->resource()->resourceRequest()));
+ m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because the manifest had a ", String::number(m_manifestLoader->resource()->response().httpStatusCode()), " response."));
cacheUpdateFailed();
break;
case ApplicationCacheResourceLoader::Error::RedirectForbidden:
- InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_loader->resource()->resourceRequest()));
+ InspectorInstrumentation::didFailLoading(m_frame, m_frame->loader().documentLoader(), m_currentResourceIdentifier, m_frame->loader().cancelledError(m_manifestLoader->resource()->resourceRequest()));
m_frame->document()->addConsoleMessage(MessageSource::AppCache, MessageLevel::Error, makeString("Application Cache manifest could not be fetched, because a redirection was attempted."));
cacheUpdateFailed();
break;
@@ -855,7 +752,7 @@
void ApplicationCacheGroup::checkIfLoadIsComplete()
{
- if (m_loader || !m_pendingEntries.isEmpty() || m_downloadingPendingMasterResourceLoadersCount)
+ if (m_manifestLoader || m_entryLoader || !m_pendingEntries.isEmpty() || m_downloadingPendingMasterResourceLoadersCount)
return;
// We're done, all resources have finished downloading (successfully or not).
@@ -997,8 +894,27 @@
postListenerTask(eventNames().progressEvent, m_progressTotal, m_progressDone, m_associatedDocumentLoaders);
m_progressDone++;
- ASSERT(!m_currentHandle);
- m_currentHandle = createResourceHandle(URL(ParsedURLString, firstPendingEntryURL), m_newestCache ? m_newestCache->resourceForURL(firstPendingEntryURL) : 0);
+ ASSERT(!m_manifestLoader);
+ ASSERT(!m_entryLoader);
+
+ auto request = createRequest(URL { ParsedURLString, firstPendingEntryURL }, m_newestCache ? m_newestCache->resourceForURL(firstPendingEntryURL) : nullptr);
+
+ m_currentResourceIdentifier = m_frame->page()->progress().createUniqueIdentifier();
+ InspectorInstrumentation::willSendRequest(m_frame, m_currentResourceIdentifier, m_frame->loader().documentLoader(), request, ResourceResponse { });
+
+ auto& documentLoader = *m_frame->loader().documentLoader();
+ m_entryLoader = ApplicationCacheResourceLoader::create(m_pendingEntries.begin()->value, documentLoader.cachedResourceLoader(), WTFMove(request), [this] (auto&& resourceOrError) {
+ if (!resourceOrError.has_value()) {
+ auto error = resourceOrError.error();
+ if (error == ApplicationCacheResourceLoader::Error::Abort)
+ return;
+ this->didFailLoadingEntry(error, m_entryLoader->resource()->url());
+ return;
+ }
+
+ m_currentResource = WTFMove(resourceOrError.value());
+ this->didFinishLoadingEntry(m_entryLoader->resource()->url());
+ });
}
void ApplicationCacheGroup::deliverDelayedMainResources()
Modified: trunk/Source/WebCore/loader/appcache/ApplicationCacheGroup.h (228900 => 228901)
--- trunk/Source/WebCore/loader/appcache/ApplicationCacheGroup.h 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/loader/appcache/ApplicationCacheGroup.h 2018-02-21 22:37:27 UTC (rev 228901)
@@ -28,7 +28,6 @@
#include "ApplicationCacheResourceLoader.h"
#include "DOMApplicationCache.h"
#include "URL.h"
-#include "ResourceHandleClient.h"
#include <wtf/Noncopyable.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
@@ -42,7 +41,6 @@
class Document;
class DocumentLoader;
class Frame;
-class ResourceHandle;
class SecurityOrigin;
enum ApplicationCacheUpdateOption {
@@ -50,7 +48,7 @@
ApplicationCacheUpdateWithoutBrowsingContext
};
-class ApplicationCacheGroup final : private ResourceHandleClient {
+class ApplicationCacheGroup {
WTF_MAKE_NONCOPYABLE(ApplicationCacheGroup);
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -103,25 +101,12 @@
void scheduleReachedMaxAppCacheSizeCallback();
- RefPtr<ResourceHandle> createResourceHandle(const URL&, ApplicationCacheResource* newestCachedResource);
-
- // For normal resource loading, WebKit client is asked about each resource individually. Since application cache does not belong to any particular document,
- // the existing client callback cannot be used, so assume that any client that enables application cache also wants it to use credential storage.
- bool shouldUseCredentialStorage(ResourceHandle*) override { return true; }
-
- // ResourceHandleClient
- void didReceiveResponseAsync(ResourceHandle*, ResourceResponse&&, CompletionHandler<void()>&&) final;
- void willSendRequestAsync(ResourceHandle*, ResourceRequest&&, ResourceResponse&&, CompletionHandler<void(ResourceRequest&&)>&&) final;
-#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
- void canAuthenticateAgainstProtectionSpaceAsync(ResourceHandle*, const ProtectionSpace&) final;
-#endif
- void didReceiveData(ResourceHandle*, const char*, unsigned length, int encodedDataLength) final;
- void didFinishLoading(ResourceHandle*) final;
- void didFail(ResourceHandle*, const ResourceError&) final;
-
void didFinishLoadingManifest();
void didFailLoadingManifest(ApplicationCacheResourceLoader::Error);
+ void didFailLoadingEntry(ApplicationCacheResourceLoader::Error, const URL&);
+ void didFinishLoadingEntry(const URL&);
+
void didReachMaxAppCacheSize();
void didReachOriginQuota(int64_t totalSpaceNeeded);
@@ -193,14 +178,13 @@
// the course of action in case of this failure (i.e. call the ChromeClient callback or run the failure steps).
bool m_calledReachedMaxAppCacheSize { false };
- RefPtr<ResourceHandle> m_currentHandle;
RefPtr<ApplicationCacheResource> m_currentResource;
+ RefPtr<ApplicationCacheResourceLoader> m_entryLoader;
unsigned long m_currentResourceIdentifier;
RefPtr<ApplicationCacheResource> m_manifestResource;
+ RefPtr<ApplicationCacheResourceLoader> m_manifestLoader;
- RefPtr<ApplicationCacheResourceLoader> m_loader;
-
int64_t m_availableSpaceInQuota;
bool m_originQuotaExceededPreviously { false };
Modified: trunk/Source/WebCore/loader/appcache/ApplicationCacheResource.cpp (228900 => 228901)
--- trunk/Source/WebCore/loader/appcache/ApplicationCacheResource.cpp 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/loader/appcache/ApplicationCacheResource.cpp 2018-02-21 22:37:27 UTC (rev 228901)
@@ -36,6 +36,7 @@
, m_estimatedSizeInStorage(0)
, m_path(path)
{
+ resourceResponse().setSource(ResourceResponse::Source::ApplicationCache);
}
void ApplicationCacheResource::deliver(ResourceLoader& loader)
Modified: trunk/Source/WebCore/loader/appcache/ApplicationCacheResourceLoader.cpp (228900 => 228901)
--- trunk/Source/WebCore/loader/appcache/ApplicationCacheResourceLoader.cpp 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/loader/appcache/ApplicationCacheResourceLoader.cpp 2018-02-21 22:37:27 UTC (rev 228901)
@@ -30,11 +30,11 @@
namespace WebCore {
-RefPtr<ApplicationCacheResourceLoader> ApplicationCacheResourceLoader::create(CachedResourceLoader& loader, ResourceRequest&& request, CompletionHandler<void(ResourceOrError&&)>&& callback)
+RefPtr<ApplicationCacheResourceLoader> ApplicationCacheResourceLoader::create(unsigned type, CachedResourceLoader& loader, ResourceRequest&& request, CompletionHandler<void(ResourceOrError&&)>&& callback)
{
ResourceLoaderOptions options;
options.storedCredentialsPolicy = StoredCredentialsPolicy::Use;
- options.credentials = FetchOptions::Credentials::SameOrigin;
+ options.credentials = FetchOptions::Credentials::Include;
options.applicationCacheMode = ApplicationCacheMode::Bypass;
CachedResourceRequest cachedResourceRequest { WTFMove(request), options };
auto resource = loader.requestRawResource(WTFMove(cachedResourceRequest));
@@ -42,11 +42,12 @@
callback(makeUnexpected(Error::CannotCreateResource));
return nullptr;
}
- return adoptRef(*new ApplicationCacheResourceLoader { WTFMove(resource.value()), WTFMove(callback) });
+ return adoptRef(*new ApplicationCacheResourceLoader { type, WTFMove(resource.value()), WTFMove(callback) });
}
-ApplicationCacheResourceLoader::ApplicationCacheResourceLoader(CachedResourceHandle<CachedRawResource>&& resource, CompletionHandler<void(ResourceOrError&&)>&& callback)
- : m_resource(WTFMove(resource))
+ApplicationCacheResourceLoader::ApplicationCacheResourceLoader(unsigned type, CachedResourceHandle<CachedRawResource>&& resource, CompletionHandler<void(ResourceOrError&&)>&& callback)
+ : m_type(type)
+ , m_resource(WTFMove(resource))
, m_callback(WTFMove(callback))
{
m_resource->addClient(*this);
@@ -78,7 +79,22 @@
{
ASSERT_UNUSED(resource, &resource == m_resource);
- receivedManifestResponse(response);
+ if (response.httpStatusCode() == 404 || response.httpStatusCode() == 410) {
+ cancel(Error::NotFound);
+ return;
+ }
+
+ if (response.httpStatusCode() == 304) {
+ notifyFinished(*m_resource);
+ return;
+ }
+
+ if (response.httpStatusCode() / 100 != 2) {
+ cancel(Error::NotOK);
+ return;
+ }
+
+ m_applicationCacheResource = ApplicationCacheResource::create(m_resource->url(), response, m_type);
}
void ApplicationCacheResourceLoader::dataReceived(CachedResource&, const char* data, int length)
@@ -86,10 +102,17 @@
m_applicationCacheResource->data().append(data, length);
}
-void ApplicationCacheResourceLoader::redirectReceived(CachedResource&, ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&& callback)
+void ApplicationCacheResourceLoader::redirectReceived(CachedResource&, ResourceRequest&& newRequest, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&& callback)
{
- cancel(Error::RedirectForbidden);
- callback({ });
+ m_hasRedirection = true;
+ bool isRedirectionDisallowed = (m_type & ApplicationCacheResource::Type::Manifest) || (m_type & ApplicationCacheResource::Explicit) || (m_type & ApplicationCacheResource::Fallback);
+
+ if (isRedirectionDisallowed) {
+ cancel(Error::RedirectForbidden);
+ callback({ });
+ return;
+ }
+ callback(WTFMove(newRequest));
}
void ApplicationCacheResourceLoader::notifyFinished(CachedResource& resource)
@@ -111,24 +134,4 @@
resourceHandle->removeClient(*this);
}
-void ApplicationCacheResourceLoader::receivedManifestResponse(const ResourceResponse& response)
-{
- if (response.httpStatusCode() == 404 || response.httpStatusCode() == 410) {
- cancel(Error::NotFound);
- return;
- }
-
- if (response.httpStatusCode() == 304) {
- notifyFinished(*m_resource);
- return;
- }
-
- if (response.httpStatusCode() / 100 != 2) {
- cancel(Error::NotOK);
- return;
- }
-
- m_applicationCacheResource = ApplicationCacheResource::create(m_resource->url(), response, ApplicationCacheResource::Manifest);
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/loader/appcache/ApplicationCacheResourceLoader.h (228900 => 228901)
--- trunk/Source/WebCore/loader/appcache/ApplicationCacheResourceLoader.h 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/loader/appcache/ApplicationCacheResourceLoader.h 2018-02-21 22:37:27 UTC (rev 228901)
@@ -41,18 +41,18 @@
enum class Error { Abort, NetworkError, CannotCreateResource, NotFound, NotOK, RedirectForbidden };
using ResourceOrError = Expected<RefPtr<ApplicationCacheResource>, Error>;
- static RefPtr<ApplicationCacheResourceLoader> create(CachedResourceLoader&, ResourceRequest&&, CompletionHandler<void(ResourceOrError&&)>&&);
+ static RefPtr<ApplicationCacheResourceLoader> create(unsigned, CachedResourceLoader&, ResourceRequest&&, CompletionHandler<void(ResourceOrError&&)>&&);
~ApplicationCacheResourceLoader();
void cancel(Error = Error::Abort);
const CachedResource* resource() const { return m_resource.get(); }
+ bool hasRedirection() const { return m_hasRedirection; }
+ unsigned type() const { return m_type; }
private:
- explicit ApplicationCacheResourceLoader(CachedResourceHandle<CachedRawResource>&&, CompletionHandler<void(ResourceOrError&&)>&&);
+ explicit ApplicationCacheResourceLoader(unsigned, CachedResourceHandle<CachedRawResource>&&, CompletionHandler<void(ResourceOrError&&)>&&);
- void receivedManifestResponse(const ResourceResponse&);
-
// CachedRawResourceClient
void responseReceived(CachedResource&, const ResourceResponse&) final;
void dataReceived(CachedResource&, const char* data, int dataLength) final;
@@ -59,9 +59,11 @@
void redirectReceived(CachedResource&, ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&) final;
void notifyFinished(CachedResource&) final;
+ unsigned m_type;
CachedResourceHandle<CachedRawResource> m_resource;
RefPtr<ApplicationCacheResource> m_applicationCacheResource;
CompletionHandler<void(ResourceOrError&&)> m_callback;
+ bool m_hasRedirection { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.h (228900 => 228901)
--- trunk/Source/WebCore/platform/network/ResourceResponseBase.h 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.h 2018-02-21 22:37:27 UTC (rev 228901)
@@ -139,7 +139,7 @@
WEBCORE_EXPORT std::optional<WallTime> lastModified() const;
ParsedContentRange& contentRange() const;
- enum class Source { Unknown, Network, DiskCache, DiskCacheAfterValidation, MemoryCache, MemoryCacheAfterValidation, ServiceWorker };
+ enum class Source { Unknown, Network, DiskCache, DiskCacheAfterValidation, MemoryCache, MemoryCacheAfterValidation, ServiceWorker, ApplicationCache };
WEBCORE_EXPORT Source source() const;
void setSource(Source source) { m_source = source; }
Modified: trunk/Source/WebCore/platform/network/cocoa/ResourceResponseCocoa.mm (228900 => 228901)
--- trunk/Source/WebCore/platform/network/cocoa/ResourceResponseCocoa.mm 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/platform/network/cocoa/ResourceResponseCocoa.mm 2018-02-21 22:37:27 UTC (rev 228901)
@@ -78,7 +78,7 @@
CertificateInfo ResourceResponse::platformCertificateInfo() const
{
- ASSERT(m_nsResponse || source() == Source::ServiceWorker);
+ ASSERT(m_nsResponse || source() == Source::ServiceWorker || source() == Source::ApplicationCache);
CFURLResponseRef cfResponse = [m_nsResponse _CFURLResponse];
if (!cfResponse)
Modified: trunk/Source/WebCore/testing/Internals.cpp (228900 => 228901)
--- trunk/Source/WebCore/testing/Internals.cpp 2018-02-21 22:34:01 UTC (rev 228900)
+++ trunk/Source/WebCore/testing/Internals.cpp 2018-02-21 22:37:27 UTC (rev 228901)
@@ -668,6 +668,8 @@
return "Memory cache";
case ResourceResponse::Source::MemoryCacheAfterValidation:
return "Memory cache after validation";
+ case ResourceResponse::Source::ApplicationCache:
+ return "Application cache";
}
ASSERT_NOT_REACHED();
return "Error";