Title: [163226] trunk/Source/WebCore
- Revision
- 163226
- Author
- [email protected]
- Date
- 2014-01-31 17:40:44 -0800 (Fri, 31 Jan 2014)
Log Message
[Cocoa] Add NEFilterSource support to ContentFilterMac
https://bugs.webkit.org/show_bug.cgi?id=127979
Reviewed by Sam Weinig.
Update ContentFilterMac to work with both WebFilterEvaluator and
NEFilterSource, if enabled.
* platform/ContentFilter.h: Set HAVE_NE_FILTER_SOURCE based on platform
conditionals, and forward-declare NEFilterSource.
* platform/mac/ContentFilterMac.mm: Included NEFilterSource.h if the SDK
has it; declared the class directly if not. Also soft-linked
NetworkExtension.framework.
(WebCore::ContentFilter::ContentFilter): Initialized
m_neFilterSourceStatus to NEFilterSourceStatusNeedsMoreData and created
m_platformContentFilter and m_neFilterSource objects if their
respective filters were enabled.
(WebCore::ContentFilter::isEnabled): Returned true if either filter is
enabled.
(WebCore::ContentFilter::addData): Added incoming data to each filter
that is enabled.
(WebCore::ContentFilter::finishedAddingData): Notified each enabled
filter that we are finished adding data.
(WebCore::ContentFilter::needsMoreData): Returned true if either filter
needs more data.
(WebCore::ContentFilter::didBlockData): Returned true if either filter
blocked data.
(WebCore::ContentFilter::getReplacementData): Returned
m_replacementData. Commented that this will currently return a null
string if NEFilterSource blocked the load.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (163225 => 163226)
--- trunk/Source/WebCore/ChangeLog 2014-02-01 01:37:59 UTC (rev 163225)
+++ trunk/Source/WebCore/ChangeLog 2014-02-01 01:40:44 UTC (rev 163226)
@@ -1,3 +1,36 @@
+2014-01-30 Andy Estes <[email protected]>
+
+ [Cocoa] Add NEFilterSource support to ContentFilterMac
+ https://bugs.webkit.org/show_bug.cgi?id=127979
+
+ Reviewed by Sam Weinig.
+
+ Update ContentFilterMac to work with both WebFilterEvaluator and
+ NEFilterSource, if enabled.
+
+ * platform/ContentFilter.h: Set HAVE_NE_FILTER_SOURCE based on platform
+ conditionals, and forward-declare NEFilterSource.
+ * platform/mac/ContentFilterMac.mm: Included NEFilterSource.h if the SDK
+ has it; declared the class directly if not. Also soft-linked
+ NetworkExtension.framework.
+ (WebCore::ContentFilter::ContentFilter): Initialized
+ m_neFilterSourceStatus to NEFilterSourceStatusNeedsMoreData and created
+ m_platformContentFilter and m_neFilterSource objects if their
+ respective filters were enabled.
+ (WebCore::ContentFilter::isEnabled): Returned true if either filter is
+ enabled.
+ (WebCore::ContentFilter::addData): Added incoming data to each filter
+ that is enabled.
+ (WebCore::ContentFilter::finishedAddingData): Notified each enabled
+ filter that we are finished adding data.
+ (WebCore::ContentFilter::needsMoreData): Returned true if either filter
+ needs more data.
+ (WebCore::ContentFilter::didBlockData): Returned true if either filter
+ blocked data.
+ (WebCore::ContentFilter::getReplacementData): Returned
+ m_replacementData. Commented that this will currently return a null
+ string if NEFilterSource blocked the load.
+
2014-01-31 Oliver Hunt <[email protected]>
Rollout r163195 and related patches
Modified: trunk/Source/WebCore/platform/ContentFilter.h (163225 => 163226)
--- trunk/Source/WebCore/platform/ContentFilter.h 2014-02-01 01:37:59 UTC (rev 163225)
+++ trunk/Source/WebCore/platform/ContentFilter.h 2014-02-01 01:40:44 UTC (rev 163226)
@@ -29,8 +29,8 @@
#if USE(CONTENT_FILTERING)
#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
#include <wtf/RetainPtr.h>
+#include <wtf/ThreadSafeRefCounted.h>
#if PLATFORM(IOS)
#include <wtf/Functional.h>
@@ -40,15 +40,25 @@
OBJC_CLASS WebFilterEvaluator;
#endif
+#define HAVE_NE_FILTER_SOURCE TARGET_OS_EMBEDDED || (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 10100)
+
+#if HAVE(NE_FILTER_SOURCE)
+#import <atomic>
+#import <dispatch/dispatch.h>
+OBJC_CLASS NEFilterSource;
+#endif
+
namespace WebCore {
class ResourceResponse;
-class ContentFilter : public RefCounted<ContentFilter> {
+class ContentFilter : public ThreadSafeRefCounted<ContentFilter> {
public:
static PassRefPtr<ContentFilter> create(const ResourceResponse&);
static bool isEnabled();
-
+
+ virtual ~ContentFilter();
+
void addData(const char* data, int length);
void finishedAddingData();
bool needsMoreData() const;
@@ -67,6 +77,13 @@
RetainPtr<WebFilterEvaluator> m_platformContentFilter;
RetainPtr<NSData> m_replacementData;
#endif
+
+#if HAVE(NE_FILTER_SOURCE)
+ std::atomic<long> m_neFilterSourceStatus;
+ RetainPtr<NEFilterSource> m_neFilterSource;
+ dispatch_queue_t m_neFilterSourceQueue;
+ dispatch_semaphore_t m_neFilterSourceSemaphore;
+#endif
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/mac/ContentFilterMac.mm (163225 => 163226)
--- trunk/Source/WebCore/platform/mac/ContentFilterMac.mm 2014-02-01 01:37:59 UTC (rev 163225)
+++ trunk/Source/WebCore/platform/mac/ContentFilterMac.mm 2014-02-01 01:40:44 UTC (rev 163226)
@@ -49,6 +49,40 @@
SOFT_LINK_PRIVATE_FRAMEWORK(WebContentAnalysis);
SOFT_LINK_CLASS(WebContentAnalysis, WebFilterEvaluator);
+#if HAVE(NE_FILTER_SOURCE)
+
+#if defined(__has_include) && __has_include(<NetworkExtension/NEFilterSource.h>)
+#import <NetworkExtension/NEFilterSource.h>
+#else
+typedef NS_ENUM(NSInteger, NEFilterSourceStatus) {
+ NEFilterSourceStatusPass = 1,
+ NEFilterSourceStatusBlock = 2,
+ NEFilterSourceStatusNeedsMoreData = 3,
+ NEFilterSourceStatusError = 4,
+};
+
+typedef NS_ENUM(NSInteger, NEFilterSourceDirection) {
+ NEFilterSourceDirectionOutbound = 1,
+ NEFilterSourceDirectionInbound = 2,
+};
+
+@interface NEFilterSource : NSObject
++ (BOOL)filterRequired;
+- (id)initWithURL:(NSURL *)url direction:(NEFilterSourceDirection)direction socketIdentifier:(uint64_t)socketIdentifier;
+- (void)addData:(NSData *)data withCompletionQueue:(dispatch_queue_t)queue completionHandler:(void (^)(NEFilterSourceStatus, NSData *))completionHandler;
+- (void)dataCompleteWithCompletionQueue:(dispatch_queue_t)queue completionHandler:(void (^)(NEFilterSourceStatus, NSData *))completionHandler;
+@property (readonly) NEFilterSourceStatus status;
+@property (readonly) NSURL *url;
+@property (readonly) NEFilterSourceDirection direction;
+@property (readonly) uint64_t socketIdentifier;
+@end
+#endif
+
+SOFT_LINK_FRAMEWORK(NetworkExtension);
+SOFT_LINK_CLASS(NetworkExtension, NEFilterSource);
+
+#endif // HAVE(NE_FILTER_SOURCE)
+
namespace WebCore {
PassRefPtr<ContentFilter> ContentFilter::create(const ResourceResponse& response)
@@ -57,47 +91,116 @@
}
ContentFilter::ContentFilter(const ResourceResponse& response)
- : m_platformContentFilter(adoptNS([[getWebFilterEvaluatorClass() alloc] initWithResponse:response.nsURLResponse()]))
+#if HAVE(NE_FILTER_SOURCE)
+ : m_neFilterSourceStatus(NEFilterSourceStatusNeedsMoreData)
+#endif
{
- ASSERT(m_platformContentFilter);
+ if ([getWebFilterEvaluatorClass() isManagedSession])
+ m_platformContentFilter = adoptNS([[getWebFilterEvaluatorClass() alloc] initWithResponse:response.nsURLResponse()]);
+
+#if HAVE(NE_FILTER_SOURCE)
+ if ([getNEFilterSourceClass() filterRequired]) {
+ m_neFilterSource = adoptNS([[getNEFilterSourceClass() alloc] initWithURL:[response.nsURLResponse() URL] direction:NEFilterSourceDirectionInbound socketIdentifier:0]);
+ m_neFilterSourceQueue = dispatch_queue_create("com.apple.WebCore.NEFilterSourceQueue", DISPATCH_QUEUE_SERIAL);
+ }
+#endif
}
+ContentFilter::~ContentFilter()
+{
+#if HAVE(NE_FILTER_SOURCE)
+ dispatch_release(m_neFilterSourceQueue);
+#endif
+}
+
bool ContentFilter::isEnabled()
{
- return [getWebFilterEvaluatorClass() isManagedSession];
+ return [getWebFilterEvaluatorClass() isManagedSession]
+#if HAVE(NE_FILTER_SOURCE)
+ || [getNEFilterSourceClass() filterRequired]
+#endif
+ ;
}
void ContentFilter::addData(const char* data, int length)
{
ASSERT(needsMoreData());
- ASSERT(![m_replacementData.get() length]);
- m_replacementData = [m_platformContentFilter addData:[NSData dataWithBytesNoCopy:(void*)data length:length freeWhenDone:NO]];
- ASSERT(needsMoreData() || [m_replacementData.get() length]);
+
+ if (m_platformContentFilter) {
+ ASSERT(![m_replacementData.get() length]);
+ m_replacementData = [m_platformContentFilter addData:[NSData dataWithBytesNoCopy:(void*)data length:length freeWhenDone:NO]];
+ ASSERT(needsMoreData() || [m_replacementData.get() length]);
+ }
+
+#if HAVE(NE_FILTER_SOURCE)
+ if (!m_neFilterSource)
+ return;
+
+ ref();
+ [m_neFilterSource addData:[NSData dataWithBytesNoCopy:(void*)data length:length freeWhenDone:NO] withCompletionQueue:m_neFilterSourceQueue completionHandler:^(NEFilterSourceStatus status, NSData *) {
+ m_neFilterSourceStatus = status;
+ deref();
+ }];
+#endif
}
void ContentFilter::finishedAddingData()
{
ASSERT(needsMoreData());
- ASSERT(![m_replacementData.get() length]);
- m_replacementData = [m_platformContentFilter dataComplete];
+
+ if (m_platformContentFilter) {
+ ASSERT(![m_replacementData.get() length]);
+ m_replacementData = [m_platformContentFilter dataComplete];
+ }
+
+#if HAVE(NE_FILTER_SOURCE)
+ if (!m_neFilterSource)
+ return;
+
+ ref();
+ m_neFilterSourceSemaphore = dispatch_semaphore_create(0);
+ [m_neFilterSource dataCompleteWithCompletionQueue:m_neFilterSourceQueue completionHandler:^(NEFilterSourceStatus status, NSData *) {
+ m_neFilterSourceStatus = status;
+ deref();
+
+ dispatch_semaphore_signal(m_neFilterSourceSemaphore);
+ }];
+
+ // FIXME: We have to block here since DocumentLoader expects to have a
+ // blocked/not blocked answer from the filter immediately after calling
+ // finishedAddingData(). We should find a way to make this asynchronous.
+ dispatch_semaphore_wait(m_neFilterSourceSemaphore, DISPATCH_TIME_FOREVER);
+ dispatch_release(m_neFilterSourceSemaphore);
+#endif
+
ASSERT(!needsMoreData());
}
bool ContentFilter::needsMoreData() const
{
- return [m_platformContentFilter filterState] == kWFEStateBuffering;
+ return [m_platformContentFilter filterState] == kWFEStateBuffering
+#if HAVE(NE_FILTER_SOURCE)
+ || m_neFilterSourceStatus == NEFilterSourceStatusNeedsMoreData
+#endif
+ ;
}
bool ContentFilter::didBlockData() const
{
- return [m_platformContentFilter wasBlocked];
+ return [m_platformContentFilter wasBlocked]
+#if HAVE(NE_FILTER_SOURCE)
+ || m_neFilterSourceStatus == NEFilterSourceStatusBlock
+#endif
+ ;
}
const char* ContentFilter::getReplacementData(int& length) const
{
+ // FIXME: This will return a null pointer with length 0 when using
+ // NEFilterSource. We need to show a proper error page instead.
ASSERT(!needsMoreData());
- length = [m_replacementData.get() length];
- return static_cast<const char*>([m_replacementData.get() bytes]);
+ length = [m_replacementData length];
+ return static_cast<const char*>([m_replacementData bytes]);
}
} // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes