<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[181523] trunk/Source/WebCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/181523">181523</a></dd>
<dt>Author</dt> <dd>aestes@apple.com</dd>
<dt>Date</dt> <dd>2015-03-15 22:44:03 -0700 (Sun, 15 Mar 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>[Content Filtering] Adopt new NEFilterSource SPI
https://bugs.webkit.org/show_bug.cgi?id=142710
rdar://problem/19023855
Reviewed by Dan Bernstein.
Teach NetworkExtensionContentFilter to use a new, alternate NEFilterSource SPI on platforms where it is available.
* platform/ContentFilter.cpp:
(WebCore::ContentFilter::types): Renamed HAVE(NE_FILTER_SOURCE) to HAVE(NETWORK_EXTENSION).
* platform/cocoa/NetworkExtensionContentFilter.h: Renamed member variables to remove redundancy, forward-declared NEFilterSourceStatus,
added a dispatch_semaphore member variable to avoid creating and destroying multiple semaphores, and made m_originalData a SharedBuffer.
* platform/cocoa/NetworkExtensionContentFilter.mm:
(decisionInfoReplacementData): Returned the replacement data from a decision handler info dictionary.
(WebCore::createNEFilterSource): Created either an old-style or new-style NEFilterSource object.
(WebCore::NetworkExtensionContentFilter::NetworkExtensionContentFilter): Called receivedResponse:decisionHandler: when using the new SPI.
(WebCore::NetworkExtensionContentFilter::~NetworkExtensionContentFilter): Released the dispatch_semaphore.
(WebCore::NetworkExtensionContentFilter::addData): Appended the copied NSData to m_originalData, avoiding an additional copy previously
being made by NSMutableData. Used the new receivedData:decisionHandler: SPI when appropriate.
(WebCore::NetworkExtensionContentFilter::finishedAddingData): Used the new finishedLoadingWithDecisionHandler: SPI when appropriate.
(WebCore::NetworkExtensionContentFilter::needsMoreData): Changed m_neFilterSourceStatus to m_status.
(WebCore::NetworkExtensionContentFilter::didBlockData): Ditto.
(WebCore::NetworkExtensionContentFilter::getReplacementData): Returned the replacement data from NEFilterSource if the load was blocked.
Otherwise, returned the original data.
(WebCore::NetworkExtensionContentFilter::handleDecision): Added a helper to set m_status and m_replacementData, and to signal m_semaphore.
* platform/spi/cocoa/NEFilterSourceSPI.h: Declared the new NEFilterSource SPI on platforms that support it.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformContentFiltercpp">trunk/Source/WebCore/platform/ContentFilter.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformcocoaNetworkExtensionContentFilterh">trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.h</a></li>
<li><a href="#trunkSourceWebCoreplatformcocoaNetworkExtensionContentFiltermm">trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformspicocoaNEFilterSourceSPIh">trunk/Source/WebCore/platform/spi/cocoa/NEFilterSourceSPI.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (181522 => 181523)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-03-16 05:34:27 UTC (rev 181522)
+++ trunk/Source/WebCore/ChangeLog        2015-03-16 05:44:03 UTC (rev 181523)
</span><span class="lines">@@ -1,3 +1,32 @@
</span><ins>+2015-03-15 Andy Estes <aestes@apple.com>
+
+ [Content Filtering] Adopt new NEFilterSource SPI
+ https://bugs.webkit.org/show_bug.cgi?id=142710
+ rdar://problem/19023855
+
+ Reviewed by Dan Bernstein.
+
+ Teach NetworkExtensionContentFilter to use a new, alternate NEFilterSource SPI on platforms where it is available.
+
+ * platform/ContentFilter.cpp:
+ (WebCore::ContentFilter::types): Renamed HAVE(NE_FILTER_SOURCE) to HAVE(NETWORK_EXTENSION).
+ * platform/cocoa/NetworkExtensionContentFilter.h: Renamed member variables to remove redundancy, forward-declared NEFilterSourceStatus,
+ added a dispatch_semaphore member variable to avoid creating and destroying multiple semaphores, and made m_originalData a SharedBuffer.
+ * platform/cocoa/NetworkExtensionContentFilter.mm:
+ (decisionInfoReplacementData): Returned the replacement data from a decision handler info dictionary.
+ (WebCore::createNEFilterSource): Created either an old-style or new-style NEFilterSource object.
+ (WebCore::NetworkExtensionContentFilter::NetworkExtensionContentFilter): Called receivedResponse:decisionHandler: when using the new SPI.
+ (WebCore::NetworkExtensionContentFilter::~NetworkExtensionContentFilter): Released the dispatch_semaphore.
+ (WebCore::NetworkExtensionContentFilter::addData): Appended the copied NSData to m_originalData, avoiding an additional copy previously
+ being made by NSMutableData. Used the new receivedData:decisionHandler: SPI when appropriate.
+ (WebCore::NetworkExtensionContentFilter::finishedAddingData): Used the new finishedLoadingWithDecisionHandler: SPI when appropriate.
+ (WebCore::NetworkExtensionContentFilter::needsMoreData): Changed m_neFilterSourceStatus to m_status.
+ (WebCore::NetworkExtensionContentFilter::didBlockData): Ditto.
+ (WebCore::NetworkExtensionContentFilter::getReplacementData): Returned the replacement data from NEFilterSource if the load was blocked.
+ Otherwise, returned the original data.
+ (WebCore::NetworkExtensionContentFilter::handleDecision): Added a helper to set m_status and m_replacementData, and to signal m_semaphore.
+ * platform/spi/cocoa/NEFilterSourceSPI.h: Declared the new NEFilterSource SPI on platforms that support it.
+
</ins><span class="cx"> 2015-03-15 Brent Fulgham <bfulgham@apple.com>
</span><span class="cx">
</span><span class="cx"> Scroll snap points are not supported on iframe content
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformContentFiltercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ContentFilter.cpp (181522 => 181523)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ContentFilter.cpp        2015-03-16 05:34:27 UTC (rev 181522)
+++ trunk/Source/WebCore/platform/ContentFilter.cpp        2015-03-16 05:44:03 UTC (rev 181523)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> static NeverDestroyed<Vector<ContentFilter::Type>> types {
</span><span class="cx"> Vector<ContentFilter::Type> {
</span><span class="cx"> type<ParentalControlsContentFilter>(),
</span><del>-#if HAVE(NE_FILTER_SOURCE)
</del><ins>+#if HAVE(NETWORK_EXTENSION)
</ins><span class="cx"> type<NetworkExtensionContentFilter>()
</span><span class="cx"> #endif
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcocoaNetworkExtensionContentFilterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.h (181522 => 181523)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.h        2015-03-16 05:34:27 UTC (rev 181522)
+++ trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.h        2015-03-16 05:44:03 UTC (rev 181523)
</span><span class="lines">@@ -27,12 +27,20 @@
</span><span class="cx"> #define NetworkExtensionContentFilter_h
</span><span class="cx">
</span><span class="cx"> #include "ContentFilter.h"
</span><ins>+#include "SharedBuffer.h"
+#include <objc/NSObjCRuntime.h>
</ins><span class="cx"> #include <wtf/Compiler.h>
</span><ins>+#include <wtf/OSObjectPtr.h>
+#include <wtf/Ref.h>
</ins><span class="cx"> #include <wtf/RetainPtr.h>
</span><span class="cx">
</span><del>-#define HAVE_NE_FILTER_SOURCE TARGET_OS_EMBEDDED || (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 && CPU(X86_64))
</del><ins>+#define HAVE_NETWORK_EXTENSION PLATFORM(IOS) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 && CPU(X86_64))
</ins><span class="cx">
</span><ins>+enum NEFilterSourceStatus : NSInteger;
+
</ins><span class="cx"> OBJC_CLASS NEFilterSource;
</span><ins>+OBJC_CLASS NSData;
+OBJC_CLASS NSDictionary;
</ins><span class="cx"> OBJC_CLASS NSMutableData;
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -46,7 +54,6 @@
</span><span class="cx"> static bool canHandleResponse(const ResourceResponse&);
</span><span class="cx"> static std::unique_ptr<NetworkExtensionContentFilter> create(const ResourceResponse&);
</span><span class="cx">
</span><del>- ~NetworkExtensionContentFilter() override;
</del><span class="cx"> void addData(const char* data, int length) override;
</span><span class="cx"> void finishedAddingData() override;
</span><span class="cx"> bool needsMoreData() const override;
</span><span class="lines">@@ -56,11 +63,14 @@
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> explicit NetworkExtensionContentFilter(const ResourceResponse&);
</span><ins>+ void handleDecision(NEFilterSourceStatus, NSData *replacementData);
</ins><span class="cx">
</span><del>- long m_neFilterSourceStatus;
</del><ins>+ NEFilterSourceStatus m_status;
+ OSObjectPtr<dispatch_queue_t> m_queue;
+ OSObjectPtr<dispatch_semaphore_t> m_semaphore;
+ Ref<SharedBuffer> m_originalData;
+ RetainPtr<NSData> m_replacementData;
</ins><span class="cx"> RetainPtr<NEFilterSource> m_neFilterSource;
</span><del>- dispatch_queue_t m_neFilterSourceQueue;
- RetainPtr<NSMutableData> m_originalData;
</del><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcocoaNetworkExtensionContentFiltermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm (181522 => 181523)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm        2015-03-16 05:34:27 UTC (rev 181522)
+++ trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm        2015-03-16 05:44:03 UTC (rev 181523)
</span><span class="lines">@@ -26,7 +26,7 @@
</span><span class="cx"> #import "config.h"
</span><span class="cx"> #import "NetworkExtensionContentFilter.h"
</span><span class="cx">
</span><del>-#if HAVE(NE_FILTER_SOURCE)
</del><ins>+#if HAVE(NETWORK_EXTENSION)
</ins><span class="cx">
</span><span class="cx"> #import "NEFilterSourceSPI.h"
</span><span class="cx"> #import "ResourceResponse.h"
</span><span class="lines">@@ -36,6 +36,18 @@
</span><span class="cx"> SOFT_LINK_FRAMEWORK(NetworkExtension);
</span><span class="cx"> SOFT_LINK_CLASS(NetworkExtension, NEFilterSource);
</span><span class="cx">
</span><ins>+#if HAVE(MODERN_NE_FILTER_SOURCE)
+// FIXME: <rdar://problem/20165664> Expose decisionHandler dictionary keys as NSString constants in NEFilterSource.h
+static NSString * const optionsPageData = @"PageData";
+
+static inline NSData *replacementDataFromDecisionInfo(NSDictionary *decisionInfo)
+{
+ id replacementData = decisionInfo[optionsPageData];
+ ASSERT(!replacementData || [replacementData isKindOfClass:[NSData class]]);
+ return replacementData;
+}
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> bool NetworkExtensionContentFilter::canHandleResponse(const ResourceResponse& response)
</span><span class="lines">@@ -48,80 +60,103 @@
</span><span class="cx"> return std::make_unique<NetworkExtensionContentFilter>(response);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+static inline RetainPtr<NEFilterSource> createNEFilterSource(const URL& url, dispatch_queue_t decisionQueue)
+{
+#if HAVE(MODERN_NE_FILTER_SOURCE)
+ UNUSED_PARAM(url);
+ return adoptNS([allocNEFilterSourceInstance() initWithDecisionQueue:decisionQueue]);
+#else
+ UNUSED_PARAM(decisionQueue);
+ return adoptNS([allocNEFilterSourceInstance() initWithURL:url direction:NEFilterSourceDirectionInbound socketIdentifier:0]);
+#endif
+}
+
</ins><span class="cx"> NetworkExtensionContentFilter::NetworkExtensionContentFilter(const ResourceResponse& response)
</span><del>- : m_neFilterSourceStatus { NEFilterSourceStatusNeedsMoreData }
- , m_neFilterSource { adoptNS([allocNEFilterSourceInstance() initWithURL:[response.nsURLResponse() URL] direction:NEFilterSourceDirectionInbound socketIdentifier:0]) }
- , m_neFilterSourceQueue { dispatch_queue_create("com.apple.WebCore.NEFilterSourceQueue", DISPATCH_QUEUE_SERIAL) }
</del><ins>+ : m_status { NEFilterSourceStatusNeedsMoreData }
+ , m_queue { adoptOSObject(dispatch_queue_create("com.apple.WebCore.NEFilterSourceQueue", DISPATCH_QUEUE_SERIAL)) }
+ , m_semaphore { adoptOSObject(dispatch_semaphore_create(0)) }
+ , m_originalData { *SharedBuffer::create() }
+ , m_neFilterSource { createNEFilterSource(response.url(), m_queue.get()) }
</ins><span class="cx"> {
</span><span class="cx"> ASSERT([getNEFilterSourceClass() filterRequired]);
</span><span class="cx">
</span><del>- long long expectedContentSize = [response.nsURLResponse() expectedContentLength];
- if (expectedContentSize < 0)
- m_originalData = adoptNS([[NSMutableData alloc] init]);
- else
- m_originalData = adoptNS([[NSMutableData alloc] initWithCapacity:(NSUInteger)expectedContentSize]);
-}
</del><ins>+#if HAVE(MODERN_NE_FILTER_SOURCE)
+ [m_neFilterSource receivedResponse:response.nsURLResponse() decisionHandler:[this](NEFilterSourceStatus status, NSDictionary *decisionInfo) {
+ handleDecision(status, replacementDataFromDecisionInfo(decisionInfo));
+ }];
</ins><span class="cx">
</span><del>-NetworkExtensionContentFilter::~NetworkExtensionContentFilter()
-{
- dispatch_release(m_neFilterSourceQueue);
</del><ins>+ // FIXME: We have to block here since DocumentLoader expects to have a
+ // blocked/not blocked answer from the filter immediately after calling
+ // addData(). We should find a way to make this asynchronous.
+ dispatch_semaphore_wait(m_semaphore.get(), DISPATCH_TIME_FOREVER);
+#endif
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void NetworkExtensionContentFilter::addData(const char* data, int length)
</span><span class="cx"> {
</span><ins>+ RetainPtr<NSData> copiedData { [NSData dataWithBytes:(void*)data length:length] };
+
</ins><span class="cx"> // FIXME: NEFilterSource doesn't buffer data like WebFilterEvaluator does,
</span><span class="cx"> // so we need to do it ourselves so getReplacementData() can return the
</span><span class="cx"> // original bytes back to the loader. We should find a way to remove this
</span><span class="cx"> // additional copy.
</span><del>- [m_originalData appendBytes:data length:length];
</del><ins>+ m_originalData->append((CFDataRef)copiedData.get());
</ins><span class="cx">
</span><del>- dispatch_semaphore_t neFilterSourceSemaphore = dispatch_semaphore_create(0);
- [m_neFilterSource addData:[NSData dataWithBytes:(void*)data length:length] withCompletionQueue:m_neFilterSourceQueue completionHandler:^(NEFilterSourceStatus status, NSData *) {
- m_neFilterSourceStatus = status;
- dispatch_semaphore_signal(neFilterSourceSemaphore);
</del><ins>+#if HAVE(MODERN_NE_FILTER_SOURCE)
+ [m_neFilterSource receivedData:copiedData.get() decisionHandler:[this](NEFilterSourceStatus status, NSDictionary *decisionInfo) {
+ handleDecision(status, replacementDataFromDecisionInfo(decisionInfo));
</ins><span class="cx"> }];
</span><ins>+#else
+ [m_neFilterSource addData:copiedData.get() withCompletionQueue:m_queue.get() completionHandler:[this](NEFilterSourceStatus status, NSData *replacementData) {
+ ASSERT(!replacementData);
+ handleDecision(status, replacementData);
+ }];
+#endif
</ins><span class="cx">
</span><span class="cx"> // FIXME: We have to block here since DocumentLoader expects to have a
</span><span class="cx"> // blocked/not blocked answer from the filter immediately after calling
</span><span class="cx"> // addData(). We should find a way to make this asynchronous.
</span><del>- dispatch_semaphore_wait(neFilterSourceSemaphore, DISPATCH_TIME_FOREVER);
- dispatch_release(neFilterSourceSemaphore);
</del><ins>+ dispatch_semaphore_wait(m_semaphore.get(), DISPATCH_TIME_FOREVER);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void NetworkExtensionContentFilter::finishedAddingData()
</span><span class="cx"> {
</span><del>- dispatch_semaphore_t neFilterSourceSemaphore = dispatch_semaphore_create(0);
- [m_neFilterSource dataCompleteWithCompletionQueue:m_neFilterSourceQueue completionHandler:^(NEFilterSourceStatus status, NSData *) {
- m_neFilterSourceStatus = status;
- dispatch_semaphore_signal(neFilterSourceSemaphore);
</del><ins>+#if HAVE(MODERN_NE_FILTER_SOURCE)
+ [m_neFilterSource finishedLoadingWithDecisionHandler:[this](NEFilterSourceStatus status, NSDictionary *decisionInfo) {
+ handleDecision(status, replacementDataFromDecisionInfo(decisionInfo));
</ins><span class="cx"> }];
</span><ins>+#else
+ [m_neFilterSource dataCompleteWithCompletionQueue:m_queue.get() completionHandler:[this](NEFilterSourceStatus status, NSData *replacementData) {
+ ASSERT(!replacementData);
+ handleDecision(status, replacementData);
+ }];
+#endif
</ins><span class="cx">
</span><span class="cx"> // FIXME: We have to block here since DocumentLoader expects to have a
</span><span class="cx"> // blocked/not blocked answer from the filter immediately after calling
</span><span class="cx"> // finishedAddingData(). We should find a way to make this asynchronous.
</span><del>- dispatch_semaphore_wait(neFilterSourceSemaphore, DISPATCH_TIME_FOREVER);
- dispatch_release(neFilterSourceSemaphore);
</del><ins>+ dispatch_semaphore_wait(m_semaphore.get(), DISPATCH_TIME_FOREVER);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool NetworkExtensionContentFilter::needsMoreData() const
</span><span class="cx"> {
</span><del>- return m_neFilterSourceStatus == NEFilterSourceStatusNeedsMoreData;
</del><ins>+ return m_status == NEFilterSourceStatusNeedsMoreData;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool NetworkExtensionContentFilter::didBlockData() const
</span><span class="cx"> {
</span><del>- return m_neFilterSourceStatus == NEFilterSourceStatusBlock;
</del><ins>+ return m_status == NEFilterSourceStatusBlock;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> const char* NetworkExtensionContentFilter::getReplacementData(int& length) const
</span><span class="cx"> {
</span><span class="cx"> if (didBlockData()) {
</span><del>- length = 0;
- return nullptr;
</del><ins>+ length = [m_replacementData length];
+ return static_cast<const char*>([m_replacementData bytes]);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- length = [m_originalData length];
- return static_cast<const char*>([m_originalData bytes]);
</del><ins>+ length = m_originalData->size();
+ return m_originalData->data();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> ContentFilterUnblockHandler NetworkExtensionContentFilter::unblockHandler() const
</span><span class="lines">@@ -129,6 +164,14 @@
</span><span class="cx"> return { };
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void NetworkExtensionContentFilter::handleDecision(NEFilterSourceStatus status, NSData *replacementData)
+{
+ m_status = status;
+ if (status == NEFilterSourceStatusBlock)
+ m_replacementData = replacementData;
+ dispatch_semaphore_signal(m_semaphore.get());
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><del>-#endif // HAVE(NE_FILTER_SOURCE)
</del><ins>+#endif // HAVE(NETWORK_EXTENSION)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformspicocoaNEFilterSourceSPIh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/spi/cocoa/NEFilterSourceSPI.h (181522 => 181523)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/spi/cocoa/NEFilterSourceSPI.h        2015-03-16 05:34:27 UTC (rev 181522)
+++ trunk/Source/WebCore/platform/spi/cocoa/NEFilterSourceSPI.h        2015-03-16 05:44:03 UTC (rev 181523)
</span><span class="lines">@@ -23,6 +23,8 @@
</span><span class="cx"> * THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> */
</span><span class="cx">
</span><ins>+#define HAVE_MODERN_NE_FILTER_SOURCE (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000)
+
</ins><span class="cx"> #if USE(APPLE_INTERNAL_SDK)
</span><span class="cx">
</span><span class="cx"> #import <NetworkExtension/NEFilterSource.h>
</span><span class="lines">@@ -44,7 +46,7 @@
</span><span class="cx"> @interface NEFilterSource : NSObject
</span><span class="cx"> @end
</span><span class="cx">
</span><del>-@interface NEFilterSource (Details)
</del><ins>+@interface NEFilterSource (WKLegacyDetails)
</ins><span class="cx"> + (BOOL)filterRequired;
</span><span class="cx"> - (id)initWithURL:(NSURL *)url direction:(NEFilterSourceDirection)direction socketIdentifier:(uint64_t)socketIdentifier;
</span><span class="cx"> - (void)addData:(NSData *)data withCompletionQueue:(dispatch_queue_t)queue completionHandler:(void (^)(NEFilterSourceStatus, NSData *))completionHandler;
</span><span class="lines">@@ -55,4 +57,17 @@
</span><span class="cx"> @property (readonly) uint64_t socketIdentifier;
</span><span class="cx"> @end
</span><span class="cx">
</span><ins>+#if HAVE(MODERN_NE_FILTER_SOURCE)
+typedef void (^NEFilterSourceDecisionHandler)(NEFilterSourceStatus, NSDictionary *);
+
+@interface NEFilterSource (WKModernDetails)
+- (id)initWithDecisionQueue:(dispatch_queue_t)queue;
+- (void)willSendRequest:(NSURLRequest *)request decisionHandler:(NEFilterSourceDecisionHandler)decisionHandler;
+- (void)receivedResponse:(NSURLResponse *)response decisionHandler:(NEFilterSourceDecisionHandler)decisionHandler;
+- (void)receivedData:(NSData *)data decisionHandler:(NEFilterSourceDecisionHandler)decisionHandler;
+- (void)finishedLoadingWithDecisionHandler:(NEFilterSourceDecisionHandler)decisionHandler;
+- (void)remediateWithDecisionHandler:(NEFilterSourceDecisionHandler)decisionHandler;
+@end
</ins><span class="cx"> #endif
</span><ins>+
+#endif
</ins></span></pre>
</div>
</div>
</body>
</html>