[Web App Manifest] Support fetching the app manifest
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Dec 2017 02:41:20 +0000 (02:41 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Dec 2017 02:41:20 +0000 (02:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180292

Patch by David Quesada <david_quesada@apple.com> on 2017-12-05
Reviewed by Geoffrey Garen.

Add support in WebCore for loading and parsing application manifests. This functionality
is currently exposed with two methods: DocumentLoader::loadApplicationManifest() to call
to start loading the manifest, and FrameLoaderClient::finishedLoadingApplicationManifest()
for clients to override in order to be notified of the loaded manifest.

No new tests, since no functionality is exposed to web content or embedders yet. The
needed SPI will be added in an upcoming patch.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
    Added CachedApplicationManifest and ApplicationManifestLoader.
* html/HTMLLinkElement.h:
* html/LinkRelAttribute.cpp:
(WebCore::LinkRelAttribute::LinkRelAttribute):
(WebCore::LinkRelAttribute::isSupported):
    Add "manifest" as a supported 'rel' type for links.
* html/LinkRelAttribute.h:
* inspector/agents/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::resourceTypeJSON):
(WebCore::InspectorPageAgent::inspectorResourceType):
* inspector/agents/InspectorPageAgent.h:
* loader/ApplicationManifestLoader.cpp: Added.
    Added a class ApplicationManifestLoader which handles creating a ResourceRequest,
    loading the resource from the CachedResourceLoader, and parsing the resulting text.
    This class and its relation to DocumentLoader are roughly based on that of IconLoader,
    which serves a similar purpose - requesting a resource on the page and ultimately
    providing it to the embedder.
(WebCore::ApplicationManifestLoader::ApplicationManifestLoader):
(WebCore::ApplicationManifestLoader::~ApplicationManifestLoader):
(WebCore::ApplicationManifestLoader::startLoading):
(WebCore::ApplicationManifestLoader::stopLoading):
(WebCore::ApplicationManifestLoader::processManifest):
(WebCore::ApplicationManifestLoader::notifyFinished):
* loader/ApplicationManifestLoader.h: Copied from Source/WebCore/page/csp/ContentSecurityPolicyDirectiveNames.h.
* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::stopLoading):
(WebCore::DocumentLoader::loadApplicationManifest):
(WebCore::DocumentLoader::finishedLoadingApplicationManifest):
(WebCore::DocumentLoader::notifyFinishedLoadingApplicationManifest):
* loader/DocumentLoader.h:
* loader/FrameLoaderClient.h:
* loader/LinkLoader.cpp:
(WebCore::createLinkPreloadResourceClient):
(WebCore::LinkLoader::isSupportedType):
* loader/ResourceLoadInfo.cpp:
(WebCore::toResourceType):
* loader/SubresourceLoader.cpp:
(WebCore::logResourceLoaded):
* loader/cache/CachedApplicationManifest.cpp: Added.
(WebCore::CachedApplicationManifest::CachedApplicationManifest):
(WebCore::CachedApplicationManifest::finishLoading):
(WebCore::CachedApplicationManifest::setEncoding):
(WebCore::CachedApplicationManifest::encoding const):
(WebCore::CachedApplicationManifest::process):
    Add a method to process the fetched text into an ApplicationManifest. CachedApplicationManifest
    does not store the resulting ApplicationManifest because the text of an application
    manifest can yield a different ApplicationManifest depending on the URL of the document
    processing it.
* loader/cache/CachedApplicationManifest.h: Copied from Source/WebCore/page/csp/ContentSecurityPolicyDirectiveNames.h.
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::defaultPriorityForResourceType):
* loader/cache/CachedResource.h:
* loader/cache/CachedResourceLoader.cpp:
(WebCore::createResource):
(WebCore::CachedResourceLoader::requestApplicationManifest):
(WebCore::contentTypeFromResourceType):
(WebCore::CachedResourceLoader::checkInsecureContent const):
(WebCore::CachedResourceLoader::allowedByContentSecurityPolicy const):
* loader/cache/CachedResourceLoader.h:
* page/DiagnosticLoggingKeys.cpp:
(WebCore::DiagnosticLoggingKeys::applicationManifestKey):
* page/DiagnosticLoggingKeys.h:
* page/csp/ContentSecurityPolicy.cpp:
(WebCore::ContentSecurityPolicy::allowManifestFromSource const):
* page/csp/ContentSecurityPolicy.h:
* page/csp/ContentSecurityPolicyDirectiveList.cpp:
(WebCore::ContentSecurityPolicyDirectiveList::violatedDirectiveForManifest const):
(WebCore::ContentSecurityPolicyDirectiveList::addDirective):
* page/csp/ContentSecurityPolicyDirectiveList.h:
* page/csp/ContentSecurityPolicyDirectiveNames.cpp:
* page/csp/ContentSecurityPolicyDirectiveNames.h:

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

31 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/HTMLLinkElement.h
Source/WebCore/html/LinkRelAttribute.cpp
Source/WebCore/html/LinkRelAttribute.h
Source/WebCore/inspector/agents/InspectorPageAgent.cpp
Source/WebCore/inspector/agents/InspectorPageAgent.h
Source/WebCore/loader/ApplicationManifestLoader.cpp [new file with mode: 0644]
Source/WebCore/loader/ApplicationManifestLoader.h [new file with mode: 0644]
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/DocumentLoader.h
Source/WebCore/loader/FrameLoaderClient.h
Source/WebCore/loader/LinkLoader.cpp
Source/WebCore/loader/ResourceLoadInfo.cpp
Source/WebCore/loader/SubresourceLoader.cpp
Source/WebCore/loader/cache/CachedApplicationManifest.cpp [new file with mode: 0644]
Source/WebCore/loader/cache/CachedApplicationManifest.h [new file with mode: 0644]
Source/WebCore/loader/cache/CachedResource.cpp
Source/WebCore/loader/cache/CachedResource.h
Source/WebCore/loader/cache/CachedResourceLoader.cpp
Source/WebCore/loader/cache/CachedResourceLoader.h
Source/WebCore/page/DiagnosticLoggingKeys.cpp
Source/WebCore/page/DiagnosticLoggingKeys.h
Source/WebCore/page/csp/ContentSecurityPolicy.cpp
Source/WebCore/page/csp/ContentSecurityPolicy.h
Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp
Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h
Source/WebCore/page/csp/ContentSecurityPolicyDirectiveNames.cpp
Source/WebCore/page/csp/ContentSecurityPolicyDirectiveNames.h
Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp

index a80873e..bf87cbd 100644 (file)
@@ -1,3 +1,92 @@
+2017-12-05  David Quesada  <david_quesada@apple.com>
+
+        [Web App Manifest] Support fetching the app manifest 
+        https://bugs.webkit.org/show_bug.cgi?id=180292
+
+        Reviewed by Geoffrey Garen.
+
+        Add support in WebCore for loading and parsing application manifests. This functionality
+        is currently exposed with two methods: DocumentLoader::loadApplicationManifest() to call
+        to start loading the manifest, and FrameLoaderClient::finishedLoadingApplicationManifest()
+        for clients to override in order to be notified of the loaded manifest.
+
+        No new tests, since no functionality is exposed to web content or embedders yet. The
+        needed SPI will be added in an upcoming patch.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+            Added CachedApplicationManifest and ApplicationManifestLoader.
+        * html/HTMLLinkElement.h:
+        * html/LinkRelAttribute.cpp:
+        (WebCore::LinkRelAttribute::LinkRelAttribute):
+        (WebCore::LinkRelAttribute::isSupported):
+            Add "manifest" as a supported 'rel' type for links.
+        * html/LinkRelAttribute.h:
+        * inspector/agents/InspectorPageAgent.cpp:
+        (WebCore::InspectorPageAgent::resourceTypeJSON):
+        (WebCore::InspectorPageAgent::inspectorResourceType):
+        * inspector/agents/InspectorPageAgent.h:
+        * loader/ApplicationManifestLoader.cpp: Added.
+            Added a class ApplicationManifestLoader which handles creating a ResourceRequest,
+            loading the resource from the CachedResourceLoader, and parsing the resulting text.
+            This class and its relation to DocumentLoader are roughly based on that of IconLoader,
+            which serves a similar purpose - requesting a resource on the page and ultimately
+            providing it to the embedder.
+        (WebCore::ApplicationManifestLoader::ApplicationManifestLoader):
+        (WebCore::ApplicationManifestLoader::~ApplicationManifestLoader):
+        (WebCore::ApplicationManifestLoader::startLoading):
+        (WebCore::ApplicationManifestLoader::stopLoading):
+        (WebCore::ApplicationManifestLoader::processManifest):
+        (WebCore::ApplicationManifestLoader::notifyFinished):
+        * loader/ApplicationManifestLoader.h: Copied from Source/WebCore/page/csp/ContentSecurityPolicyDirectiveNames.h.
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::stopLoading):
+        (WebCore::DocumentLoader::loadApplicationManifest):
+        (WebCore::DocumentLoader::finishedLoadingApplicationManifest):
+        (WebCore::DocumentLoader::notifyFinishedLoadingApplicationManifest):
+        * loader/DocumentLoader.h:
+        * loader/FrameLoaderClient.h:
+        * loader/LinkLoader.cpp:
+        (WebCore::createLinkPreloadResourceClient):
+        (WebCore::LinkLoader::isSupportedType):
+        * loader/ResourceLoadInfo.cpp:
+        (WebCore::toResourceType):
+        * loader/SubresourceLoader.cpp:
+        (WebCore::logResourceLoaded):
+        * loader/cache/CachedApplicationManifest.cpp: Added.
+        (WebCore::CachedApplicationManifest::CachedApplicationManifest):
+        (WebCore::CachedApplicationManifest::finishLoading):
+        (WebCore::CachedApplicationManifest::setEncoding):
+        (WebCore::CachedApplicationManifest::encoding const):
+        (WebCore::CachedApplicationManifest::process):
+            Add a method to process the fetched text into an ApplicationManifest. CachedApplicationManifest
+            does not store the resulting ApplicationManifest because the text of an application
+            manifest can yield a different ApplicationManifest depending on the URL of the document
+            processing it.
+        * loader/cache/CachedApplicationManifest.h: Copied from Source/WebCore/page/csp/ContentSecurityPolicyDirectiveNames.h.
+        * loader/cache/CachedResource.cpp:
+        (WebCore::CachedResource::defaultPriorityForResourceType):
+        * loader/cache/CachedResource.h:
+        * loader/cache/CachedResourceLoader.cpp:
+        (WebCore::createResource):
+        (WebCore::CachedResourceLoader::requestApplicationManifest):
+        (WebCore::contentTypeFromResourceType):
+        (WebCore::CachedResourceLoader::checkInsecureContent const):
+        (WebCore::CachedResourceLoader::allowedByContentSecurityPolicy const):
+        * loader/cache/CachedResourceLoader.h:
+        * page/DiagnosticLoggingKeys.cpp:
+        (WebCore::DiagnosticLoggingKeys::applicationManifestKey):
+        * page/DiagnosticLoggingKeys.h:
+        * page/csp/ContentSecurityPolicy.cpp:
+        (WebCore::ContentSecurityPolicy::allowManifestFromSource const):
+        * page/csp/ContentSecurityPolicy.h:
+        * page/csp/ContentSecurityPolicyDirectiveList.cpp:
+        (WebCore::ContentSecurityPolicyDirectiveList::violatedDirectiveForManifest const):
+        (WebCore::ContentSecurityPolicyDirectiveList::addDirective):
+        * page/csp/ContentSecurityPolicyDirectiveList.h:
+        * page/csp/ContentSecurityPolicyDirectiveNames.cpp:
+        * page/csp/ContentSecurityPolicyDirectiveNames.h:
+
 2017-12-05  Stephan Szabo  <stephan.szabo@sony.com>
 
         Switch windows build to Visual Studio 2017
index 5660860..93c0207 100644 (file)
@@ -27,6 +27,10 @@ Modules/airplay/WebKitPlaybackTargetAvailabilityEvent.cpp
 
 Modules/applicationmanifest/ApplicationManifestParser.cpp
 
+loader/ApplicationManifestLoader.cpp
+
+loader/cache/CachedApplicationManifest.cpp
+
 #endif
 
 Modules/beacon/NavigatorBeacon.cpp
index 079f3d8..7383378 100644 (file)
                628D214E12131EF40055DCFC /* FrameNetworkingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 628D214D12131EF40055DCFC /* FrameNetworkingContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
                62C1217D11AB9E77003C462C /* SuspendableTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 62C1217B11AB9E77003C462C /* SuspendableTimer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                62CD325A1157E57C0063B0A7 /* CustomEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 62CD32571157E57C0063B0A7 /* CustomEvent.h */; };
+               63152D191F9531EE007A5E4B /* ApplicationManifestLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 63152D171F9531EE007A5E4B /* ApplicationManifestLoader.h */; };
                63189AE30E83A33300012E41 /* NodeRareData.h in Headers */ = {isa = PBXBuildFile; fileRef = 63189AE20E83A33300012E41 /* NodeRareData.h */; settings = {ATTRIBUTES = (); }; };
+               6353E1E61F91743100A34208 /* CachedApplicationManifest.h in Headers */ = {isa = PBXBuildFile; fileRef = 6353E1E41F91743100A34208 /* CachedApplicationManifest.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6354F4C91F7AFC9400D89DF3 /* ApplicationManifestParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 6354F4C71F7AFC9400D89DF3 /* ApplicationManifestParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
                63BD4A5F1F778E9F00438722 /* ApplicationManifest.h in Headers */ = {isa = PBXBuildFile; fileRef = 63BD4A5D1F778E9F00438722 /* ApplicationManifest.h */; settings = {ATTRIBUTES = (Private, ); }; };
                63D7B32D0E78CD3F00F7617C /* NodeRenderStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 63D7B32C0E78CD3F00F7617C /* NodeRenderStyle.h */; settings = {ATTRIBUTES = (Private, ); }; };
                62CD32561157E57C0063B0A7 /* CustomEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CustomEvent.cpp; sourceTree = "<group>"; };
                62CD32571157E57C0063B0A7 /* CustomEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomEvent.h; sourceTree = "<group>"; };
                62CD32581157E57C0063B0A7 /* CustomEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CustomEvent.idl; sourceTree = "<group>"; };
+               63152D171F9531EE007A5E4B /* ApplicationManifestLoader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ApplicationManifestLoader.h; sourceTree = "<group>"; };
+               63152D181F9531EE007A5E4B /* ApplicationManifestLoader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ApplicationManifestLoader.cpp; sourceTree = "<group>"; };
                63189AE20E83A33300012E41 /* NodeRareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NodeRareData.h; sourceTree = "<group>"; };
+               6353E1E41F91743100A34208 /* CachedApplicationManifest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CachedApplicationManifest.h; sourceTree = "<group>"; };
+               6353E1E51F91743100A34208 /* CachedApplicationManifest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CachedApplicationManifest.cpp; sourceTree = "<group>"; };
                6354F4C71F7AFC9400D89DF3 /* ApplicationManifestParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ApplicationManifestParser.h; sourceTree = "<group>"; };
                6354F4C81F7AFC9400D89DF3 /* ApplicationManifestParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ApplicationManifestParser.cpp; sourceTree = "<group>"; };
                637B7ADE0E8767B800E32194 /* ElementRareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementRareData.h; sourceTree = "<group>"; };
                A8D2B2521287A56000AF4DDA /* cache */ = {
                        isa = PBXGroup;
                        children = (
+                               6353E1E51F91743100A34208 /* CachedApplicationManifest.cpp */,
+                               6353E1E41F91743100A34208 /* CachedApplicationManifest.h */,
                                BCB16C000979C3BD00467741 /* CachedCSSStyleSheet.cpp */,
                                BCB16C010979C3BD00467741 /* CachedCSSStyleSheet.h */,
                                BC64B4C90CB4295D005F2B62 /* CachedFont.cpp */,
                                5126E6B60A2E3AEF005C29FA /* icon */,
                                A15E31F01E0CB075004B371C /* ios */,
                                93A1EAA20A5634D8006960A0 /* mac */,
+                               63152D181F9531EE007A5E4B /* ApplicationManifestLoader.cpp */,
+                               63152D171F9531EE007A5E4B /* ApplicationManifestLoader.h */,
                                A149786C1ABAF33800CEF7E4 /* ContentFilter.cpp */,
                                A149786D1ABAF33800CEF7E4 /* ContentFilter.h */,
                                E1424C91164B52C800F32D40 /* CookieJar.cpp */,
                                1A8F6BC10DB55CDC001DB794 /* ApplicationCacheResource.h in Headers */,
                                1A2AAC590DC2A3B100A20D9A /* ApplicationCacheStorage.h in Headers */,
                                63BD4A5F1F778E9F00438722 /* ApplicationManifest.h in Headers */,
+                               63152D191F9531EE007A5E4B /* ApplicationManifestLoader.h in Headers */,
                                6354F4C91F7AFC9400D89DF3 /* ApplicationManifestParser.h in Headers */,
                                9B417064125662B3006B28FC /* ApplyBlockElementCommand.h in Headers */,
                                93309DD9099E64920056E581 /* ApplyStyleCommand.h in Headers */,
                                1A569CFC0D7E2B82007C3983 /* c_runtime.h in Headers */,
                                1A569CFE0D7E2B82007C3983 /* c_utility.h in Headers */,
                                07C046C41E42508B007201E7 /* CAAudioStreamDescription.h in Headers */,
+                               6353E1E61F91743100A34208 /* CachedApplicationManifest.h in Headers */,
                                BCB16C1A0979C3BD00467741 /* CachedCSSStyleSheet.h in Headers */,
                                BC64B4CC0CB4295D005F2B62 /* CachedFont.h in Headers */,
                                1AEF4E67170E160300AB2799 /* CachedFontClient.h in Headers */,
index c4b68cc..1092cbf 100644 (file)
@@ -73,6 +73,10 @@ public:
 
     WEBCORE_EXPORT DOMTokenList& relList();
 
+#if ENABLE(APPLICATION_MANIFEST)
+    bool isApplicationManifest() const { return m_relAttribute.isApplicationManifest; }
+#endif
+
 private:
     void parseAttribute(const QualifiedName&, const AtomicString&) final;
 
index 572bdb3..af0b1b0 100644 (file)
@@ -65,6 +65,10 @@ LinkRelAttribute::LinkRelAttribute(Document& document, const String& rel)
     else if (equalLettersIgnoringASCIICase(rel, "alternate stylesheet") || equalLettersIgnoringASCIICase(rel, "stylesheet alternate")) {
         isStyleSheet = true;
         isAlternate = true;
+#if ENABLE(APPLICATION_MANIFEST)
+    } else if (equalLettersIgnoringASCIICase(rel, "manifest")) {
+        isApplicationManifest = true;
+#endif
     } else {
         // Tokenize the rel attribute and set bits based on specific keywords that we find.
         String relCopy = rel;
@@ -98,6 +102,9 @@ bool LinkRelAttribute::isSupported(Document& document, StringView attribute)
 #if ENABLE(LINK_PREFETCH)
         "prefetch", "subresource",
 #endif
+#if ENABLE(APPLICATION_MANIFEST)
+        "manifest",
+#endif
     };
 
     for (auto* supportedAttribute : supportedAttributes) {
index f12e986..a6110a7 100644 (file)
@@ -51,6 +51,9 @@ struct LinkRelAttribute {
     bool isLinkPrefetch { false };
     bool isLinkSubresource { false };
 #endif
+#if ENABLE(APPLICATION_MANIFEST)
+    bool isApplicationManifest { false };
+#endif
 
     LinkRelAttribute();
     LinkRelAttribute(Document&, const String&);
index d654f14..2cb1dae 100644 (file)
 #include <wtf/text/StringBuilder.h>
 #include <yarr/RegularExpression.h>
 
+#if ENABLE(APPLICATION_MANIFEST)
+#include "CachedApplicationManifest.h"
+#endif
+
 #if ENABLE(WEB_ARCHIVE) && USE(CF)
 #include "LegacyWebArchive.h"
 #endif
@@ -204,6 +208,10 @@ Inspector::Protocol::Page::ResourceType InspectorPageAgent::resourceTypeJSON(Ins
         return Inspector::Protocol::Page::ResourceType::WebSocket;
     case OtherResource:
         return Inspector::Protocol::Page::ResourceType::Other;
+#if ENABLE(APPLICATION_MANIFEST)
+    case ApplicationManifestResource:
+        break;
+#endif
     }
     return Inspector::Protocol::Page::ResourceType::Other;
 }
@@ -229,6 +237,10 @@ InspectorPageAgent::ResourceType InspectorPageAgent::inspectorResourceType(Cache
         return InspectorPageAgent::DocumentResource;
     case CachedResource::Beacon:
         return InspectorPageAgent::BeaconResource;
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+        return InspectorPageAgent::ApplicationManifestResource;
+#endif
     case CachedResource::MediaResource:
     case CachedResource::Icon:
     case CachedResource::RawResource:
index 483da93..2cf81f5 100644 (file)
@@ -71,6 +71,9 @@ public:
         PingResource,
         BeaconResource,
         WebSocketResource,
+#if ENABLE(APPLICATION_MANIFEST)
+        ApplicationManifestResource,
+#endif
         OtherResource,
     };
 
diff --git a/Source/WebCore/loader/ApplicationManifestLoader.cpp b/Source/WebCore/loader/ApplicationManifestLoader.cpp
new file mode 100644 (file)
index 0000000..11655de
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ApplicationManifestLoader.h"
+
+#if ENABLE(APPLICATION_MANIFEST)
+
+#include "CachedApplicationManifest.h"
+#include "CachedResourceLoader.h"
+#include "CachedResourceRequest.h"
+#include "CachedResourceRequestInitiators.h"
+#include "DocumentLoader.h"
+#include "Frame.h"
+
+namespace WebCore {
+
+ApplicationManifestLoader::ApplicationManifestLoader(DocumentLoader& documentLoader, const URL& url, bool useCredentials)
+    : m_documentLoader(documentLoader)
+    , m_url(url)
+    , m_useCredentials(useCredentials)
+{
+}
+
+ApplicationManifestLoader::~ApplicationManifestLoader()
+{
+    stopLoading();
+}
+
+bool ApplicationManifestLoader::startLoading()
+{
+    ASSERT(!m_resource);
+    auto* frame = m_documentLoader.frame();
+    if (!frame)
+        return false;
+
+    ResourceRequest resourceRequest = m_url;
+    resourceRequest.setPriority(ResourceLoadPriority::Low);
+#if !ERROR_DISABLED
+    // Copy this because we may want to access it after transferring the
+    // `resourceRequest` to the `request`. If we don't, then the LOG_ERROR
+    // below won't print a URL.
+    auto resourceRequestURL = resourceRequest.url();
+#endif
+
+    auto credentials = m_useCredentials ? FetchOptions::Credentials::Include : FetchOptions::Credentials::Omit;
+    auto options = ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, StoredCredentialsPolicy::DoNotUse, ClientCredentialPolicy::CannotAskClientForCredentials, credentials, DoSecurityCheck, FetchOptions::Mode::NoCors, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::AllowCaching);
+    options.destination = FetchOptions::Destination::Manifest;
+    CachedResourceRequest request(WTFMove(resourceRequest), options);
+
+    auto cachedResource = frame->document()->cachedResourceLoader().requestApplicationManifest(WTFMove(request));
+    m_resource = cachedResource.value_or(nullptr);
+    if (m_resource)
+        m_resource->addClient(*this);
+    else {
+        LOG_ERROR("Failed to start load for application manifest at url %s (error: %s)", resourceRequestURL.string().ascii().data(), cachedResource.error().localizedDescription().utf8().data());
+        return false;
+    }
+
+    return true;
+}
+
+void ApplicationManifestLoader::stopLoading()
+{
+    if (m_resource) {
+        m_resource->removeClient(*this);
+        m_resource = nullptr;
+    }
+}
+
+std::optional<ApplicationManifest>& ApplicationManifestLoader::processManifest()
+{
+    if (!m_processedManifest && m_resource) {
+        auto manifestURL = m_url;
+        auto documentURL = m_documentLoader.url();
+        auto frame = m_documentLoader.frame();
+        auto document = frame ? frame->document() : nullptr;
+        m_processedManifest = m_resource->process(manifestURL, documentURL, document);
+    }
+    return m_processedManifest;
+}
+
+void ApplicationManifestLoader::notifyFinished(CachedResource& resource)
+{
+    ASSERT_UNUSED(resource, &resource == m_resource);
+    m_documentLoader.finishedLoadingApplicationManifest(*this);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(APPLICATION_MANIFEST)
diff --git a/Source/WebCore/loader/ApplicationManifestLoader.h b/Source/WebCore/loader/ApplicationManifestLoader.h
new file mode 100644 (file)
index 0000000..8b6431a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(APPLICATION_MANIFEST)
+
+#include "ApplicationManifest.h"
+#include "CachedRawResourceClient.h"
+#include "CachedResourceHandle.h"
+#include "URL.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class CachedApplicationManifest;
+class DocumentLoader;
+
+class ApplicationManifestLoader final : private CachedRawResourceClient {
+WTF_MAKE_NONCOPYABLE(ApplicationManifestLoader); WTF_MAKE_FAST_ALLOCATED;
+public:
+    typedef WTF::Function<void (CachedResourceHandle<CachedApplicationManifest>)> CompletionHandlerType;
+
+    ApplicationManifestLoader(DocumentLoader&, const URL&, bool);
+    virtual ~ApplicationManifestLoader();
+
+    bool startLoading();
+    void stopLoading();
+
+    std::optional<ApplicationManifest>& processManifest();
+
+private:
+    void notifyFinished(CachedResource&);
+
+    DocumentLoader& m_documentLoader;
+    std::optional<ApplicationManifest> m_processedManifest;
+    URL m_url;
+    bool m_useCredentials;
+    CachedResourceHandle<CachedApplicationManifest> m_resource;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(APPLICATION_MANIFEST)
index 5a43cc4..29d79af 100644 (file)
 #include <wtf/text/CString.h>
 #include <wtf/text/WTFString.h>
 
+#if ENABLE(APPLICATION_MANIFEST)
+#include "ApplicationManifestLoader.h"
+#include "HTMLHeadElement.h"
+#include "HTMLLinkElement.h"
+#endif
+
 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
 #include "ArchiveFactory.h"
 #endif
@@ -281,6 +287,12 @@ void DocumentLoader::stopLoading()
         notifyFinishedLoadingIcon(callbackIdentifier, nullptr);
     m_iconLoaders.clear();
     m_iconsPendingLoadDecision.clear();
+    
+#if ENABLE(APPLICATION_MANIFEST)
+    for (auto callbackIdentifier : m_applicationManifestLoaders.values())
+        notifyFinishedLoadingApplicationManifest(callbackIdentifier, std::nullopt);
+    m_applicationManifestLoaders.clear();
+#endif
 
     // Always cancel multipart loaders
     cancelAll(m_multipartSubresourceLoaders);
@@ -1045,6 +1057,69 @@ void DocumentLoader::clearMainResourceLoader()
         checkLoadComplete();
 }
 
+#if ENABLE(APPLICATION_MANIFEST)
+uint64_t DocumentLoader::loadApplicationManifest()
+{
+    static uint64_t nextCallbackID = 1;
+
+    auto* document = this->document();
+    if (!document)
+        return 0;
+
+    if (!m_frame->isMainFrame())
+        return 0;
+
+    if (document->url().isEmpty() || document->url().isBlankURL())
+        return 0;
+
+    auto head = document->head();
+    if (!head)
+        return 0;
+
+    URL manifestURL;
+    bool useCredentials = false;
+    for (const auto& link : childrenOfType<HTMLLinkElement>(*head)) {
+        if (link.isApplicationManifest()) {
+            manifestURL = link.href();
+            useCredentials = equalIgnoringASCIICase(link.attributeWithoutSynchronization(HTMLNames::crossoriginAttr), "use-credentials");
+            break;
+        }
+    }
+
+    if (manifestURL.isEmpty() || !manifestURL.isValid())
+        return 0;
+
+    auto manifestLoader = std::make_unique<ApplicationManifestLoader>(*this, manifestURL, useCredentials);
+    auto* rawManifestLoader = manifestLoader.get();
+    auto callbackID = nextCallbackID++;
+    m_applicationManifestLoaders.set(WTFMove(manifestLoader), callbackID);
+
+    if (!rawManifestLoader->startLoading()) {
+        m_applicationManifestLoaders.remove(rawManifestLoader);
+        return 0;
+    }
+
+    return callbackID;
+}
+
+void DocumentLoader::finishedLoadingApplicationManifest(ApplicationManifestLoader& loader)
+{
+    // If the DocumentLoader has detached from its frame, all manifest loads should have already been canceled.
+    ASSERT(m_frame);
+
+    auto callbackIdentifier = m_applicationManifestLoaders.get(&loader);
+    notifyFinishedLoadingApplicationManifest(callbackIdentifier, loader.processManifest());
+    m_applicationManifestLoaders.remove(&loader);
+}
+
+void DocumentLoader::notifyFinishedLoadingApplicationManifest(uint64_t callbackIdentifier, std::optional<ApplicationManifest> manifest)
+{
+    RELEASE_ASSERT(callbackIdentifier);
+    RELEASE_ASSERT(m_frame);
+    m_frame->loader().client().finishedLoadingApplicationManifest(callbackIdentifier, manifest);
+}
+#endif
+
 void DocumentLoader::setCustomHeaderFields(Vector<HTTPHeaderField>&& fields)
 {
     m_customHeaderFields = WTFMove(fields);
index efb8da2..f5a3d35 100644 (file)
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
+#if ENABLE(APPLICATION_MANIFEST)
+#include "ApplicationManifest.h"
+#endif
+
 #if HAVE(RUNLOOP_TIMER)
 #include <wtf/RunLoopTimer.h>
 #endif
@@ -61,6 +65,7 @@
 namespace WebCore {
 
 class ApplicationCacheHost;
+class ApplicationManifestLoader;
 class Archive;
 class ArchiveResource;
 class ArchiveResourceCollection;
@@ -297,6 +302,11 @@ public:
 
     const Vector<LinkIcon>& linkIcons() const { return m_linkIcons; }
 
+#if ENABLE(APPLICATION_MANIFEST)
+    WEBCORE_EXPORT uint64_t loadApplicationManifest();
+    void finishedLoadingApplicationManifest(ApplicationManifestLoader&);
+#endif
+
     WEBCORE_EXPORT void setCustomHeaderFields(Vector<HTTPHeaderField>&& fields);
     const Vector<HTTPHeaderField>& customHeaderFields() { return m_customHeaderFields; }
     
@@ -370,6 +380,10 @@ private:
 
     void notifyFinishedLoadingIcon(uint64_t callbackIdentifier, SharedBuffer*);
 
+#if ENABLE(APPLICATION_MANIFEST)
+    void notifyFinishedLoadingApplicationManifest(uint64_t callbackIdentifier, std::optional<ApplicationManifest>);
+#endif
+
     Ref<CachedResourceLoader> m_cachedResourceLoader;
 
     CachedResourceHandle<CachedRawResource> m_mainResource;
@@ -459,6 +473,10 @@ private:
     HashMap<std::unique_ptr<IconLoader>, uint64_t> m_iconLoaders;
     Vector<LinkIcon> m_linkIcons;
 
+#if ENABLE(APPLICATION_MANIFEST)
+    HashMap<std::unique_ptr<ApplicationManifestLoader>, uint64_t> m_applicationManifestLoaders;
+#endif
+
     Vector<HTTPHeaderField> m_customHeaderFields;
     
     bool m_subresourceLoadersArePageCacheAcceptable { false };
index 02f9b42..1501618 100644 (file)
 #include <wtf/Forward.h>
 #include <wtf/text/WTFString.h>
 
+#if ENABLE(APPLICATION_MANIFEST)
+#include "ApplicationManifest.h"
+#endif
+
 #if ENABLE(CONTENT_FILTERING)
 #include "ContentFilterUnblockHandler.h"
 #endif
@@ -356,6 +360,10 @@ public:
 
     virtual void getLoadDecisionForIcons(const Vector<std::pair<WebCore::LinkIcon&, uint64_t>>&) { }
     virtual void finishedLoadingIcon(uint64_t, SharedBuffer*) { }
+
+#if ENABLE(APPLICATION_MANIFEST)
+    virtual void finishedLoadingApplicationManifest(uint64_t, const std::optional<ApplicationManifest>&) { }
+#endif
 };
 
 } // namespace WebCore
index 895f1c3..baa1611 100644 (file)
@@ -171,6 +171,11 @@ static std::unique_ptr<LinkPreloadResourceClient> createLinkPreloadResourceClien
 #endif
         // None of these values is currently supported as an `as` value.
         ASSERT_NOT_REACHED();
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+        // FIXME: Support preloading the manifest.
+        ASSERT_NOT_REACHED();
+#endif
     }
     return nullptr;
 }
@@ -198,6 +203,9 @@ bool LinkLoader::isSupportedType(CachedResource::Type resourceType, const String
         return MIMETypeRegistry::isSupportedTextTrackMIMEType(mimeType);
 #endif
     case CachedResource::RawResource:
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+#endif
         return true;
     default:
         ASSERT_NOT_REACHED();
index 13b2ae1..03d61eb 100644 (file)
@@ -70,6 +70,10 @@ ResourceType toResourceType(CachedResource::Type type)
     case CachedResource::LinkSubresource:
         ASSERT_NOT_REACHED();
 #endif
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+        return ResourceType::Raw;
+#endif
     };
     return ResourceType::Raw;
 }
index c1c8a53..f5ede23 100644 (file)
@@ -471,6 +471,11 @@ static void logResourceLoaded(Frame* frame, CachedResource::Type type)
     case CachedResource::SVGDocumentResource:
         resourceType = DiagnosticLoggingKeys::svgDocumentKey();
         break;
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+        resourceType = DiagnosticLoggingKeys::applicationManifestKey();
+        break;
+#endif
 #if ENABLE(LINK_PREFETCH)
     case CachedResource::LinkPrefetch:
     case CachedResource::LinkSubresource:
diff --git a/Source/WebCore/loader/cache/CachedApplicationManifest.cpp b/Source/WebCore/loader/cache/CachedApplicationManifest.cpp
new file mode 100644 (file)
index 0000000..411307e
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CachedApplicationManifest.h"
+
+#if ENABLE(APPLICATION_MANIFEST)
+
+#include "ApplicationManifestParser.h"
+#include "SharedBuffer.h"
+#include "TextResourceDecoder.h"
+
+namespace WebCore {
+
+CachedApplicationManifest::CachedApplicationManifest(CachedResourceRequest&& request, PAL::SessionID sessionID)
+    : CachedResource(WTFMove(request), ApplicationManifest, sessionID)
+    , m_decoder(TextResourceDecoder::create("application/manifest+json", UTF8Encoding()))
+{
+}
+
+void CachedApplicationManifest::finishLoading(SharedBuffer* data)
+{
+    m_data = data;
+    setEncodedSize(data ? data->size() : 0);
+    if (data)
+        m_text = m_decoder->decodeAndFlush(data->data(), data->size());
+    CachedResource::finishLoading(data);
+}
+
+void CachedApplicationManifest::setEncoding(const String& chs)
+{
+    m_decoder->setEncoding(chs, TextResourceDecoder::EncodingFromHTTPHeader);
+}
+
+String CachedApplicationManifest::encoding() const
+{
+    return m_decoder->encoding().name();
+}
+
+std::optional<ApplicationManifest> CachedApplicationManifest::process(const URL& manifestURL, const URL& documentURL, RefPtr<ScriptExecutionContext> scriptExecutionContext)
+{
+    if (!m_text)
+        return std::nullopt;
+    if (scriptExecutionContext)
+        return ApplicationManifestParser::parse(*scriptExecutionContext, *m_text, manifestURL, documentURL);
+    return ApplicationManifestParser::parse(*m_text, manifestURL, documentURL);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(APPLICATION_MANIFEST)
diff --git a/Source/WebCore/loader/cache/CachedApplicationManifest.h b/Source/WebCore/loader/cache/CachedApplicationManifest.h
new file mode 100644 (file)
index 0000000..6b1a753
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(APPLICATION_MANIFEST)
+
+#include "ApplicationManifest.h"
+#include "CachedResource.h"
+#include <wtf/Optional.h>
+
+namespace WebCore {
+
+class ScriptExecutionContext;
+class TextResourceDecoder;
+
+class CachedApplicationManifest final : public CachedResource {
+public:
+    CachedApplicationManifest(CachedResourceRequest&&, PAL::SessionID);
+
+    std::optional<struct ApplicationManifest> process(const URL& manifestURL, const URL& documentURL, RefPtr<ScriptExecutionContext> = nullptr);
+
+private:
+    void finishLoading(SharedBuffer*) override;
+    const TextResourceDecoder* textResourceDecoder() const override { return m_decoder.ptr(); }
+    void setEncoding(const String&) override;
+    String encoding() const override;
+
+    Ref<TextResourceDecoder> m_decoder;
+    std::optional<String> m_text;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CACHED_RESOURCE(CachedApplicationManifest, CachedResource::ApplicationManifest)
+
+#endif // ENABLE(APPLICATION_MANIFEST)
index d8dbdf3..becb98a 100644 (file)
@@ -102,6 +102,10 @@ ResourceLoadPriority CachedResource::defaultPriorityForResourceType(Type type)
     case CachedResource::TextTrackResource:
         return ResourceLoadPriority::Low;
 #endif
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+        return ResourceLoadPriority::Low;
+#endif
     }
     ASSERT_NOT_REACHED();
     return ResourceLoadPriority::Low;
index c7eae12..35f78ce 100644 (file)
@@ -84,6 +84,9 @@ public:
 #if ENABLE(VIDEO_TRACK)
         , TextTrackResource
 #endif
+#if ENABLE(APPLICATION_MANIFEST)
+        , ApplicationManifest
+#endif
     };
 
     enum Status {
index 9d906b8..ac1f89a 100644 (file)
 #include <wtf/text/CString.h>
 #include <wtf/text/WTFString.h>
 
+#if ENABLE(APPLICATION_MANIFEST)
+#include "CachedApplicationManifest.h"
+#endif
+
 #if ENABLE(VIDEO_TRACK)
 #include "CachedTextTrack.h"
 #endif
@@ -134,6 +138,10 @@ static CachedResource* createResource(CachedResource::Type type, CachedResourceR
     case CachedResource::TextTrackResource:
         return new CachedTextTrack(WTFMove(request), sessionID);
 #endif
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+        return new CachedApplicationManifest(WTFMove(request), sessionID);
+#endif
     }
     ASSERT_NOT_REACHED();
     return nullptr;
@@ -322,6 +330,13 @@ ResourceErrorOr<CachedResourceHandle<CachedRawResource>> CachedResourceLoader::r
     return castCachedResourceTo<CachedRawResource>(requestResource(CachedResource::MainResource, WTFMove(request)));
 }
 
+#if ENABLE(APPLICATION_MANIFEST)
+ResourceErrorOr<CachedResourceHandle<CachedApplicationManifest>> CachedResourceLoader::requestApplicationManifest(CachedResourceRequest&& request)
+{
+    return castCachedResourceTo<CachedApplicationManifest>(requestResource(CachedResource::ApplicationManifest, WTFMove(request)));
+}
+#endif // ENABLE(APPLICATION_MANIFEST)
+
 static MixedContentChecker::ContentType contentTypeFromResourceType(CachedResource::Type type)
 {
     switch (type) {
@@ -362,6 +377,10 @@ static MixedContentChecker::ContentType contentTypeFromResourceType(CachedResour
     case CachedResource::TextTrackResource:
         return MixedContentChecker::ContentType::Active;
 #endif
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+        return MixedContentChecker::ContentType::Active;
+#endif
     default:
         ASSERT_NOT_REACHED();
         return MixedContentChecker::ContentType::Active;
@@ -418,6 +437,9 @@ bool CachedResourceLoader::checkInsecureContent(CachedResource::Type type, const
     case CachedResource::LinkSubresource:
         // Prefetch cannot affect the current document.
 #endif
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+#endif
         break;
     }
     return true;
@@ -466,6 +488,12 @@ bool CachedResourceLoader::allowedByContentSecurityPolicy(CachedResource::Type t
     case CachedResource::Beacon:
     case CachedResource::RawResource:
         return true;
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+        if (!m_document->contentSecurityPolicy()->allowManifestFromSource(url, redirectResponseReceived))
+            return false;
+        break;
+#endif
     default:
         ASSERT_NOT_REACHED();
     }
index d3288ca..8b513c6 100644 (file)
@@ -41,6 +41,9 @@
 
 namespace WebCore {
 
+#if ENABLE(APPLICATION_MANIFEST)
+class CachedApplicationManifest;
+#endif
 class CachedCSSStyleSheet;
 class CachedSVGDocument;
 class CachedFont;
@@ -96,6 +99,9 @@ public:
 #if ENABLE(VIDEO_TRACK)
     ResourceErrorOr<CachedResourceHandle<CachedTextTrack>> requestTextTrack(CachedResourceRequest&&);
 #endif
+#if ENABLE(APPLICATION_MANIFEST)
+    ResourceErrorOr<CachedResourceHandle<CachedApplicationManifest>> requestApplicationManifest(CachedResourceRequest&&);
+#endif
 
     // Logs an access denied message to the console for the specified URL.
     void printAccessDeniedMessage(const URL& url) const;
index ef10201..6f91d46 100644 (file)
@@ -413,6 +413,13 @@ String DiagnosticLoggingKeys::applicationCacheKey()
     return ASCIILiteral("applicationCache");
 }
 
+#if ENABLE(APPLICATION_MANIFEST)
+String DiagnosticLoggingKeys::applicationManifestKey()
+{
+    return ASCIILiteral("applicationManifest");
+}
+#endif
+
 String DiagnosticLoggingKeys::audioKey()
 {
     return ASCIILiteral("audio");
index a2bd365..66719f7 100644 (file)
@@ -34,6 +34,9 @@ public:
     WEBCORE_EXPORT static String activeInForegroundTabKey();
     WEBCORE_EXPORT static String activeInBackgroundTabOnlyKey();
     static String applicationCacheKey();
+#if ENABLE(APPLICATION_MANIFEST)
+    static String applicationManifestKey();
+#endif
     static String audioKey();
     WEBCORE_EXPORT static String backNavigationDeltaKey();
     WEBCORE_EXPORT static String cacheControlNoStoreKey();
index a464890..7c55511 100644 (file)
@@ -549,6 +549,13 @@ bool ContentSecurityPolicy::allowFontFromSource(const URL& url, RedirectResponse
     return allowResourceFromSource(url, redirectResponseReceived, ContentSecurityPolicyDirectiveNames::fontSrc, &ContentSecurityPolicyDirectiveList::violatedDirectiveForFont);
 }
 
+#if ENABLE(APPLICATION_MANIFEST)
+bool ContentSecurityPolicy::allowManifestFromSource(const URL& url, RedirectResponseReceived redirectResponseReceived) const
+{
+    return allowResourceFromSource(url, redirectResponseReceived, ContentSecurityPolicyDirectiveNames::manifestSrc, &ContentSecurityPolicyDirectiveList::violatedDirectiveForManifest);
+}
+#endif // ENABLE(APPLICATION_MANIFEST)
+
 bool ContentSecurityPolicy::allowMediaFromSource(const URL& url, RedirectResponseReceived redirectResponseReceived) const
 {
     return allowResourceFromSource(url, redirectResponseReceived, ContentSecurityPolicyDirectiveNames::mediaSrc, &ContentSecurityPolicyDirectiveList::violatedDirectiveForMedia);
index a6da0d6..fbd8d39 100644 (file)
@@ -103,6 +103,9 @@ public:
     bool allowImageFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
     bool allowStyleFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
     bool allowFontFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
+#if ENABLE(APPLICATION_MANIFEST)
+    bool allowManifestFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
+#endif
     bool allowMediaFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
 
     bool allowChildFrameFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
index 2c46c67..8ed3ac9 100644 (file)
@@ -243,6 +243,16 @@ const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violat
     return operativeDirective;
 }
 
+#if ENABLE(APPLICATION_MANIFEST)
+const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForManifest(const URL& url, bool didReceiveRedirectResponse) const
+{
+    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_manifestSrc.get());
+    if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
+        return nullptr;
+    return operativeDirective;
+}
+#endif // ENABLE(APPLICATION_MANIFEST)
+
 const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForMedia(const URL& url, bool didReceiveRedirectResponse) const
 {
     ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_mediaSrc.get());
@@ -475,6 +485,10 @@ void ContentSecurityPolicyDirectiveList::addDirective(const String& name, const
         setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_imgSrc);
     else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::fontSrc))
         setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_fontSrc);
+#if ENABLE(APPLICATION_MANIFEST)
+    else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::manifestSrc))
+        setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_manifestSrc);
+#endif
     else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::mediaSrc))
         setCSPDirective<ContentSecurityPolicySourceListDirective>(name, value, m_mediaSrc);
     else if (equalIgnoringASCIICase(name, ContentSecurityPolicyDirectiveNames::connectSrc))
index 70a2430..91261fa 100644 (file)
@@ -63,6 +63,9 @@ public:
     const ContentSecurityPolicyDirective* violatedDirectiveForFrame(const URL&, bool didReceiveRedirectResponse) const;
     const ContentSecurityPolicyDirective* violatedDirectiveForFrameAncestor(const Frame&) const;
     const ContentSecurityPolicyDirective* violatedDirectiveForImage(const URL&, bool didReceiveRedirectResponse) const;
+#if ENABLE(APPLICATION_MANIFEST)
+    const ContentSecurityPolicyDirective* violatedDirectiveForManifest(const URL&, bool didReceiveRedirectResponse) const;
+#endif
     const ContentSecurityPolicyDirective* violatedDirectiveForMedia(const URL&, bool didReceiveRedirectResponse) const;
     const ContentSecurityPolicyDirective* violatedDirectiveForObjectSource(const URL&, bool didReceiveRedirectResponse, ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone) const;
     const ContentSecurityPolicyDirective* violatedDirectiveForPluginType(const String& type, const String& typeAttribute) const;
@@ -121,6 +124,9 @@ private:
     std::unique_ptr<ContentSecurityPolicySourceListDirective> m_frameAncestors;
     std::unique_ptr<ContentSecurityPolicySourceListDirective> m_frameSrc;
     std::unique_ptr<ContentSecurityPolicySourceListDirective> m_imgSrc;
+#if ENABLE(APPLICATION_MANIFEST)
+    std::unique_ptr<ContentSecurityPolicySourceListDirective> m_manifestSrc;
+#endif
     std::unique_ptr<ContentSecurityPolicySourceListDirective> m_mediaSrc;
     std::unique_ptr<ContentSecurityPolicySourceListDirective> m_objectSrc;
     std::unique_ptr<ContentSecurityPolicySourceListDirective> m_scriptSrc;
index 261f741..076a504 100644 (file)
@@ -38,6 +38,9 @@ const char* const fontSrc = "font-src";
 const char* const formAction = "form-action";
 const char* const frameAncestors = "frame-ancestors";
 const char* const frameSrc = "frame-src";
+#if ENABLE(APPLICATION_MANIFEST)
+const char* const manifestSrc = "manifest-src";
+#endif
 const char* const imgSrc = "img-src";
 const char* const mediaSrc = "media-src";
 const char* const objectSrc = "object-src";
index f13f04a..aeacd46 100644 (file)
@@ -38,6 +38,9 @@ extern const char* const formAction;
 extern const char* const frameAncestors;
 extern const char* const frameSrc;
 extern const char* const imgSrc;
+#if ENABLE(APPLICATION_MANIFEST)
+extern const char* const manifestSrc;
+#endif
 extern const char* const mediaSrc;
 extern const char* const objectSrc;
 extern const char* const pluginTypes;
index 33f70e9..17a2f43 100644 (file)
@@ -121,6 +121,9 @@ static Seconds maximumBufferingTime(CachedResource* resource)
     case CachedResource::SVGFontResource:
 #endif
     case CachedResource::FontResource:
+#if ENABLE(APPLICATION_MANIFEST)
+    case CachedResource::ApplicationManifest:
+#endif
         return Seconds::infinity();
     case CachedResource::ImageResource:
         return 500_ms;