Changeset 229477 in webkit
- Timestamp:
- Mar 9, 2018 12:47:11 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r229475 r229477 1 2018-03-09 Youenn Fablet <youenn@apple.com> 2 3 ServiceWorkerClientFetch should send data to its resource loader once the didReceiveResponse completion handler is called 4 https://bugs.webkit.org/show_bug.cgi?id=183110 5 6 Reviewed by Chris Dumez. 7 8 Buffering data/finish event/fail event until the response completion handler is called. 9 10 * WebProcess/Storage/ServiceWorkerClientFetch.cpp: 11 (WebKit::ServiceWorkerClientFetch::didReceiveResponse): 12 (WebKit::ServiceWorkerClientFetch::didReceiveData): 13 (WebKit::ServiceWorkerClientFetch::didFinish): 14 (WebKit::ServiceWorkerClientFetch::didFail): 15 (WebKit::ServiceWorkerClientFetch::didNotHandle): 16 (WebKit::ServiceWorkerClientFetch::cancel): 17 (WebKit::ServiceWorkerClientFetch::continueLoadingAfterCheckingResponse): 18 * WebProcess/Storage/ServiceWorkerClientFetch.h: 19 1 20 2018-03-09 Jer Noble <jer.noble@apple.com> 2 21 -
trunk/Source/WebKit/WebProcess/Storage/ServiceWorkerClientFetch.cpp
r228852 r229477 107 107 if (auto error = validateResponse(response)) { 108 108 m_loader->didFail(error.value()); 109 ASSERT(!m_loader); 109 110 if (auto callback = WTFMove(m_callback)) 110 111 callback(Result::Succeeded); … … 142 143 response.setURL(m_loader->request().url()); 143 144 145 m_isCheckingResponse = true; 144 146 m_loader->didReceiveResponse(response, [this, protectedThis = WTFMove(protectedThis)] { 147 m_isCheckingResponse = false; 148 continueLoadingAfterCheckingResponse(); 145 149 if (auto callback = WTFMove(m_callback)) 146 150 callback(Result::Succeeded); … … 149 153 } 150 154 151 void ServiceWorkerClientFetch::didReceiveData(const IPC::DataReference& data, int64_t encodedDataLength) 152 { 153 callOnMainThread([this, protectedThis = makeRef(*this), data = data.vector(), encodedDataLength] { 154 if (!m_loader) 155 return; 156 157 m_loader->didReceiveData(reinterpret_cast<const char*>(data.data()), data.size(), encodedDataLength, DataPayloadBytes); 155 void ServiceWorkerClientFetch::didReceiveData(const IPC::DataReference& dataReference, int64_t encodedDataLength) 156 { 157 auto* data = reinterpret_cast<const char*>(dataReference.data()); 158 if (!m_buffer) { 159 m_buffer = SharedBuffer::create(data, dataReference.size()); 160 m_encodedDataLength = encodedDataLength; 161 } else { 162 m_buffer->append(data, dataReference.size()); 163 m_encodedDataLength += encodedDataLength; 164 } 165 166 if (m_isCheckingResponse) 167 return; 168 169 callOnMainThread([this, protectedThis = makeRef(*this)] { 170 if (!m_loader) 171 return; 172 173 m_loader->didReceiveBuffer(m_buffer.releaseNonNull(), m_encodedDataLength, DataPayloadBytes); 174 m_encodedDataLength = 0; 158 175 }); 159 176 } … … 166 183 void ServiceWorkerClientFetch::didFinish() 167 184 { 185 m_didFinish = true; 186 187 if (m_isCheckingResponse) 188 return; 189 168 190 callOnMainThread([this, protectedThis = makeRef(*this)] { 169 191 if (!m_loader) … … 193 215 void ServiceWorkerClientFetch::didFail() 194 216 { 217 m_didFail = true; 218 219 if (m_isCheckingResponse) 220 return; 221 195 222 callOnMainThread([this, protectedThis = makeRef(*this)] { 196 223 if (!m_loader) … … 208 235 void ServiceWorkerClientFetch::didNotHandle() 209 236 { 237 ASSERT(!m_isCheckingResponse); 238 210 239 callOnMainThread([this, protectedThis = makeRef(*this)] { 211 240 if (!m_loader) … … 224 253 callback(Result::Cancelled); 225 254 m_loader = nullptr; 255 m_buffer = nullptr; 256 } 257 258 void ServiceWorkerClientFetch::continueLoadingAfterCheckingResponse() 259 { 260 ASSERT(!m_isCheckingResponse); 261 if (!m_loader) 262 return; 263 264 if (m_encodedDataLength) { 265 callOnMainThread([this, protectedThis = makeRef(*this)] { 266 if (!m_loader || !m_encodedDataLength) 267 return; 268 m_loader->didReceiveBuffer(m_buffer.releaseNonNull(), m_encodedDataLength, DataPayloadBytes); 269 m_encodedDataLength = 0; 270 }); 271 } 272 273 if (m_didFail) { 274 didFail(); 275 return; 276 } 277 278 if (m_didFinish) 279 didFinish(); 226 280 } 227 281 -
trunk/Source/WebKit/WebProcess/Storage/ServiceWorkerClientFetch.h
r228198 r229477 67 67 void didNotHandle(); 68 68 69 void continueLoadingAfterCheckingResponse(); 70 69 71 WebServiceWorkerProvider& m_serviceWorkerProvider; 70 72 RefPtr<WebCore::ResourceLoader> m_loader; … … 75 77 RedirectionStatus m_redirectionStatus { RedirectionStatus::None }; 76 78 bool m_shouldClearReferrerOnHTTPSToHTTPRedirect { true }; 79 RefPtr<WebCore::SharedBuffer> m_buffer; 80 int64_t m_encodedDataLength { 0 }; 81 bool m_isCheckingResponse { false }; 82 bool m_didFinish { false }; 83 bool m_didFail { false }; 77 84 }; 78 85 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm
r229150 r229477 154 154 @end 155 155 156 static bool shouldAccept = true; 157 static bool navigationComplete = false; 158 static bool navigationFailed = false; 159 160 @interface TestSWAsyncNavigationDelegate : NSObject <WKNavigationDelegate, WKUIDelegate> 161 @end 162 163 @implementation TestSWAsyncNavigationDelegate 164 165 - (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation 166 { 167 navigationComplete = true; 168 } 169 170 - (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error 171 { 172 navigationFailed = true; 173 navigationComplete = true; 174 } 175 176 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error 177 { 178 navigationFailed = true; 179 navigationComplete = true; 180 } 181 182 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler 183 { 184 decisionHandler(WKNavigationActionPolicyAllow); 185 } 186 187 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler 188 { 189 int64_t deferredWaitTime = 100 * NSEC_PER_MSEC; 190 dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, deferredWaitTime); 191 dispatch_after(when, dispatch_get_main_queue(), ^{ 192 decisionHandler(shouldAccept ? WKNavigationResponsePolicyAllow : WKNavigationResponsePolicyCancel); 193 }); 194 } 195 @end 196 197 156 198 static const char* mainBytes = R"SWRESOURCE( 157 199 <script> … … 619 661 } 620 662 663 TEST(ServiceWorkers, WaitForPolicyDelegate) 664 { 665 [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins]; 666 667 // Start with a clean slate data store 668 [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() { 669 done = true; 670 }]; 671 TestWebKitAPI::Util::run(&done); 672 done = false; 673 674 RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 675 676 RetainPtr<SWMessageHandlerWithExpectedMessage> messageHandler = adoptNS([[SWMessageHandlerWithExpectedMessage alloc] init]); 677 [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"]; 678 679 RetainPtr<SWSchemes> handler = adoptNS([[SWSchemes alloc] init]); 680 handler->resources.set("sw://host/main.html", ResourceInfo { @"text/html", mainForFirstLoadInterceptTestBytes }); 681 handler->resources.set("sw://host/sw.js", ResourceInfo { @"application/javascript", scriptInterceptingFirstLoadBytes }); 682 [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SW"]; 683 684 RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); 685 [webView.get().configuration.processPool _registerURLSchemeServiceWorkersCanHandle:@"sw"]; 686 687 // Register a service worker and activate it. 688 expectedMessage = "Service Worker activated"; 689 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"sw://host/main.html"]]; 690 [webView loadRequest:request]; 691 692 TestWebKitAPI::Util::run(&done); 693 694 webView = nullptr; 695 configuration = nullptr; 696 messageHandler = nullptr; 697 handler = nullptr; 698 699 done = false; 700 701 configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 702 messageHandler = adoptNS([[SWMessageHandlerWithExpectedMessage alloc] init]); 703 [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"]; 704 705 handler = adoptNS([[SWSchemes alloc] init]); 706 handler->resources.set("sw://host/main.html", ResourceInfo { @"text/html", mainForFirstLoadInterceptTestBytes }); 707 handler->resources.set("sw://host/sw.js", ResourceInfo { @"application/javascript", scriptInterceptingFirstLoadBytes }); 708 [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SW"]; 709 710 webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); 711 [webView.get().configuration.processPool _registerURLSchemeServiceWorkersCanHandle:@"sw"]; 712 713 // Verify service worker is intercepting load. 714 expectedMessage = "Intercepted by worker"; 715 request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"sw://host/main.html"]]; 716 [webView loadRequest:request]; 717 718 TestWebKitAPI::Util::run(&done); 719 done = false; 720 721 webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); 722 [webView.get().configuration.processPool _registerURLSchemeServiceWorkersCanHandle:@"sw"]; 723 auto delegate = adoptNS([[TestSWAsyncNavigationDelegate alloc] init]); 724 [webView setNavigationDelegate:delegate.get()]; 725 [webView setUIDelegate:delegate.get()]; 726 727 shouldAccept = true; 728 navigationFailed = false; 729 navigationComplete = false; 730 731 // Verify service worker load goes well when policy delegate is ok. 732 request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"sw://host/main.html"]]; 733 [webView loadRequest:request]; 734 TestWebKitAPI::Util::run(&navigationComplete); 735 736 EXPECT_FALSE(navigationFailed); 737 738 webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); 739 [webView.get().configuration.processPool _registerURLSchemeServiceWorkersCanHandle:@"sw"]; 740 [webView setNavigationDelegate:delegate.get()]; 741 [webView setUIDelegate:delegate.get()]; 742 743 shouldAccept = false; 744 navigationFailed = false; 745 navigationComplete = false; 746 747 // Verify service worker load fails well when policy delegate is not ok. 748 request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"sw://host/main.html"]]; 749 [webView loadRequest:request]; 750 TestWebKitAPI::Util::run(&navigationComplete); 751 752 EXPECT_TRUE(navigationFailed); 753 } 621 754 #if WK_HAVE_C_SPI 622 755
Note: See TracChangeset
for help on using the changeset viewer.