WebPage sometimes incorrectly rules out PDF as a mime type that can be showed
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Apr 2018 21:01:25 +0000 (21:01 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Apr 2018 21:01:25 +0000 (21:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184369

Reviewed by Chris Dumez.

Source/WebCore:

WebPage does need to check for plugins at reception of the response.
In that case, the page URL is the URL from which we are navigating out.
Add plugin API to check for plugin availability with an extra URL parameter to cover that case.

Covered by API test.

* plugins/PluginData.cpp:
(WebCore::PluginData::supportsWebVisibleMimeTypeForURL const):
(WebCore::PluginData::supportsWebVisibleMimeType const):
* plugins/PluginData.h:

Source/WebKit:

Use API to check for plugin availability for response at navigation time.

* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::canShowResponse const):
(WebKit::WebPage::canShowMIMEType const):
* WebProcess/WebPage/WebPage.h:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/WKNavigationResponse.mm:
(TEST):

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

Source/WebCore/ChangeLog
Source/WebCore/plugins/PluginData.cpp
Source/WebCore/plugins/PluginData.h
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKNavigationResponse.mm

index 5ce29e2..e5f04ac 100644 (file)
@@ -1,3 +1,21 @@
+2018-04-20  Youenn Fablet  <youenn@apple.com>
+
+        WebPage sometimes incorrectly rules out PDF as a mime type that can be showed
+        https://bugs.webkit.org/show_bug.cgi?id=184369
+
+        Reviewed by Chris Dumez.
+
+        WebPage does need to check for plugins at reception of the response.
+        In that case, the page URL is the URL from which we are navigating out.
+        Add plugin API to check for plugin availability with an extra URL parameter to cover that case.
+
+        Covered by API test.
+
+        * plugins/PluginData.cpp:
+        (WebCore::PluginData::supportsWebVisibleMimeTypeForURL const):
+        (WebCore::PluginData::supportsWebVisibleMimeType const):
+        * plugins/PluginData.h:
+
 2018-04-20  Daniel Bates  <dabates@apple.com>
 
         Remove Strong Password decoration when text field type changes
index eeec241..b4662ca 100644 (file)
@@ -120,12 +120,23 @@ void PluginData::getMimesAndPluginIndiciesForPlugins(const Vector<PluginInfo>& p
     }
 }
 
+bool PluginData::supportsWebVisibleMimeTypeForURL(const String& mimeType, const AllowedPluginTypes allowedPluginTypes, const URL& url) const
+{
+    if (!protocolHostAndPortAreEqual(m_cachedVisiblePlugins.pageURL, url))
+        m_cachedVisiblePlugins = { url, m_page.pluginInfoProvider().webVisiblePluginInfo(m_page, url) };
+    return supportsWebVisibleMimeType(mimeType, allowedPluginTypes, *m_cachedVisiblePlugins.pluginList);
+}
+
 bool PluginData::supportsWebVisibleMimeType(const String& mimeType, const AllowedPluginTypes allowedPluginTypes) const
 {
+    return supportsWebVisibleMimeType(mimeType, allowedPluginTypes, webVisiblePlugins());
+}
+
+bool PluginData::supportsWebVisibleMimeType(const String& mimeType, const AllowedPluginTypes allowedPluginTypes, const Vector<PluginInfo>& plugins) const
+{
     Vector<MimeClassInfo> mimes;
     Vector<size_t> mimePluginIndices;
-    const Vector<PluginInfo>& plugins = webVisiblePlugins();
-    getWebVisibleMimesAndPluginIndices(mimes, mimePluginIndices);
+    getMimesAndPluginIndiciesForPlugins(plugins, mimes, mimePluginIndices);
 
     for (unsigned i = 0; i < mimes.size(); ++i) {
         if (mimes[i].type == mimeType && (allowedPluginTypes == AllPlugins || plugins[mimePluginIndices[i]].isApplicationPlugin))
index 5004606..167852d 100644 (file)
@@ -115,6 +115,7 @@ public:
     String pluginFileForWebVisibleMimeType(const String& mimeType) const;
 
     WEBCORE_EXPORT bool supportsMimeType(const String& mimeType, const AllowedPluginTypes) const;
+    WEBCORE_EXPORT bool supportsWebVisibleMimeTypeForURL(const String& mimeType, const AllowedPluginTypes, const URL&) const;
 
 private:
     explicit PluginData(Page&);
@@ -122,6 +123,7 @@ private:
     bool getPluginInfoForWebVisibleMimeType(const String& mimeType, PluginInfo&) const;
     void getMimesAndPluginIndices(Vector<MimeClassInfo>&, Vector<size_t>&) const;
     void getMimesAndPluginIndiciesForPlugins(const Vector<PluginInfo>&, Vector<MimeClassInfo>&, Vector<size_t>&) const;
+    bool supportsWebVisibleMimeType(const String& mimeType, const AllowedPluginTypes, const Vector<PluginInfo>&) const;
 
 protected:
     Page& m_page;
index 04637bb..fb4bec9 100644 (file)
@@ -1,3 +1,19 @@
+2018-04-20  Youenn Fablet  <youenn@apple.com>
+
+        WebPage sometimes incorrectly rules out PDF as a mime type that can be showed
+        https://bugs.webkit.org/show_bug.cgi?id=184369
+
+        Reviewed by Chris Dumez.
+
+        Use API to check for plugin availability for response at navigation time.
+
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::canShowResponse const):
+        (WebKit::WebPage::canShowMIMEType const):
+        * WebProcess/WebPage/WebPage.h:
+
 2018-04-20  Daniel Bates  <dabates@apple.com>
 
         Remove Strong Password decoration when text field type changes
index 74ac8b2..2700322 100644 (file)
@@ -749,7 +749,7 @@ void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceRespons
         return;
     }
 
-    bool canShowMIMEType = webPage->canShowMIMEType(response.mimeType());
+    bool canShowResponse = webPage->canShowResponse(response);
 
     WebCore::Frame* coreFrame = m_frame->coreFrame();
     auto* policyDocumentLoader = coreFrame ? coreFrame->loader().provisionalDocumentLoader() : nullptr;
@@ -757,7 +757,7 @@ void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceRespons
     
     Ref<WebFrame> protector(*m_frame);
     uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function), WebFrame::ForNavigationAction::No);
-    if (!webPage->send(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), navigationID, response, request, canShowMIMEType, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))))
+    if (!webPage->send(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), navigationID, response, request, canShowResponse, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))))
         m_frame->didReceivePolicyDecision(listenerID, PolicyAction::Ignore, 0, { }, { });
 }
 
index e328b26..00c5dc0 100644 (file)
@@ -5091,20 +5091,33 @@ void WebPage::setSelectTrailingWhitespaceEnabled(bool enabled)
     }
 }
 
-bool WebPage::canShowMIMEType(const String& MIMEType) const
+bool WebPage::canShowResponse(const WebCore::ResourceResponse& response) const
 {
-    if (MIMETypeRegistry::canShowMIMEType(MIMEType))
+    return canShowMIMEType(response.mimeType(), [&](auto& mimeType, auto allowedPlugins) {
+        return m_page->pluginData().supportsWebVisibleMimeTypeForURL(mimeType, allowedPlugins, response.url());
+    });
+}
+
+bool WebPage::canShowMIMEType(const String& mimeType) const
+{
+    return canShowMIMEType(mimeType, [&](auto& mimeType, auto allowedPlugins) {
+        return m_page->pluginData().supportsWebVisibleMimeType(mimeType, allowedPlugins);
+    });
+}
+
+bool WebPage::canShowMIMEType(const String& mimeType, const Function<bool(const String&, PluginData::AllowedPluginTypes)>& pluginsSupport) const
+{
+    if (MIMETypeRegistry::canShowMIMEType(mimeType))
         return true;
 
-    if (!MIMEType.isNull() && m_mimeTypesWithCustomContentProviders.contains(MIMEType))
+    if (!mimeType.isNull() && m_mimeTypesWithCustomContentProviders.contains(mimeType))
         return true;
 
-    const PluginData& pluginData = m_page->pluginData();
-    if (pluginData.supportsWebVisibleMimeType(MIMEType, PluginData::AllPlugins) && corePage()->mainFrame().loader().subframeLoader().allowPlugins())
+    if (corePage()->mainFrame().loader().subframeLoader().allowPlugins() && pluginsSupport(mimeType, PluginData::AllPlugins))
         return true;
 
     // We can use application plugins even if plugins aren't enabled.
-    if (pluginData.supportsWebVisibleMimeType(MIMEType, PluginData::OnlyApplicationPlugins))
+    if (pluginsSupport(mimeType, PluginData::OnlyApplicationPlugins))
         return true;
 
     return false;
index 0a81534..2de69ad 100644 (file)
@@ -57,6 +57,7 @@
 #include <WebCore/IntSizeHash.h>
 #include <WebCore/Page.h>
 #include <WebCore/PageOverlay.h>
+#include <WebCore/PluginData.h>
 #include <WebCore/UserActivity.h>
 #include <WebCore/UserContentTypes.h>
 #include <WebCore/UserInterfaceLayoutDirection.h>
@@ -954,6 +955,7 @@ public:
     std::optional<WebCore::IntSize> viewportSizeForCSSViewportUnits() const { return m_viewportSizeForCSSViewportUnits; }
 
     bool canShowMIMEType(const String& MIMEType) const;
+    bool canShowResponse(const WebCore::ResourceResponse&) const;
 
     void addTextCheckingRequest(uint64_t requestID, Ref<WebCore::TextCheckingRequest>&&);
     void didFinishCheckingText(uint64_t requestID, const Vector<WebCore::TextCheckingResult>&);
@@ -1412,6 +1414,8 @@ private:
     RefPtr<WebCore::HTMLAttachmentElement> attachmentElementWithIdentifier(const String& identifier) const;
 #endif
 
+    bool canShowMIMEType(const String&, const Function<bool(const String&, WebCore::PluginData::AllowedPluginTypes)>& supportsPlugin) const;
+
     uint64_t m_pageID;
 
     std::unique_ptr<WebCore::Page> m_page;
index 7da17f3..ec518db 100644 (file)
@@ -1,3 +1,13 @@
+2018-04-20  Youenn Fablet  <youenn@apple.com>
+
+        WebPage sometimes incorrectly rules out PDF as a mime type that can be showed
+        https://bugs.webkit.org/show_bug.cgi?id=184369
+
+        Reviewed by Chris Dumez.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKNavigationResponse.mm:
+        (TEST):
+
 2018-04-20  Daniel Bates  <dabates@apple.com>
 
         Remove Strong Password decoration when text field type changes
index 995ed86..f032bbe 100644 (file)
@@ -28,6 +28,7 @@
 #if WK_API_ENABLED
 
 #import "Utilities.h"
+#import <WebKit/WKProcessPoolPrivate.h>
 #import <WebKit/WebKit.h>
 #import <wtf/RetainPtr.h>
 
@@ -124,4 +125,24 @@ TEST(WebKit, WKNavigationResponseUnknownMIMEType)
     TestWebKitAPI::Util::run(&isDone);
 }
 
+TEST(WebKit, WKNavigationResponsePDFType)
+{
+    isDone = false;
+    auto schemeHandler = adoptNS([[WKNavigationResponseTestSchemeHandler alloc] init]);
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"test"];
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+    auto navigationDelegate = adoptNS([[WKNavigationResponseTestNavigationDelegate alloc] init]);
+    webView.get().navigationDelegate = navigationDelegate.get();
+
+    [[[webView configuration] processPool] _addSupportedPlugin: @"" named: @"WebKit built-in PDF" withMimeTypes: [NSSet setWithArray: @[ @"application/pdf" ]] withExtensions: [NSSet setWithArray: @[ ]]];
+
+    schemeHandler.get().mimeType = @"application/pdf";
+    navigationDelegate.get().expectation = YES;
+
+    NSURL *testURL = [NSURL URLWithString:@"test:///pdf-response"];
+    [webView loadRequest:[NSURLRequest requestWithURL:testURL]];
+    TestWebKitAPI::Util::run(&isDone);
+}
+
 #endif // WK_API_ENABLED