Changeset 227348 in webkit


Ignore:
Timestamp:
Jan 22, 2018 12:22:43 PM (6 years ago)
Author:
Chris Dumez
Message:

Safari Tech Preview can't use GitHub login at forums.swift.org
https://bugs.webkit.org/show_bug.cgi?id=181908
<rdar://problem/36715111>

Patch by Youenn Fablet <youenn@apple.com> on 2018-01-22
Reviewed by Chris Dumez.

Source/WebCore:

Test: http/wpt/service-workers/navigation-redirect.https.html

For subresource loads, redirections will not change who is in charge of continuing the load (service worker or network process).
For navigation loads, we need to match the registration for every redirection since this is using the Manual redirect mode.
This allows starting the load with a service worker and finishing the load with another service worker, which will become the controller.

Implement this by wrapping the registration matching of an URL within DocumentLoader::matchRegistration.
Use that method in DocumentLoader::redirectReceived.

  • loader/DocumentLoader.cpp:

(WebCore::DocumentLoader::matchRegistration):
(WebCore::doRegistrationsMatch):
(WebCore::DocumentLoader::redirectReceived):
(WebCore::DocumentLoader::startLoadingMainResource):

  • loader/DocumentLoader.h:

LayoutTests:

  • http/wpt/service-workers/navigation-redirect-worker.js: Added.

(async):

  • http/wpt/service-workers/navigation-redirect.https-expected.txt: Added.
  • http/wpt/service-workers/navigation-redirect.https.html: Added.
Location:
trunk
Files:
3 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r227346 r227348  
     12018-01-22  Youenn Fablet  <youenn@apple.com>
     2
     3        Safari Tech Preview can't use GitHub login at forums.swift.org
     4        https://bugs.webkit.org/show_bug.cgi?id=181908
     5        <rdar://problem/36715111>
     6
     7        Reviewed by Chris Dumez.
     8
     9        * http/wpt/service-workers/navigation-redirect-worker.js: Added.
     10        (async):
     11        * http/wpt/service-workers/navigation-redirect.https-expected.txt: Added.
     12        * http/wpt/service-workers/navigation-redirect.https.html: Added.
     13
    1142018-01-22  Antti Koivisto  <antti@apple.com>
    215
  • trunk/Source/WebCore/ChangeLog

    r227346 r227348  
     12018-01-22  Youenn Fablet  <youenn@apple.com>
     2
     3        Safari Tech Preview can't use GitHub login at forums.swift.org
     4        https://bugs.webkit.org/show_bug.cgi?id=181908
     5        <rdar://problem/36715111>
     6
     7        Reviewed by Chris Dumez.
     8
     9        Test: http/wpt/service-workers/navigation-redirect.https.html
     10
     11        For subresource loads, redirections will not change who is in charge of continuing the load (service worker or network process).
     12        For navigation loads, we need to match the registration for every redirection since this is using the Manual redirect mode.
     13        This allows starting the load with a service worker and finishing the load with another service worker, which will become the controller.
     14
     15        Implement this by wrapping the registration matching of an URL within DocumentLoader::matchRegistration.
     16        Use that method in DocumentLoader::redirectReceived.
     17
     18        * loader/DocumentLoader.cpp:
     19        (WebCore::DocumentLoader::matchRegistration):
     20        (WebCore::doRegistrationsMatch):
     21        (WebCore::DocumentLoader::redirectReceived):
     22        (WebCore::DocumentLoader::startLoadingMainResource):
     23        * loader/DocumentLoader.h:
     24
    1252018-01-22  Antti Koivisto  <antti@apple.com>
    226
  • trunk/Source/WebCore/loader/DocumentLoader.cpp

    r227242 r227348  
    483483}
    484484
     485#if ENABLE(SERVICE_WORKER)
     486void DocumentLoader::matchRegistration(const URL& url, SWClientConnection::RegistrationCallback&& callback)
     487{
     488    auto shouldTryLoadingThroughServiceWorker = !frameLoader()->isReloadingFromOrigin() && m_frame->page() && RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled() && SchemeRegistry::canServiceWorkersHandleURLScheme(url.protocol().toStringWithoutCopying());
     489    if (!shouldTryLoadingThroughServiceWorker) {
     490        callback(std::nullopt);
     491        return;
     492    }
     493
     494    auto origin = (!m_frame->isMainFrame() && m_frame->document()) ? makeRef(m_frame->document()->topOrigin()) : SecurityOrigin::create(url);
     495    auto sessionID = m_frame->page()->sessionID();
     496    auto& provider = ServiceWorkerProvider::singleton();
     497    if (!provider.mayHaveServiceWorkerRegisteredForOrigin(sessionID, origin)) {
     498        callback(std::nullopt);
     499        return;
     500    }
     501
     502    auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(sessionID);
     503    connection.matchRegistration(origin, url, WTFMove(callback));
     504}
     505
     506static inline bool areRegistrationsEqual(const std::optional<ServiceWorkerRegistrationData>& a, const std::optional<ServiceWorkerRegistrationData>& b)
     507{
     508    if (!a)
     509        return !b;
     510    if (!b)
     511        return false;
     512    return a->identifier == b->identifier;
     513}
     514#endif
     515
    485516void DocumentLoader::redirectReceived(CachedResource& resource, ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
    486517{
    487518    ASSERT_UNUSED(resource, &resource == m_mainResource);
     519#if ENABLE(SERVICE_WORKER)
     520    willSendRequest(WTFMove(request), redirectResponse, [completionHandler = WTFMove(completionHandler), protectedThis = makeRef(*this), this] (auto&& request) mutable {
     521        if (request.isNull() || !m_mainDocumentError.isNull() || !m_frame) {
     522            completionHandler({ });
     523            return;
     524        }
     525        auto url = request.url();
     526        matchRegistration(url, [request = WTFMove(request), completionHandler = WTFMove(completionHandler), protectedThis = WTFMove(protectedThis), this] (auto&& registrationData) mutable {
     527            if (!m_mainDocumentError.isNull() || !m_frame) {
     528                completionHandler({ });
     529                return;
     530            }
     531
     532            if (areRegistrationsEqual(m_serviceWorkerRegistrationData, registrationData)) {
     533                completionHandler(WTFMove(request));
     534                return;
     535            }
     536
     537            // Service worker registration changed, we need to cancel the current load to restart a new one.
     538            clearMainResource();
     539            completionHandler({ });
     540
     541            m_serviceWorkerRegistrationData = WTFMove(registrationData);
     542            loadMainResource(WTFMove(request));
     543            return;
     544        });
     545    });
     546#else
    488547    willSendRequest(WTFMove(request), redirectResponse, WTFMove(completionHandler));
     548#endif
    489549}
    490550
     
    15871647#if ENABLE(SERVICE_WORKER)
    15881648        // FIXME: Implement local URL interception by getting the service worker of the parent.
    1589         auto tryLoadingThroughServiceWorker = !frameLoader()->isReloadingFromOrigin() && m_frame->page() && RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled() && SchemeRegistry::canServiceWorkersHandleURLScheme(request.url().protocol().toStringWithoutCopying());
    1590         if (tryLoadingThroughServiceWorker) {
    1591             auto origin = (!m_frame->isMainFrame() && m_frame->document()) ? makeRef(m_frame->document()->topOrigin()) : SecurityOrigin::create(request.url());
    1592             auto sessionID = m_frame->page()->sessionID();
    1593             auto& provider = ServiceWorkerProvider::singleton();
    1594             if (provider.mayHaveServiceWorkerRegisteredForOrigin(sessionID, origin)) {
    1595                 auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(sessionID);
    1596                 auto url = request.url();
    1597                 connection.matchRegistration(origin, url, [request = WTFMove(request), protectedThis = WTFMove(protectedThis), this] (auto&& registrationData) mutable {
    1598                     if (!m_mainDocumentError.isNull() || !m_frame)
    1599                         return;
    1600 
    1601                     m_serviceWorkerRegistrationData = WTFMove(registrationData);
    1602                     loadMainResource(WTFMove(request));
    1603                 });
     1649        auto url = request.url();
     1650        matchRegistration(url, [request = WTFMove(request), protectedThis = WTFMove(protectedThis), this] (auto&& registrationData) mutable {
     1651            if (!m_mainDocumentError.isNull() || !m_frame)
    16041652                return;
    1605             }
    1606         }
    1607 #endif
     1653
     1654            m_serviceWorkerRegistrationData = WTFMove(registrationData);
     1655            loadMainResource(WTFMove(request));
     1656        });
     1657#else
    16081658        loadMainResource(WTFMove(request));
     1659#endif
    16091660    });
    16101661}
  • trunk/Source/WebCore/loader/DocumentLoader.h

    r226984 r227348  
    330330    Document* document() const;
    331331
     332#if ENABLE(SERVICE_WORKER)
     333    void matchRegistration(const URL&, CompletionHandler<void(std::optional<ServiceWorkerRegistrationData>&&)>&&);
     334#endif
     335
    332336    void loadMainResource(ResourceRequest&&);
    333337
Note: See TracChangeset for help on using the changeset viewer.