Changeset 251409 in webkit
- Timestamp:
- Oct 21, 2019 6:34:39 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r251404 r251409 1 2019-10-21 youenn fablet <youenn@apple.com> 2 3 Move service worker registration matching for navigation loads to network process 4 https://bugs.webkit.org/show_bug.cgi?id=203144 5 6 Reviewed by Chris Dumez. 7 8 For regular loads, we no longer match service worker registration explicitly. 9 This is now done by NetworkResourceLoader explicitly. 10 We still need to explicitely match registrations in those two cases: 11 - There is an app cache resource that can be used. We will use it only if there is no registration. 12 - There is a resource from the meory cache that can be used. We will match the registration to make sure 13 the document is controlled by the right service worker. The load will still be served from the memory cache. 14 15 Since DocumentLoader is no longer matching registration, we need a way from NetworkProcess to inform that there is 16 a matching registration and that the document is controlled. 17 For that purpose, DocumentLoader is adding itself in a global map with the temporary document identifier as the key. 18 Adding to the map happens when loading the main resource and removal from the map happens when destroying the DocumentLoader. 19 For this to happen properly, the temporary document identifier is kept the same for the lifetime of the DocumentLoader. 20 21 Registration matching was postponed until service worker registration is done. 22 Since we no longer do registration matching in WebProcess, we need to wait in NetworkProcess for that to happen. 23 We introduce a way for SWServer to notify when import is completed for that purpose. 24 25 Covered by existing tests. 26 27 * loader/DocumentLoader.cpp: 28 (WebCore::DocumentLoader::fromTemporaryDocumentIdentifier): 29 (WebCore::DocumentLoader::~DocumentLoader): 30 (WebCore::DocumentLoader::setControllingServiceWorkerRegistration): 31 (WebCore::DocumentLoader::redirectReceived): 32 (WebCore::DocumentLoader::responseReceived): 33 (WebCore::DocumentLoader::startLoadingMainResource): 34 (WebCore::DocumentLoader::unregisterTemporaryServiceWorkerClient): 35 (WebCore::DocumentLoader::loadMainResource): 36 * loader/DocumentLoader.h: 37 * loader/appcache/ApplicationCacheHost.cpp: 38 (WebCore::ApplicationCacheHost::canLoadMainResource): 39 * loader/appcache/ApplicationCacheHost.h: 40 * workers/service/server/SWServer.cpp: 41 (WebCore::SWServer::~SWServer): 42 (WebCore::SWServer::registrationStoreImportComplete): 43 (WebCore::SWServer::whenImportIsCompleted): 44 (WebCore::SWServer::doRegistrationMatching): 45 * workers/service/server/SWServer.h: 46 (WebCore::SWServer::isImportCompleted const): 47 1 48 2019-10-21 Sihui Liu <sihui_liu@apple.com> 2 49 -
trunk/Source/WebCore/loader/DocumentLoader.cpp
r251220 r251409 126 126 } 127 127 128 static HashMap<DocumentIdentifier, DocumentLoader*>& temporaryIdentifierToLoaderMap() 129 { 130 static NeverDestroyed<HashMap<DocumentIdentifier, DocumentLoader*>> map; 131 return map.get(); 132 } 133 134 DocumentLoader* DocumentLoader::fromTemporaryDocumentIdentifier(DocumentIdentifier identifier) 135 { 136 return temporaryIdentifierToLoaderMap().get(identifier); 137 } 138 128 139 DocumentLoader::DocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData) 129 140 : FrameDestructionObserver(nullptr) … … 162 173 m_cachedResourceLoader->clearDocumentLoader(); 163 174 clearMainResource(); 175 176 #if ENABLE(SERVICE_WORKER) 177 if (m_temporaryServiceWorkerClient) { 178 ASSERT(temporaryIdentifierToLoaderMap().contains(*m_temporaryServiceWorkerClient)); 179 temporaryIdentifierToLoaderMap().remove(*m_temporaryServiceWorkerClient); 180 } 181 #endif 164 182 } 165 183 … … 469 487 470 488 #if ENABLE(SERVICE_WORKER) 489 bool DocumentLoader::setControllingServiceWorkerRegistration(ServiceWorkerRegistrationData&& data) 490 { 491 if (!m_loadingMainResource) 492 return false; 493 494 ASSERT(!m_gotFirstByte); 495 m_serviceWorkerRegistrationData = WTFMove(data); 496 return true; 497 } 498 471 499 void DocumentLoader::matchRegistration(const URL& url, SWClientConnection::RegistrationCallback&& callback) 472 500 { … … 502 530 ASSERT_UNUSED(resource, &resource == m_mainResource); 503 531 #if ENABLE(SERVICE_WORKER) 504 bool isRedirectionFromServiceWorker = redirectResponse.source() == ResourceResponse::Source::ServiceWorker; 505 willSendRequest(WTFMove(request), redirectResponse, [isRedirectionFromServiceWorker, completionHandler = WTFMove(completionHandler), protectedThis = makeRef(*this), this] (auto&& request) mutable { 532 if (m_serviceWorkerRegistrationData) { 533 m_serviceWorkerRegistrationData = { }; 534 unregisterTemporaryServiceWorkerClient(); 535 } 536 willSendRequest(WTFMove(request), redirectResponse, [completionHandler = WTFMove(completionHandler), protectedThis = makeRef(*this), this] (auto&& request) mutable { 506 537 ASSERT(!m_substituteData.isValid()); 507 538 if (request.isNull() || !m_mainDocumentError.isNull() || !m_frame) { … … 510 541 } 511 542 512 auto url = request.url(); 513 this->matchRegistration(url, [request = WTFMove(request), isRedirectionFromServiceWorker, completionHandler = WTFMove(completionHandler), protectedThis = WTFMove(protectedThis), this] (auto&& registrationData) mutable { 514 if (!m_mainDocumentError.isNull() || !m_frame) { 515 completionHandler({ }); 516 return; 517 } 518 519 if (!registrationData && this->tryLoadingRedirectRequestFromApplicationCache(request)) { 520 completionHandler({ }); 521 return; 522 } 523 524 bool shouldContinueLoad = areRegistrationsEqual(m_serviceWorkerRegistrationData, registrationData) 525 && isRedirectionFromServiceWorker == !!registrationData; 526 527 if (shouldContinueLoad) { 543 if (m_applicationCacheHost->canLoadMainResource(request)) { 544 auto url = request.url(); 545 // Let's check service worker registration to see whether loading from network or not. 546 this->matchRegistration(url, [request = WTFMove(request), completionHandler = WTFMove(completionHandler), protectedThis = WTFMove(protectedThis), this](auto&& registrationData) mutable { 547 if (!m_mainDocumentError.isNull() || !m_frame) { 548 completionHandler({ }); 549 return; 550 } 551 if (!registrationData && this->tryLoadingRedirectRequestFromApplicationCache(request)) { 552 completionHandler({ }); 553 return; 554 } 528 555 completionHandler(WTFMove(request)); 529 return; 530 } 531 532 this->restartLoadingDueToServiceWorkerRegistrationChange(WTFMove(request), WTFMove(registrationData)); 533 completionHandler({ }); 556 }); 534 557 return; 535 }); 558 } 559 completionHandler(WTFMove(request)); 536 560 }); 537 561 #else … … 696 720 } 697 721 698 #if ENABLE(SERVICE_WORKER)699 void DocumentLoader::restartLoadingDueToServiceWorkerRegistrationChange(ResourceRequest&& request, Optional<ServiceWorkerRegistrationData>&& registrationData)700 {701 clearMainResource();702 703 ASSERT(!isCommitted());704 m_serviceWorkerRegistrationData = WTFMove(registrationData);705 loadMainResource(WTFMove(request));706 707 if (m_mainResource)708 frameLoader()->client().dispatchDidReceiveServerRedirectForProvisionalLoad();709 }710 #endif711 712 722 void DocumentLoader::stopLoadingAfterXFrameOptionsOrContentSecurityPolicyDenied(unsigned long identifier, const ResourceResponse& response) 713 723 { … … 726 736 { 727 737 ASSERT_UNUSED(resource, m_mainResource == &resource); 738 #if ENABLE(SERVICE_WORKER) 739 if (RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled() && response.source() == ResourceResponse::Source::MemoryCache) { 740 matchRegistration(response.url(), [this, protectedThis = makeRef(*this), response, completionHandler = WTFMove(completionHandler)](auto&& registrationData) mutable { 741 if (!m_mainDocumentError.isNull() || !m_frame) { 742 completionHandler(); 743 return; 744 } 745 m_serviceWorkerRegistrationData = WTFMove(registrationData); 746 responseReceived(response, WTFMove(completionHandler)); 747 }); 748 return; 749 } 750 #endif 728 751 responseReceived(response, WTFMove(completionHandler)); 729 752 } … … 1755 1778 willSendRequest(ResourceRequest(m_request), ResourceResponse(), [this, protectedThis = WTFMove(protectedThis)] (ResourceRequest&& request) mutable { 1756 1779 m_request = request; 1780 // FIXME: Implement local URL interception by getting the service worker of the parent. 1757 1781 1758 1782 // willSendRequest() may lead to our Frame being detached or cancelling the load via nulling the ResourceRequest. … … 1769 1793 1770 1794 #if ENABLE(SERVICE_WORKER) 1771 // FIXME: Implement local URL interception by getting the service worker of the parent. 1772 auto url = request.url(); 1773 matchRegistration(url, [request = WTFMove(request), protectedThis = WTFMove(protectedThis), this] (auto&& registrationData) mutable { 1774 if (!m_mainDocumentError.isNull() || !m_frame) { 1775 RELEASE_LOG_IF_ALLOWED("startLoadingMainResource callback: Load canceled because of main document error (frame = %p, main = %d)", m_frame, m_frame ? m_frame->isMainFrame() : false); 1776 return; 1777 } 1778 1779 m_serviceWorkerRegistrationData = WTFMove(registrationData); 1780 1781 // Prefer existing substitute data (from WKWebView.loadData etc) over service worker fetch. 1782 if (this->tryLoadingSubstituteData()) { 1783 RELEASE_LOG_IF_ALLOWED("startLoadingMainResource callback: Load canceled because of substitute data (frame = %p, main = %d)", m_frame, m_frame ? m_frame->isMainFrame() : false); 1784 return; 1785 } 1786 // Try app cache only if there is no service worker. 1787 if (!m_serviceWorkerRegistrationData && this->tryLoadingRequestFromApplicationCache()) { 1788 RELEASE_LOG_IF_ALLOWED("startLoadingMainResource callback: Loaded from Application Cache (frame = %p, main = %d)", m_frame, m_frame->isMainFrame()); 1789 return; 1790 } 1791 this->loadMainResource(WTFMove(request)); 1792 }); 1795 if (m_applicationCacheHost->canLoadMainResource(request) || m_substituteData.isValid()) { 1796 auto url = request.url(); 1797 matchRegistration(url, [request = WTFMove(request), protectedThis = WTFMove(protectedThis), this] (auto&& registrationData) mutable { 1798 if (!m_mainDocumentError.isNull() || !m_frame) { 1799 RELEASE_LOG_IF_ALLOWED("startLoadingMainResource callback: Load canceled because of main document error (frame = %p, main = %d)", m_frame, m_frame ? m_frame->isMainFrame() : false); 1800 return; 1801 } 1802 1803 m_serviceWorkerRegistrationData = WTFMove(registrationData); 1804 // Prefer existing substitute data (from WKWebView.loadData etc) over service worker fetch. 1805 if (this->tryLoadingSubstituteData()) { 1806 RELEASE_LOG_IF_ALLOWED("startLoadingMainResource callback: Load canceled because of substitute data (frame = %p, main = %d)", m_frame, m_frame ? m_frame->isMainFrame() : false); 1807 return; 1808 } 1809 1810 if (!m_serviceWorkerRegistrationData && this->tryLoadingRequestFromApplicationCache()) { 1811 RELEASE_LOG_IF_ALLOWED("startLoadingMainResource callback: Loaded from Application Cache (frame = %p, main = %d)", m_frame, m_frame->isMainFrame()); 1812 return; 1813 } 1814 this->loadMainResource(WTFMove(request)); 1815 }); 1816 return; 1817 } 1793 1818 #else 1794 1819 if (tryLoadingRequestFromApplicationCache()) { … … 1796 1821 return; 1797 1822 } 1823 #endif 1798 1824 loadMainResource(WTFMove(request)); 1799 #endif1800 1825 }); 1801 1826 } 1802 1827 1803 void DocumentLoader:: registerTemporaryServiceWorkerClient(const URL& url)1828 void DocumentLoader::unregisterTemporaryServiceWorkerClient() 1804 1829 { 1805 1830 #if ENABLE(SERVICE_WORKER) 1806 ASSERT(!m_temporaryServiceWorkerClient); 1807 1808 if (!m_serviceWorkerRegistrationData) 1809 return; 1810 1811 m_temporaryServiceWorkerClient = DocumentIdentifier::generate(); 1812 1813 auto& serviceWorkerConnection = ServiceWorkerProvider::singleton().serviceWorkerConnection(); 1814 1815 // FIXME: Compute ServiceWorkerClientFrameType appropriately. 1816 ServiceWorkerClientData data { { serviceWorkerConnection.serverConnectionIdentifier(), *m_temporaryServiceWorkerClient }, ServiceWorkerClientType::Window, ServiceWorkerClientFrameType::None, url }; 1817 1818 RefPtr<SecurityOrigin> topOrigin; 1819 if (m_frame->isMainFrame()) 1820 topOrigin = SecurityOrigin::create(url); 1821 else 1822 topOrigin = &m_frame->mainFrame().document()->topOrigin(); 1823 serviceWorkerConnection.registerServiceWorkerClient(*topOrigin, WTFMove(data), m_serviceWorkerRegistrationData->identifier, m_frame->loader().userAgent(url)); 1824 #else 1825 UNUSED_PARAM(url); 1826 #endif 1827 } 1828 1829 void DocumentLoader::unregisterTemporaryServiceWorkerClient() 1830 { 1831 #if ENABLE(SERVICE_WORKER) 1832 if (!m_temporaryServiceWorkerClient) 1831 if (!m_temporaryServiceWorkerClient || !RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled()) 1833 1832 return; 1834 1833 1835 1834 auto& serviceWorkerConnection = ServiceWorkerProvider::singleton().serviceWorkerConnection(); 1836 1835 serviceWorkerConnection.unregisterServiceWorkerClient(*m_temporaryServiceWorkerClient); 1837 m_temporaryServiceWorkerClient = WTF::nullopt;1838 1836 #endif 1839 1837 } … … 1841 1839 void DocumentLoader::loadMainResource(ResourceRequest&& request) 1842 1840 { 1843 static NeverDestroyed<ResourceLoaderOptions>mainResourceLoadOptions(1841 ResourceLoaderOptions mainResourceLoadOptions( 1844 1842 SendCallbackPolicy::SendCallbacks, 1845 1843 ContentSniffingPolicy::SniffContent, … … 1854 1852 DefersLoadingPolicy::AllowDefersLoading, 1855 1853 CachingPolicy::AllowCaching); 1854 #if ENABLE(SERVICE_WORKER) 1855 if (!m_temporaryServiceWorkerClient) { 1856 // The main navigation load will trigger the registration of the temp client. 1857 m_temporaryServiceWorkerClient = DocumentIdentifier::generate(); 1858 ASSERT(!temporaryIdentifierToLoaderMap().contains(*m_temporaryServiceWorkerClient)); 1859 temporaryIdentifierToLoaderMap().add(*m_temporaryServiceWorkerClient, this); 1860 } 1861 mainResourceLoadOptions.clientIdentifier = m_temporaryServiceWorkerClient; 1862 #endif 1856 1863 CachedResourceRequest mainResourceRequest(WTFMove(request), mainResourceLoadOptions); 1857 1864 if (!m_frame->isMainFrame() && m_frame->document()) { … … 1864 1871 } 1865 1872 1866 #if ENABLE(SERVICE_WORKER)1867 mainResourceRequest.setNavigationServiceWorkerRegistrationData(m_serviceWorkerRegistrationData);1868 if (mainResourceRequest.options().serviceWorkersMode != ServiceWorkersMode::None) {1869 // As per step 12 of https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm, the active service worker should be controlling the document.1870 // Since we did not yet create the document, we register a temporary service worker client instead.1871 registerTemporaryServiceWorkerClient(mainResourceRequest.resourceRequest().url());1872 }1873 #endif1874 1875 1873 m_mainResource = m_cachedResourceLoader->requestMainResource(WTFMove(mainResourceRequest)).value_or(nullptr); 1876 1874 -
trunk/Source/WebCore/loader/DocumentLoader.h
r251220 r251409 150 150 return adoptRef(*new DocumentLoader(request, data)); 151 151 } 152 153 WEBCORE_EXPORT static DocumentLoader* fromTemporaryDocumentIdentifier(DocumentIdentifier); 154 152 155 WEBCORE_EXPORT virtual ~DocumentLoader(); 153 156 … … 393 396 bool allowContentChangeObserverQuirk() const { return m_allowContentChangeObserverQuirk; } 394 397 398 #if ENABLE(SERVICE_WORKER) 399 WEBCORE_EXPORT bool setControllingServiceWorkerRegistration(ServiceWorkerRegistrationData&&); 400 #endif 401 395 402 protected: 396 403 WEBCORE_EXPORT DocumentLoader(const ResourceRequest&, const SubstituteData&); … … 406 413 void matchRegistration(const URL&, CompletionHandler<void(Optional<ServiceWorkerRegistrationData>&&)>&&); 407 414 #endif 408 void registerTemporaryServiceWorkerClient(const URL&);409 415 void unregisterTemporaryServiceWorkerClient(); 410 416 … … 448 454 bool tryLoadingSubstituteData(); 449 455 bool tryLoadingRedirectRequestFromApplicationCache(const ResourceRequest&); 450 #if ENABLE(SERVICE_WORKER)451 void restartLoadingDueToServiceWorkerRegistrationChange(ResourceRequest&&, Optional<ServiceWorkerRegistrationData>&&);452 #endif453 456 void continueAfterContentPolicy(PolicyAction); 454 457 -
trunk/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp
r251220 r251409 81 81 } 82 82 83 bool ApplicationCacheHost::canLoadMainResource(const ResourceRequest& request) 84 { 85 if (!isApplicationCacheEnabled() || isApplicationCacheBlockedForRequest(request)) 86 return false; 87 return !!ApplicationCacheGroup::cacheForMainRequest(request, &m_documentLoader); 88 } 89 83 90 void ApplicationCacheHost::maybeLoadMainResource(const ResourceRequest& request, SubstituteData& substituteData) 84 91 { -
trunk/Source/WebCore/loader/appcache/ApplicationCacheHost.h
r251220 r251409 91 91 void selectCacheWithManifest(const URL& manifestURL); 92 92 93 bool canLoadMainResource(const ResourceRequest&); 94 93 95 void maybeLoadMainResource(const ResourceRequest&, SubstituteData&); 94 96 void maybeLoadMainResourceForRedirect(const ResourceRequest&, SubstituteData&); -
trunk/Source/WebCore/workers/service/server/SWServer.cpp
r251384 r251409 70 70 connections.clear(); 71 71 72 for (auto& callback : std::exchange(m_importCompletedCallbacks, { })) 73 callback(); 74 72 75 Vector<SWServerWorker*> runningWorkers; 73 76 for (auto& worker : m_runningOrTerminatingWorkers.values()) { … … 132 135 133 136 performGetOriginsWithRegistrationsCallbacks(); 134 } 137 138 for (auto& callback : std::exchange(m_importCompletedCallbacks, { })) 139 callback(); 140 } 141 142 void SWServer::whenImportIsCompleted(CompletionHandler<void()>&& callback) 143 { 144 ASSERT(!m_importCompleted); 145 m_importCompletedCallbacks.append(WTFMove(callback)); 146 } 147 135 148 136 149 void SWServer::registrationStoreDatabaseFailedToOpen() … … 758 771 SWServerRegistration* SWServer::doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL) 759 772 { 773 ASSERT(isImportCompleted()); 760 774 SWServerRegistration* selectedRegistration = nullptr; 761 775 for (auto& pair : m_scopeToRegistrationMap) { -
trunk/Source/WebCore/workers/service/server/SWServer.h
r251384 r251409 204 204 WEBCORE_EXPORT void createContextConnection(const RegistrableDomain&); 205 205 206 bool isImportCompleted() const { return m_importCompleted; } 207 WEBCORE_EXPORT void whenImportIsCompleted(CompletionHandler<void()>&&); 208 206 209 private: 207 210 void scriptFetchFinished(Connection&, const ServiceWorkerFetchResult&); … … 263 266 CreateContextConnectionCallback m_createContextConnectionCallback; 264 267 HashSet<WebCore::RegistrableDomain> m_pendingConnectionDomains; 268 Vector<CompletionHandler<void()>> m_importCompletedCallbacks; 265 269 }; 266 270 -
trunk/Source/WebKit/ChangeLog
r251404 r251409 1 2019-10-21 youenn fablet <youenn@apple.com> 2 3 Move service worker registration matching for navigation loads to network process 4 https://bugs.webkit.org/show_bug.cgi?id=203144 5 6 Reviewed by Chris Dumez. 7 8 Create a WebSWServerConnection whenever receiving a load request in NetworkProcess. 9 This connection is used to check for service worker registration in case of navigation loads. 10 Similarly, we create a WebSWClientConnection whenever WebProcess needs it, including when receiving WebSWClientConnection messages from NetworkProcess. 11 This for instance happens when service worker registration import is complete to fill the shared registration origin store. 12 13 Delay loads until SWServer has finished importing its registrations. 14 This is needed since we might otherwise not intercept loads that could be intercepted. 15 Waiting for importing registrations was previously ensured by WebProcess getting a matching registration in DocumentLoader. 16 17 NetworkResourceLoader is now checking for service worker interception in case of redirections for navigations. 18 This is needed as redirections could end up using a new registration. 19 20 * NetworkProcess/NetworkConnectionToWebProcess.cpp: 21 (WebKit::NetworkConnectionToWebProcess::NetworkConnectionToWebProcess): 22 (WebKit::NetworkConnectionToWebProcess::scheduleResourceLoad): 23 (WebKit::NetworkConnectionToWebProcess::establishSWServerConnection): 24 (WebKit::NetworkConnectionToWebProcess::swConnection): 25 * NetworkProcess/NetworkConnectionToWebProcess.h: 26 * NetworkProcess/NetworkConnectionToWebProcess.messages.in: 27 * NetworkProcess/NetworkResourceLoader.cpp: 28 (WebKit::NetworkResourceLoader::continueWillSendRequest): 29 (WebKit::NetworkResourceLoader::startWithServiceWorker): 30 (WebKit::NetworkResourceLoader::serviceWorkerDidNotHandle): 31 * NetworkProcess/NetworkResourceLoader.h: 32 * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp: 33 (WebKit::ServiceWorkerFetchTask::ServiceWorkerFetchTask): 34 (WebKit::ServiceWorkerFetchTask::start): 35 (WebKit::ServiceWorkerFetchTask::startFetch): 36 (WebKit::ServiceWorkerFetchTask::continueFetchTaskWith): 37 * NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h: 38 (WebKit::ServiceWorkerFetchTask::takeRequest): 39 * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp: 40 (WebKit::WebSWServerConnection::controlClient): 41 (WebKit::WebSWServerConnection::createFetchTask): 42 * NetworkProcess/ServiceWorker/WebSWServerConnection.h: 43 * WebProcess/Network/NetworkProcessConnection.cpp: 44 (WebKit::NetworkProcessConnection::didReceiveMessage): 45 * WebProcess/Network/WebLoaderStrategy.cpp: 46 (WebKit::WebLoaderStrategy::scheduleLoad): 47 * WebProcess/Storage/WebSWClientConnection.cpp: 48 (WebKit::WebSWClientConnection::WebSWClientConnection): 49 (WebKit::WebSWClientConnection::registrationReady): 50 (WebKit::WebSWClientConnection::documentIsControlled): 51 * WebProcess/Storage/WebSWClientConnection.h: 52 * WebProcess/Storage/WebSWClientConnection.messages.in: 53 1 54 2019-10-21 Sihui Liu <sihui_liu@apple.com> 2 55 -
trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
r251146 r251409 102 102 m_connection->setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(true); 103 103 m_connection->open(); 104 105 #if ENABLE(SERVICE_WORKER) 106 establishSWServerConnection(); 107 #endif 104 108 } 105 109 … … 401 405 void NetworkConnectionToWebProcess::scheduleResourceLoad(NetworkResourceLoadParameters&& loadParameters) 402 406 { 407 #if ENABLE(SERVICE_WORKER) 408 auto& server = m_networkProcess->swServerForSession(m_sessionID); 409 if (!server.isImportCompleted()) { 410 server.whenImportIsCompleted([this, protectedThis = makeRef(*this), loadParameters = WTFMove(loadParameters)]() mutable { 411 if (!m_networkProcess->webProcessConnection(webProcessIdentifier())) 412 return; 413 ASSERT(m_networkProcess->swServerForSession(m_sessionID).isImportCompleted()); 414 scheduleResourceLoad(WTFMove(loadParameters)); 415 }); 416 return; 417 } 418 #endif 403 419 auto identifier = loadParameters.identifier; 404 420 RELEASE_ASSERT(identifier); … … 409 425 410 426 #if ENABLE(SERVICE_WORKER) 411 loader->startWithServiceWorker( m_swConnection.get());427 loader->startWithServiceWorker(); 412 428 #else 413 429 loader->start(); … … 880 896 void NetworkConnectionToWebProcess::establishSWServerConnection() 881 897 { 898 if (m_swConnection) 899 return; 900 882 901 auto& server = m_networkProcess->swServerForSession(m_sessionID); 883 902 auto connection = makeUnique<WebSWServerConnection>(m_networkProcess, server, m_connection.get(), m_webProcessIdentifier); 884 903 885 ASSERT(!m_swConnection);886 904 m_swConnection = makeWeakPtr(*connection); 887 905 server.addConnection(WTFMove(connection)); … … 905 923 906 924 m_swContextConnection = nullptr; 925 } 926 927 WebSWServerConnection& NetworkConnectionToWebProcess::swConnection() 928 { 929 if (!m_swConnection) 930 establishSWServerConnection(); 931 return *m_swConnection; 907 932 } 908 933 #endif -
trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
r251146 r251409 158 158 #if ENABLE(SERVICE_WORKER) 159 159 void serverToContextConnectionNoLongerNeeded(); 160 WebSWServerConnection& swConnection(); 160 161 #endif 161 162 -
trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
r251146 r251409 80 80 81 81 #if ENABLE(SERVICE_WORKER) 82 EstablishSWServerConnection()83 82 EstablishSWContextConnection(WebCore::RegistrableDomain domain) 84 83 CloseSWContextConnection() -
trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
r251146 r251409 762 762 { 763 763 #if ENABLE(SERVICE_WORKER) 764 if (parameters().options.mode == FetchOptions::Mode::Navigate) { 765 if (auto serviceWorkerFetchTask = m_connection->swConnection().createFetchTask(*this, newRequest)) { 766 m_networkLoad = nullptr; 767 m_serviceWorkerFetchTask = WTFMove(serviceWorkerFetchTask); 768 return; 769 } 770 m_shouldRestartLoad = !!m_serviceWorkerFetchTask; 771 m_serviceWorkerFetchTask = nullptr; 772 } 764 773 if (m_serviceWorkerFetchTask) { 765 774 m_serviceWorkerFetchTask->continueFetchTaskWith(WTFMove(newRequest)); … … 767 776 } 768 777 #endif 778 769 779 if (m_shouldRestartLoad) { 770 780 m_shouldRestartLoad = false; … … 1224 1234 1225 1235 #if ENABLE(SERVICE_WORKER) 1226 void NetworkResourceLoader::startWithServiceWorker( WebSWServerConnection* swConnection)1236 void NetworkResourceLoader::startWithServiceWorker() 1227 1237 { 1228 1238 ASSERT(!m_serviceWorkerFetchTask); 1229 m_serviceWorkerFetchTask = swConnection ? swConnection->createFetchTask(*this) : nullptr;1239 m_serviceWorkerFetchTask = m_connection->swConnection().createFetchTask(*this, originalRequest()); 1230 1240 if (m_serviceWorkerFetchTask) 1231 1241 return; … … 1242 1252 } 1243 1253 1244 m_serviceWorkerFetchTask = nullptr; 1254 if (m_serviceWorkerFetchTask) { 1255 auto newRequest = m_serviceWorkerFetchTask->takeRequest(); 1256 m_serviceWorkerFetchTask = nullptr; 1257 1258 if (m_networkLoad) 1259 m_networkLoad->updateRequestAfterRedirection(newRequest); 1260 restartNetworkLoad(WTFMove(newRequest)); 1261 return; 1262 } 1245 1263 start(); 1246 1264 } -
trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.h
r251124 r251409 127 127 128 128 #if ENABLE(SERVICE_WORKER) 129 void startWithServiceWorker( WebSWServerConnection*);129 void startWithServiceWorker(); 130 130 void serviceWorkerDidNotHandle(); 131 131 #endif -
trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp
r251124 r251409 39 39 #include "WebResourceLoaderMessages.h" 40 40 #include "WebSWContextManagerConnectionMessages.h" 41 #include "WebSWServerConnection.h" 41 42 #include "WebSWServerToContextConnection.h" 42 43 #include <WebCore/CrossOriginAccessControl.h> … … 49 50 namespace WebKit { 50 51 51 ServiceWorkerFetchTask::ServiceWorkerFetchTask(PAL::SessionID sessionID, NetworkResourceLoader& loader, SWServerConnectionIdentifier serverConnectionIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier)52 ServiceWorkerFetchTask::ServiceWorkerFetchTask(PAL::SessionID sessionID, NetworkResourceLoader& loader, ResourceRequest&& request, SWServerConnectionIdentifier serverConnectionIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, ServiceWorkerRegistrationIdentifier serviceWorkerRegistrationIdentifier) 52 53 : m_sessionID(sessionID) 53 54 , m_loader(loader) … … 55 56 , m_serverConnectionIdentifier(serverConnectionIdentifier) 56 57 , m_serviceWorkerIdentifier(serviceWorkerIdentifier) 58 , m_currentRequest(WTFMove(request)) 57 59 , m_timeoutTimer(*this, &ServiceWorkerFetchTask::timeoutTimerFired) 58 60 { … … 81 83 serviceWorkerConnection.registerFetch(*this); 82 84 83 startFetch( ResourceRequest { m_loader.originalRequest() }, serviceWorkerConnection);85 startFetch(); 84 86 } 85 87 86 void ServiceWorkerFetchTask::startFetch( ResourceRequest&& request, WebSWServerToContextConnection& serviceWorkerConnection)88 void ServiceWorkerFetchTask::startFetch() 87 89 { 88 m_currentRequest = WTFMove(request);89 90 90 auto& options = m_loader.parameters().options; 91 91 auto referrer = m_currentRequest.httpReferrer(); 92 92 93 93 // We are intercepting fetch calls after going through the HTTP layer, which may add some specific headers. 94 cleanHTTPRequestHeadersForAccessControl(m_currentRequest, m_loader.parameters().httpHeadersToKeep); 94 auto request = m_currentRequest; 95 cleanHTTPRequestHeadersForAccessControl(request, m_loader.parameters().httpHeadersToKeep); 95 96 96 bool isSent = sendToServiceWorker(Messages::WebSWContextManagerConnection::StartFetch { m_serverConnectionIdentifier, m_serviceWorkerIdentifier, m_fetchIdentifier, m_currentRequest, options, IPC::FormDataReference { m_currentRequest.httpBody() }, referrer });97 bool isSent = sendToServiceWorker(Messages::WebSWContextManagerConnection::StartFetch { m_serverConnectionIdentifier, m_serviceWorkerIdentifier, m_fetchIdentifier, request, options, IPC::FormDataReference { m_currentRequest.httpBody() }, referrer }); 97 98 ASSERT_UNUSED(isSent, isSent); 98 99 } … … 170 171 return; 171 172 } 172 startFetch(WTFMove(request), *m_serviceWorkerConnection); 173 m_currentRequest = WTFMove(request); 174 startFetch(); 173 175 } 174 176 -
trunk/Source/WebKit/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.h
r251124 r251409 30 30 #include <WebCore/FetchIdentifier.h> 31 31 #include <WebCore/ResourceRequest.h> 32 #include <WebCore/ServiceWorkerClientIdentifier.h> 32 33 #include <WebCore/ServiceWorkerTypes.h> 33 34 #include <WebCore/Timer.h> … … 53 54 class WebSWServerToContextConnection; 54 55 55 class NetworkResourceLoader;56 class WebSWServerToContextConnection;57 58 56 class ServiceWorkerFetchTask : public CanMakeWeakPtr<ServiceWorkerFetchTask> { 59 57 WTF_MAKE_FAST_ALLOCATED; 60 58 public: 61 ServiceWorkerFetchTask(PAL::SessionID, NetworkResourceLoader&, WebCore:: SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier);59 ServiceWorkerFetchTask(PAL::SessionID, NetworkResourceLoader&, WebCore::ResourceRequest&&, WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::ServiceWorkerRegistrationIdentifier); 62 60 ~ServiceWorkerFetchTask(); 63 61 … … 75 73 void didNotHandle(); 76 74 75 WebCore::ResourceRequest takeRequest() { return WTFMove(m_currentRequest); } 77 76 bool wasHandled() const { return m_wasHandled; } 78 77 … … 85 84 void didFail(const WebCore::ResourceError&); 86 85 87 void startFetch( WebCore::ResourceRequest&&, WebSWServerToContextConnection&);86 void startFetch(); 88 87 89 88 void timeoutTimerFired(); -
trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp
r251278 r251409 129 129 } 130 130 131 std::unique_ptr<ServiceWorkerFetchTask> WebSWServerConnection::createFetchTask(NetworkResourceLoader& loader) 132 { 133 if (!loader.parameters().serviceWorkerRegistrationIdentifier) 134 return nullptr; 135 131 void WebSWServerConnection::controlClient(ServiceWorkerClientIdentifier clientIdentifier, SWServerRegistration& registration, const ResourceRequest& request) 132 { 133 // As per step 12 of https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm, the active service worker should be controlling the document. 134 // We register a temporary service worker client using the identifier provided by DocumentLoader and notify DocumentLoader about it. 135 // If notification is successful, DocumentLoader will unregister the temporary service worker client just after the document is created and registered as a client. 136 sendWithAsyncReply(Messages::WebSWClientConnection::SetDocumentIsControlled { clientIdentifier.contextIdentifier, registration.data() }, [weakThis = makeWeakPtr(this), this, clientIdentifier](bool isSuccess) { 137 if (!weakThis || isSuccess) 138 return; 139 unregisterServiceWorkerClient(clientIdentifier); 140 }); 141 142 ServiceWorkerClientData data { clientIdentifier, ServiceWorkerClientType::Window, ServiceWorkerClientFrameType::None, request.url() }; 143 registerServiceWorkerClient(SecurityOriginData { registration.key().topOrigin() }, WTFMove(data), registration.identifier(), request.httpUserAgent()); 144 } 145 146 std::unique_ptr<ServiceWorkerFetchTask> WebSWServerConnection::createFetchTask(NetworkResourceLoader& loader, const ResourceRequest& request) 147 { 136 148 if (loader.parameters().serviceWorkersMode == ServiceWorkersMode::None) 137 149 return nullptr; 138 150 139 if (isPotentialNavigationOrSubresourceRequest(loader.parameters().options.destination))140 return nullptr;141 142 151 if (!server().canHandleScheme(loader.originalRequest().url().protocol())) 143 152 return nullptr; 144 153 145 auto* worker = server().activeWorkerFromRegistrationID(*loader.parameters().serviceWorkerRegistrationIdentifier); 154 Optional<ServiceWorkerRegistrationIdentifier> serviceWorkerRegistrationIdentifier; 155 if (loader.parameters().options.mode == FetchOptions::Mode::Navigate) { 156 auto topOrigin = loader.parameters().isMainFrameNavigation ? SecurityOriginData::fromURL(request.url()) : loader.parameters().topOrigin->data(); 157 auto* registration = doRegistrationMatching(topOrigin, request.url()); 158 if (!registration) 159 return nullptr; 160 161 serviceWorkerRegistrationIdentifier = registration->identifier(); 162 controlClient(ServiceWorkerClientIdentifier { loader.connectionToWebProcess().webProcessIdentifier(), *loader.parameters().options.clientIdentifier }, *registration, request); 163 } else { 164 if (!loader.parameters().serviceWorkerRegistrationIdentifier) 165 return nullptr; 166 167 if (isPotentialNavigationOrSubresourceRequest(loader.parameters().options.destination)) 168 return nullptr; 169 170 serviceWorkerRegistrationIdentifier = *loader.parameters().serviceWorkerRegistrationIdentifier; 171 } 172 173 auto* worker = server().activeWorkerFromRegistrationID(*serviceWorkerRegistrationIdentifier); 146 174 if (!worker) { 147 SWSERVERCONNECTION_RELEASE_LOG_ERROR_IF_ALLOWED("startFetch: DidNotHandle because no active worker %s", loader.parameters().serviceWorkerRegistrationIdentifier->loggingString().utf8().data());175 SWSERVERCONNECTION_RELEASE_LOG_ERROR_IF_ALLOWED("startFetch: DidNotHandle because no active worker %s", serviceWorkerRegistrationIdentifier->loggingString().utf8().data()); 148 176 return nullptr; 149 177 } … … 156 184 } 157 185 158 auto task = makeUnique<ServiceWorkerFetchTask>(sessionID(), loader, identifier(), worker->identifier());186 auto task = makeUnique<ServiceWorkerFetchTask>(sessionID(), loader, ResourceRequest { request }, identifier(), worker->identifier(), *serviceWorkerRegistrationIdentifier); 159 187 startFetch(*task, *worker); 160 188 return task; -
trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h
r251124 r251409 69 69 PAL::SessionID sessionID() const; 70 70 71 std::unique_ptr<ServiceWorkerFetchTask> createFetchTask(NetworkResourceLoader& );71 std::unique_ptr<ServiceWorkerFetchTask> createFetchTask(NetworkResourceLoader&, const WebCore::ResourceRequest&); 72 72 73 73 private: … … 86 86 87 87 void scheduleJobInServer(WebCore::ServiceWorkerJobData&&); 88 89 bool handleFetch(NetworkResourceLoader&);90 88 91 89 void startFetch(ServiceWorkerFetchTask&, WebCore::SWServerWorker&); … … 109 107 110 108 void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, WebCore::MessageWithMessagePorts&&, const WebCore::ServiceWorkerOrClientIdentifier& source); 109 void controlClient(WebCore::ServiceWorkerClientIdentifier, WebCore::SWServerRegistration&, const WebCore::ResourceRequest&); 111 110 112 111 IPC::Connection* messageSenderConnection() const final { return m_contentConnection.ptr(); } -
trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp
r251361 r251409 138 138 #if ENABLE(SERVICE_WORKER) 139 139 if (decoder.messageReceiverName() == Messages::WebSWClientConnection::messageReceiverName()) { 140 if (m_swConnection) 141 m_swConnection->didReceiveMessage(connection, decoder); 140 serviceWorkerConnection().didReceiveMessage(connection, decoder); 142 141 return; 143 142 } -
trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
r251124 r251409 221 221 url.string(); 222 222 223 if ((resourceLoader.options().serviceWorkerRegistrationIdentifier && resourceLoader.options().serviceWorkersMode != ServiceWorkersMode::None) || !tryLoadingUsingURLSchemeHandler(resourceLoader)) { 223 bool canbeLoadedThroughServiceWorkers = resourceLoader.options().serviceWorkersMode != ServiceWorkersMode::None && (resourceLoader.options().serviceWorkerRegistrationIdentifier || resourceLoader.options().mode == FetchOptions::Mode::Navigate); 224 if (canbeLoadedThroughServiceWorkers || !tryLoadingUsingURLSchemeHandler(resourceLoader)) { 224 225 #else 225 226 if (!tryLoadingUsingURLSchemeHandler(resourceLoader)) { … … 288 289 #if ENABLE(SERVICE_WORKER) 289 290 // In case of URL scheme handler, we will try to load on service workers and if unhandled, fallback to URL scheme handler. 290 if ( resourceLoader.options().serviceWorkersMode == ServiceWorkersMode::All && webPage &&webPage->urlSchemeHandlerForScheme(resourceLoader.request().url().protocol().toStringWithoutCopying()))291 if (webPage && webPage->urlSchemeHandlerForScheme(resourceLoader.request().url().protocol().toStringWithoutCopying())) 291 292 loadParameters.serviceWorkersMode = ServiceWorkersMode::Only; 292 293 else -
trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp
r251152 r251409 41 41 #include "WebSWServerConnectionMessages.h" 42 42 #include <WebCore/Document.h> 43 #include <WebCore/DocumentLoader.h> 43 44 #include <WebCore/ProcessIdentifier.h> 44 45 #include <WebCore/SecurityOrigin.h> … … 59 60 , m_swOriginTable(makeUniqueRef<WebSWOriginTable>()) 60 61 { 61 send(Messages::NetworkConnectionToWebProcess::EstablishSWServerConnection { });62 62 } 63 63 … … 182 182 } 183 183 184 void WebSWClientConnection::registrationReady(uint64_t callbackID, WebCore::ServiceWorkerRegistrationData&& registrationData)184 void WebSWClientConnection::registrationReady(uint64_t callbackID, ServiceWorkerRegistrationData&& registrationData) 185 185 { 186 186 ASSERT(registrationData.activeWorker); 187 187 if (auto callback = m_ongoingRegistrationReadyTasks.take(callbackID)) 188 188 callback(WTFMove(registrationData)); 189 } 190 191 void WebSWClientConnection::setDocumentIsControlled(DocumentIdentifier documentIdentifier, ServiceWorkerRegistrationData&& data, CompletionHandler<void(bool)>&& completionHandler) 192 { 193 auto* documentLoader = DocumentLoader::fromTemporaryDocumentIdentifier(documentIdentifier); 194 bool result = documentLoader ? documentLoader->setControllingServiceWorkerRegistration(WTFMove(data)) : false; 195 completionHandler(result); 189 196 } 190 197 -
trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.h
r251124 r251409 80 80 void registrationReady(uint64_t callbackID, WebCore::ServiceWorkerRegistrationData&&); 81 81 82 void setDocumentIsControlled(WebCore::DocumentIdentifier, WebCore::ServiceWorkerRegistrationData&&, CompletionHandler<void(bool)>&&); 83 82 84 void getRegistrations(WebCore::SecurityOriginData&& topOrigin, const URL& clientURL, GetRegistrationsCallback&&) final; 83 85 -
trunk/Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in
r239427 r251409 43 43 DidGetRegistrations(uint64_t matchRequestIdentifier, Vector<WebCore::ServiceWorkerRegistrationData> registrations) 44 44 RegistrationReady(uint64_t registrationReadyRequestIdentifier, struct WebCore::ServiceWorkerRegistrationData data) 45 46 SetDocumentIsControlled(WebCore::DocumentIdentifier temporaryDocumentIdentifier, struct WebCore::ServiceWorkerRegistrationData data) -> (bool isSuccess) Async 45 47 } 46 48 -
trunk/Tools/ChangeLog
r251407 r251409 1 2019-10-21 youenn fablet <youenn@apple.com> 2 3 Move service worker registration matching for navigation loads to network process 4 https://bugs.webkit.org/show_bug.cgi?id=203144 5 6 Reviewed by Chris Dumez. 7 8 * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm: 9 We are now creating a WebSWClientConnection whenever receiving a WebSWClientConnection message 10 from NetworkProcess. It is free to do so given it no longer requires sending some IPC. 11 Update the tests accordingly. 12 A future patch will remove the service worker registration bit feature and corresponding test. 13 1 14 2019-10-21 Simon Fraser <simon.fraser@apple.com> 2 15 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm
r251384 r251409 865 865 @end 866 866 867 static const char* regularPageWithoutConnectionBytes = R"SWRESOURCE(868 <script>869 var result = window.internals.hasServiceWorkerConnection() ? "FAIL" : "PASS";870 window.webkit.messageHandlers.regularPage.postMessage(result);871 </script>872 )SWRESOURCE";873 874 867 static const char* regularPageWithConnectionBytes = R"SWRESOURCE( 875 868 <script> … … 908 901 909 902 ServiceWorkerTCPServer server({ 910 { "text/html", regularPageWith outConnectionBytes },903 { "text/html", regularPageWithConnectionBytes }, 911 904 { "text/html", mainBytes }, 912 905 { "application/javascript", scriptBytes }, … … 1091 1084 { "application/javascript", scriptBytes }, 1092 1085 }, { 1093 { "text/html", regularPageWith outConnectionBytes },1086 { "text/html", regularPageWithConnectionBytes }, 1094 1087 }, { 1095 1088 { "text/html", regularPageWithConnectionBytes }
Note: See TracChangeset
for help on using the changeset viewer.