Changeset 181523 in webkit
- Timestamp:
- Mar 15, 2015, 10:44:03 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
-
ChangeLog (modified) (1 diff)
-
platform/ContentFilter.cpp (modified) (1 diff)
-
platform/cocoa/NetworkExtensionContentFilter.h (modified) (3 diffs)
-
platform/cocoa/NetworkExtensionContentFilter.mm (modified) (6 diffs)
-
platform/spi/cocoa/NEFilterSourceSPI.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r181522 r181523 1 2015-03-15 Andy Estes <aestes@apple.com> 2 3 [Content Filtering] Adopt new NEFilterSource SPI 4 https://bugs.webkit.org/show_bug.cgi?id=142710 5 rdar://problem/19023855 6 7 Reviewed by Dan Bernstein. 8 9 Teach NetworkExtensionContentFilter to use a new, alternate NEFilterSource SPI on platforms where it is available. 10 11 * platform/ContentFilter.cpp: 12 (WebCore::ContentFilter::types): Renamed HAVE(NE_FILTER_SOURCE) to HAVE(NETWORK_EXTENSION). 13 * platform/cocoa/NetworkExtensionContentFilter.h: Renamed member variables to remove redundancy, forward-declared NEFilterSourceStatus, 14 added a dispatch_semaphore member variable to avoid creating and destroying multiple semaphores, and made m_originalData a SharedBuffer. 15 * platform/cocoa/NetworkExtensionContentFilter.mm: 16 (decisionInfoReplacementData): Returned the replacement data from a decision handler info dictionary. 17 (WebCore::createNEFilterSource): Created either an old-style or new-style NEFilterSource object. 18 (WebCore::NetworkExtensionContentFilter::NetworkExtensionContentFilter): Called receivedResponse:decisionHandler: when using the new SPI. 19 (WebCore::NetworkExtensionContentFilter::~NetworkExtensionContentFilter): Released the dispatch_semaphore. 20 (WebCore::NetworkExtensionContentFilter::addData): Appended the copied NSData to m_originalData, avoiding an additional copy previously 21 being made by NSMutableData. Used the new receivedData:decisionHandler: SPI when appropriate. 22 (WebCore::NetworkExtensionContentFilter::finishedAddingData): Used the new finishedLoadingWithDecisionHandler: SPI when appropriate. 23 (WebCore::NetworkExtensionContentFilter::needsMoreData): Changed m_neFilterSourceStatus to m_status. 24 (WebCore::NetworkExtensionContentFilter::didBlockData): Ditto. 25 (WebCore::NetworkExtensionContentFilter::getReplacementData): Returned the replacement data from NEFilterSource if the load was blocked. 26 Otherwise, returned the original data. 27 (WebCore::NetworkExtensionContentFilter::handleDecision): Added a helper to set m_status and m_replacementData, and to signal m_semaphore. 28 * platform/spi/cocoa/NEFilterSourceSPI.h: Declared the new NEFilterSource SPI on platforms that support it. 29 1 30 2015-03-15 Brent Fulgham <bfulgham@apple.com> 2 31 -
trunk/Source/WebCore/platform/ContentFilter.cpp
r181291 r181523 41 41 Vector<ContentFilter::Type> { 42 42 type<ParentalControlsContentFilter>(), 43 #if HAVE(NE _FILTER_SOURCE)43 #if HAVE(NETWORK_EXTENSION) 44 44 type<NetworkExtensionContentFilter>() 45 45 #endif -
trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.h
r181302 r181523 28 28 29 29 #include "ContentFilter.h" 30 #include "SharedBuffer.h" 31 #include <objc/NSObjCRuntime.h> 30 32 #include <wtf/Compiler.h> 33 #include <wtf/OSObjectPtr.h> 34 #include <wtf/Ref.h> 31 35 #include <wtf/RetainPtr.h> 32 36 33 #define HAVE_NE_FILTER_SOURCE TARGET_OS_EMBEDDED || (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 && CPU(X86_64)) 37 #define HAVE_NETWORK_EXTENSION PLATFORM(IOS) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 && CPU(X86_64)) 38 39 enum NEFilterSourceStatus : NSInteger; 34 40 35 41 OBJC_CLASS NEFilterSource; 42 OBJC_CLASS NSData; 43 OBJC_CLASS NSDictionary; 36 44 OBJC_CLASS NSMutableData; 37 45 … … 47 55 static std::unique_ptr<NetworkExtensionContentFilter> create(const ResourceResponse&); 48 56 49 ~NetworkExtensionContentFilter() override;50 57 void addData(const char* data, int length) override; 51 58 void finishedAddingData() override; … … 57 64 private: 58 65 explicit NetworkExtensionContentFilter(const ResourceResponse&); 66 void handleDecision(NEFilterSourceStatus, NSData *replacementData); 59 67 60 long m_neFilterSourceStatus; 68 NEFilterSourceStatus m_status; 69 OSObjectPtr<dispatch_queue_t> m_queue; 70 OSObjectPtr<dispatch_semaphore_t> m_semaphore; 71 Ref<SharedBuffer> m_originalData; 72 RetainPtr<NSData> m_replacementData; 61 73 RetainPtr<NEFilterSource> m_neFilterSource; 62 dispatch_queue_t m_neFilterSourceQueue;63 RetainPtr<NSMutableData> m_originalData;64 74 }; 65 75 -
trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm
r181037 r181523 27 27 #import "NetworkExtensionContentFilter.h" 28 28 29 #if HAVE(NE _FILTER_SOURCE)29 #if HAVE(NETWORK_EXTENSION) 30 30 31 31 #import "NEFilterSourceSPI.h" … … 36 36 SOFT_LINK_FRAMEWORK(NetworkExtension); 37 37 SOFT_LINK_CLASS(NetworkExtension, NEFilterSource); 38 39 #if HAVE(MODERN_NE_FILTER_SOURCE) 40 // FIXME: <rdar://problem/20165664> Expose decisionHandler dictionary keys as NSString constants in NEFilterSource.h 41 static NSString * const optionsPageData = @"PageData"; 42 43 static inline NSData *replacementDataFromDecisionInfo(NSDictionary *decisionInfo) 44 { 45 id replacementData = decisionInfo[optionsPageData]; 46 ASSERT(!replacementData || [replacementData isKindOfClass:[NSData class]]); 47 return replacementData; 48 } 49 #endif 38 50 39 51 namespace WebCore { … … 49 61 } 50 62 63 static inline RetainPtr<NEFilterSource> createNEFilterSource(const URL& url, dispatch_queue_t decisionQueue) 64 { 65 #if HAVE(MODERN_NE_FILTER_SOURCE) 66 UNUSED_PARAM(url); 67 return adoptNS([allocNEFilterSourceInstance() initWithDecisionQueue:decisionQueue]); 68 #else 69 UNUSED_PARAM(decisionQueue); 70 return adoptNS([allocNEFilterSourceInstance() initWithURL:url direction:NEFilterSourceDirectionInbound socketIdentifier:0]); 71 #endif 72 } 73 51 74 NetworkExtensionContentFilter::NetworkExtensionContentFilter(const ResourceResponse& response) 52 : m_neFilterSourceStatus { NEFilterSourceStatusNeedsMoreData } 53 , m_neFilterSource { adoptNS([allocNEFilterSourceInstance() initWithURL:[response.nsURLResponse() URL] direction:NEFilterSourceDirectionInbound socketIdentifier:0]) } 54 , m_neFilterSourceQueue { dispatch_queue_create("com.apple.WebCore.NEFilterSourceQueue", DISPATCH_QUEUE_SERIAL) } 75 : m_status { NEFilterSourceStatusNeedsMoreData } 76 , m_queue { adoptOSObject(dispatch_queue_create("com.apple.WebCore.NEFilterSourceQueue", DISPATCH_QUEUE_SERIAL)) } 77 , m_semaphore { adoptOSObject(dispatch_semaphore_create(0)) } 78 , m_originalData { *SharedBuffer::create() } 79 , m_neFilterSource { createNEFilterSource(response.url(), m_queue.get()) } 55 80 { 56 81 ASSERT([getNEFilterSourceClass() filterRequired]); 57 82 58 long long expectedContentSize = [response.nsURLResponse() expectedContentLength]; 59 if (expectedContentSize < 0) 60 m_originalData = adoptNS([[NSMutableData alloc] init]); 61 else 62 m_originalData = adoptNS([[NSMutableData alloc] initWithCapacity:(NSUInteger)expectedContentSize]); 63 } 64 65 NetworkExtensionContentFilter::~NetworkExtensionContentFilter() 66 { 67 dispatch_release(m_neFilterSourceQueue); 68 } 69 70 void NetworkExtensionContentFilter::addData(const char* data, int length) 71 { 72 // FIXME: NEFilterSource doesn't buffer data like WebFilterEvaluator does, 73 // so we need to do it ourselves so getReplacementData() can return the 74 // original bytes back to the loader. We should find a way to remove this 75 // additional copy. 76 [m_originalData appendBytes:data length:length]; 77 78 dispatch_semaphore_t neFilterSourceSemaphore = dispatch_semaphore_create(0); 79 [m_neFilterSource addData:[NSData dataWithBytes:(void*)data length:length] withCompletionQueue:m_neFilterSourceQueue completionHandler:^(NEFilterSourceStatus status, NSData *) { 80 m_neFilterSourceStatus = status; 81 dispatch_semaphore_signal(neFilterSourceSemaphore); 83 #if HAVE(MODERN_NE_FILTER_SOURCE) 84 [m_neFilterSource receivedResponse:response.nsURLResponse() decisionHandler:[this](NEFilterSourceStatus status, NSDictionary *decisionInfo) { 85 handleDecision(status, replacementDataFromDecisionInfo(decisionInfo)); 82 86 }]; 83 87 … … 85 89 // blocked/not blocked answer from the filter immediately after calling 86 90 // addData(). We should find a way to make this asynchronous. 87 dispatch_semaphore_wait(neFilterSourceSemaphore, DISPATCH_TIME_FOREVER); 88 dispatch_release(neFilterSourceSemaphore); 91 dispatch_semaphore_wait(m_semaphore.get(), DISPATCH_TIME_FOREVER); 92 #endif 93 } 94 95 void NetworkExtensionContentFilter::addData(const char* data, int length) 96 { 97 RetainPtr<NSData> copiedData { [NSData dataWithBytes:(void*)data length:length] }; 98 99 // FIXME: NEFilterSource doesn't buffer data like WebFilterEvaluator does, 100 // so we need to do it ourselves so getReplacementData() can return the 101 // original bytes back to the loader. We should find a way to remove this 102 // additional copy. 103 m_originalData->append((CFDataRef)copiedData.get()); 104 105 #if HAVE(MODERN_NE_FILTER_SOURCE) 106 [m_neFilterSource receivedData:copiedData.get() decisionHandler:[this](NEFilterSourceStatus status, NSDictionary *decisionInfo) { 107 handleDecision(status, replacementDataFromDecisionInfo(decisionInfo)); 108 }]; 109 #else 110 [m_neFilterSource addData:copiedData.get() withCompletionQueue:m_queue.get() completionHandler:[this](NEFilterSourceStatus status, NSData *replacementData) { 111 ASSERT(!replacementData); 112 handleDecision(status, replacementData); 113 }]; 114 #endif 115 116 // FIXME: We have to block here since DocumentLoader expects to have a 117 // blocked/not blocked answer from the filter immediately after calling 118 // addData(). We should find a way to make this asynchronous. 119 dispatch_semaphore_wait(m_semaphore.get(), DISPATCH_TIME_FOREVER); 89 120 } 90 121 91 122 void NetworkExtensionContentFilter::finishedAddingData() 92 123 { 93 dispatch_semaphore_t neFilterSourceSemaphore = dispatch_semaphore_create(0); 94 [m_neFilterSource dataCompleteWithCompletionQueue:m_neFilterSourceQueue completionHandler:^(NEFilterSourceStatus status, NSData *) { 95 m_neFilterSourceStatus = status; 96 dispatch_semaphore_signal(neFilterSourceSemaphore); 124 #if HAVE(MODERN_NE_FILTER_SOURCE) 125 [m_neFilterSource finishedLoadingWithDecisionHandler:[this](NEFilterSourceStatus status, NSDictionary *decisionInfo) { 126 handleDecision(status, replacementDataFromDecisionInfo(decisionInfo)); 97 127 }]; 128 #else 129 [m_neFilterSource dataCompleteWithCompletionQueue:m_queue.get() completionHandler:[this](NEFilterSourceStatus status, NSData *replacementData) { 130 ASSERT(!replacementData); 131 handleDecision(status, replacementData); 132 }]; 133 #endif 98 134 99 135 // FIXME: We have to block here since DocumentLoader expects to have a 100 136 // blocked/not blocked answer from the filter immediately after calling 101 137 // finishedAddingData(). We should find a way to make this asynchronous. 102 dispatch_semaphore_wait(neFilterSourceSemaphore, DISPATCH_TIME_FOREVER); 103 dispatch_release(neFilterSourceSemaphore); 138 dispatch_semaphore_wait(m_semaphore.get(), DISPATCH_TIME_FOREVER); 104 139 } 105 140 106 141 bool NetworkExtensionContentFilter::needsMoreData() const 107 142 { 108 return m_ neFilterSourceStatus == NEFilterSourceStatusNeedsMoreData;143 return m_status == NEFilterSourceStatusNeedsMoreData; 109 144 } 110 145 111 146 bool NetworkExtensionContentFilter::didBlockData() const 112 147 { 113 return m_ neFilterSourceStatus == NEFilterSourceStatusBlock;148 return m_status == NEFilterSourceStatusBlock; 114 149 } 115 150 … … 117 152 { 118 153 if (didBlockData()) { 119 length = 0;120 return nullptr;154 length = [m_replacementData length]; 155 return static_cast<const char*>([m_replacementData bytes]); 121 156 } 122 157 123 length = [m_originalData length];124 return static_cast<const char*>([m_originalData bytes]);158 length = m_originalData->size(); 159 return m_originalData->data(); 125 160 } 126 161 … … 130 165 } 131 166 167 void NetworkExtensionContentFilter::handleDecision(NEFilterSourceStatus status, NSData *replacementData) 168 { 169 m_status = status; 170 if (status == NEFilterSourceStatusBlock) 171 m_replacementData = replacementData; 172 dispatch_semaphore_signal(m_semaphore.get()); 173 } 174 132 175 } // namespace WebCore 133 176 134 #endif // HAVE(NE _FILTER_SOURCE)177 #endif // HAVE(NETWORK_EXTENSION) -
trunk/Source/WebCore/platform/spi/cocoa/NEFilterSourceSPI.h
r180708 r181523 24 24 */ 25 25 26 #define HAVE_MODERN_NE_FILTER_SOURCE (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) 27 26 28 #if USE(APPLE_INTERNAL_SDK) 27 29 … … 45 47 @end 46 48 47 @interface NEFilterSource ( Details)49 @interface NEFilterSource (WKLegacyDetails) 48 50 + (BOOL)filterRequired; 49 51 - (id)initWithURL:(NSURL *)url direction:(NEFilterSourceDirection)direction socketIdentifier:(uint64_t)socketIdentifier; … … 56 58 @end 57 59 60 #if HAVE(MODERN_NE_FILTER_SOURCE) 61 typedef void (^NEFilterSourceDecisionHandler)(NEFilterSourceStatus, NSDictionary *); 62 63 @interface NEFilterSource (WKModernDetails) 64 - (id)initWithDecisionQueue:(dispatch_queue_t)queue; 65 - (void)willSendRequest:(NSURLRequest *)request decisionHandler:(NEFilterSourceDecisionHandler)decisionHandler; 66 - (void)receivedResponse:(NSURLResponse *)response decisionHandler:(NEFilterSourceDecisionHandler)decisionHandler; 67 - (void)receivedData:(NSData *)data decisionHandler:(NEFilterSourceDecisionHandler)decisionHandler; 68 - (void)finishedLoadingWithDecisionHandler:(NEFilterSourceDecisionHandler)decisionHandler; 69 - (void)remediateWithDecisionHandler:(NEFilterSourceDecisionHandler)decisionHandler; 70 @end 58 71 #endif 72 73 #endif
Note:
See TracChangeset
for help on using the changeset viewer.