Changeset 229666 in webkit
- Timestamp:
- Mar 16, 2018 9:11:54 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r229661 r229666 1 2018-03-16 Chris Dumez <cdumez@apple.com> 2 3 URLSchemeHandler.Basic API test fails with async policy delegates 4 https://bugs.webkit.org/show_bug.cgi?id=183678 5 6 Reviewed by Alex Christensen. 7 8 The issue is that the client calls _didPerformRedirection / didReceiveResponse / didReceiveData / didFinish 9 on the URLScheme task one after the one, synchronously. However, redirects and responses can be processed 10 asynchronously. To address the issue, we now queue operations requested by the client if we're waiting 11 for an async policy delegate. 12 13 * WebProcess/WebPage/WebURLSchemeTaskProxy.cpp: 14 (WebKit::WebURLSchemeTaskProxy::didPerformRedirection): 15 (WebKit::WebURLSchemeTaskProxy::didReceiveResponse): 16 (WebKit::WebURLSchemeTaskProxy::didReceiveData): 17 (WebKit::WebURLSchemeTaskProxy::didComplete): 18 (WebKit::WebURLSchemeTaskProxy::processNextPendingTask): 19 * WebProcess/WebPage/WebURLSchemeTaskProxy.h: 20 (WebKit::WebURLSchemeTaskProxy::queueTask): 21 1 22 2018-03-16 Claudio Saavedra <csaavedra@igalia.com> 2 23 -
trunk/Source/WebKit/WebProcess/WebPage/WebURLSchemeTaskProxy.cpp
r229209 r229666 71 71 72 72 auto completionHandler = [this, protectedThis = makeRef(*this), originalRequest = request] (ResourceRequest&& request) { 73 m_waitingFor RedirectCompletionHandler = false;73 m_waitingForCompletionHandler = false; 74 74 // We do not inform the UIProcess of WebKit's new request with the given suggested request. 75 75 // We do want to know if WebKit would have generated a request that differs from the suggested request, though. 76 76 if (request.url() != originalRequest.url()) 77 77 WTFLogAlways("Redirected scheme task would have been sent to a different URL."); 78 79 processNextPendingTask(); 78 80 }; 79 81 80 if (m_waitingForRedirectCompletionHandler) 81 WTFLogAlways("Received redirect during previous redirect processing."); 82 m_waitingForRedirectCompletionHandler = true; 82 if (m_waitingForCompletionHandler) { 83 WTFLogAlways("Received redirect during previous redirect processing, queuing it."); 84 queueTask([this, protectedThis = makeRef(*this), redirectResponse = WTFMove(redirectResponse), request = WTFMove(request)]() mutable { 85 didPerformRedirection(WTFMove(redirectResponse), WTFMove(request)); 86 }); 87 return; 88 } 89 m_waitingForCompletionHandler = true; 83 90 84 91 m_coreLoader->willSendRequest(WTFMove(request), redirectResponse, WTFMove(completionHandler)); … … 87 94 void WebURLSchemeTaskProxy::didReceiveResponse(const ResourceResponse& response) 88 95 { 89 if (m_waitingForRedirectCompletionHandler) 90 WTFLogAlways("Received response during redirect processing."); 96 if (m_waitingForCompletionHandler) { 97 WTFLogAlways("Received response during redirect processing, queuing it."); 98 queueTask([this, protectedThis = makeRef(*this), response] { 99 didReceiveResponse(response); 100 }); 101 return; 102 } 91 103 92 104 if (!hasLoader()) 93 105 return; 94 106 95 m_coreLoader->didReceiveResponse(response, nullptr); 107 m_waitingForCompletionHandler = true; 108 m_coreLoader->didReceiveResponse(response, [this, protectedThis = makeRef(*this)] { 109 m_waitingForCompletionHandler = false; 110 processNextPendingTask(); 111 }); 96 112 } 97 113 … … 101 117 return; 102 118 119 if (m_waitingForCompletionHandler) { 120 WTFLogAlways("Received data during response processing, queuing it."); 121 Vector<uint8_t> dataVector; 122 dataVector.append(data, size); 123 queueTask([this, protectedThis = makeRef(*this), dataVector = WTFMove(dataVector)] { 124 didReceiveData(dataVector.size(), dataVector.data()); 125 }); 126 return; 127 } 128 103 129 m_coreLoader->didReceiveData(reinterpret_cast<const char*>(data), size, 0, DataPayloadType::DataPayloadBytes); 130 processNextPendingTask(); 104 131 } 105 132 … … 108 135 if (!hasLoader()) 109 136 return; 137 138 if (m_waitingForCompletionHandler) { 139 queueTask([this, protectedThis = makeRef(*this), error] { 140 didComplete(error); 141 }); 142 return; 143 } 110 144 111 145 if (error.isNull()) … … 125 159 } 126 160 161 void WebURLSchemeTaskProxy::processNextPendingTask() 162 { 163 if (!m_queuedTasks.isEmpty()) 164 m_queuedTasks.takeFirst()(); 165 } 166 127 167 } // namespace WebKit -
trunk/Source/WebKit/WebProcess/WebPage/WebURLSchemeTaskProxy.h
r218750 r229666 27 27 28 28 #include <WebCore/ResourceRequest.h> 29 #include <wtf/Deque.h> 29 30 #include <wtf/RefCounted.h> 30 31 … … 62 63 bool hasLoader(); 63 64 65 void queueTask(Function<void()>&& task) { m_queuedTasks.append(WTFMove(task)); } 66 void processNextPendingTask(); 67 64 68 WebURLSchemeHandlerProxy& m_urlSchemeHandler; 65 69 RefPtr<WebCore::ResourceLoader> m_coreLoader; 66 70 WebCore::ResourceRequest m_request; 67 71 unsigned long m_identifier; 68 bool m_waitingForRedirectCompletionHandler { }; 72 bool m_waitingForCompletionHandler { false }; 73 Deque<Function<void()>> m_queuedTasks; 69 74 }; 70 75 -
trunk/Tools/ChangeLog
r229664 r229666 1 2018-03-16 Chris Dumez <cdumez@apple.com> 2 3 URLSchemeHandler.Basic API test fails with async policy delegates 4 https://bugs.webkit.org/show_bug.cgi?id=183678 5 6 Reviewed by Alex Christensen. 7 8 Add API test coverage. 9 10 * TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm: 11 (-[URLSchemeHandlerAsyncNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]): 12 (-[URLSchemeHandlerAsyncNavigationDelegate webView:decidePolicyForNavigationResponse:decisionHandler:]): 13 (TEST): 14 1 15 2018-03-16 Zalan Bujtas <zalan@apple.com> 2 16 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm
r220107 r229666 100 100 @end 101 101 102 @interface URLSchemeHandlerAsyncNavigationDelegate : NSObject <WKNavigationDelegate, WKUIDelegate> 103 @end 104 105 @implementation URLSchemeHandlerAsyncNavigationDelegate 106 107 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler 108 { 109 int64_t deferredWaitTime = 100 * NSEC_PER_MSEC; 110 dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, deferredWaitTime); 111 dispatch_after(when, dispatch_get_main_queue(), ^{ 112 decisionHandler(WKNavigationActionPolicyAllow); 113 }); 114 115 } 116 117 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler 118 { 119 int64_t deferredWaitTime = 100 * NSEC_PER_MSEC; 120 dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, deferredWaitTime); 121 dispatch_after(when, dispatch_get_main_queue(), ^{ 122 decisionHandler(WKNavigationResponsePolicyAllow); 123 }); 124 } 125 @end 126 127 102 128 static const char mainBytes[] = 103 129 "<html>" \ … … 115 141 116 142 RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); 143 144 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"testing:main"]]; 145 [webView loadRequest:request]; 146 147 TestWebKitAPI::Util::run(&done); 148 149 EXPECT_EQ([handler.get().startedURLs count], 2u); 150 EXPECT_TRUE([[handler.get().startedURLs objectAtIndex:0] isEqual:[NSURL URLWithString:@"testing:main"]]); 151 EXPECT_TRUE([[handler.get().startedURLs objectAtIndex:1] isEqual:[NSURL URLWithString:@"testing:image"]]); 152 EXPECT_EQ([handler.get().stoppedURLs count], 0u); 153 } 154 155 TEST(URLSchemeHandler, BasicWithAsyncPolicyDelegate) 156 { 157 done = false; 158 159 RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 160 161 RetainPtr<SchemeHandler> handler = adoptNS([[SchemeHandler alloc] initWithData:[NSData dataWithBytesNoCopy:(void*)mainBytes length:sizeof(mainBytes) freeWhenDone:NO] mimeType:@"text/html"]); 162 [configuration setURLSchemeHandler:handler.get() forURLScheme:@"testing"]; 163 164 RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); 165 auto delegate = adoptNS([[URLSchemeHandlerAsyncNavigationDelegate alloc] init]); 166 [webView setNavigationDelegate:delegate.get()]; 117 167 118 168 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"testing:main"]];
Note: See TracChangeset
for help on using the changeset viewer.