837df51da8ec8e6d96be6f26c305b58504c0bbc0
[WebKit-https.git] / Source / WebKit / WebProcess / Storage / WebServiceWorkerProvider.cpp
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebServiceWorkerProvider.h"
28
29 #if ENABLE(SERVICE_WORKER)
30
31 #include "WebProcess.h"
32 #include "WebSWServerConnection.h"
33 #include "WebToStorageProcessConnection.h"
34 #include <WebCore/CachedResource.h>
35 #include <WebCore/Exception.h>
36 #include <WebCore/ExceptionCode.h>
37 #include <WebCore/ServiceWorkerJob.h>
38 #include <pal/SessionID.h>
39 #include <wtf/text/WTFString.h>
40
41 using namespace PAL;
42 using namespace WebCore;
43
44 namespace WebKit {
45
46 WebServiceWorkerProvider& WebServiceWorkerProvider::singleton()
47 {
48     static NeverDestroyed<WebServiceWorkerProvider> provider;
49     return provider;
50 }
51
52 WebServiceWorkerProvider::WebServiceWorkerProvider()
53 {
54 }
55
56 WebCore::SWClientConnection& WebServiceWorkerProvider::serviceWorkerConnectionForSession(SessionID sessionID)
57 {
58     ASSERT(WebProcess::singleton().webToStorageProcessConnection());
59     return WebProcess::singleton().webToStorageProcessConnection()->serviceWorkerConnectionForSession(sessionID);
60 }
61
62 static inline bool shouldHandleFetch(const WebSWClientConnection& connection, CachedResource* resource, const ResourceLoaderOptions& options)
63 {
64     if (options.serviceWorkersMode != ServiceWorkersMode::All)
65         return false;
66
67     if (isPotentialNavigationOrSubresourceRequest(options.destination))
68         return false;
69
70     // FIXME: Implement non-subresource request loads.
71     if (isNonSubresourceRequest(options.destination) || !options.serviceWorkerIdentifier)
72         return false;
73
74     if (!resource)
75         return false;
76
77     return connection.hasServiceWorkerRegisteredForOrigin(*resource->origin());
78 }
79
80 void WebServiceWorkerProvider::handleFetch(ResourceLoader& loader, CachedResource* resource, PAL::SessionID sessionID, ServiceWorkerClientFetch::Callback&& callback)
81 {
82     auto& connection = WebProcess::singleton().webToStorageProcessConnection()->serviceWorkerConnectionForSession(sessionID);
83
84     if (!shouldHandleFetch(connection, resource, loader.options())) {
85         // FIXME: Add an option to error resource load for DTL to actually go through preflight.
86         callback(ServiceWorkerClientFetch::Result::Unhandled);
87         return;
88     }
89
90     auto fetch = connection.startFetch(*this, loader, loader.identifier(), WTFMove(callback));
91     ASSERT(fetch->isOngoing());
92
93     m_ongoingFetchTasks.add(loader.identifier(), WTFMove(fetch));
94 }
95
96 bool WebServiceWorkerProvider::cancelFetch(uint64_t fetchIdentifier)
97 {
98     auto fetch = m_ongoingFetchTasks.take(fetchIdentifier);
99     if (fetch)
100         (*fetch)->cancel();
101     return !!fetch;
102 }
103
104 void WebServiceWorkerProvider::fetchFinished(uint64_t fetchIdentifier)
105 {
106     m_ongoingFetchTasks.take(fetchIdentifier);
107 }
108
109 void WebServiceWorkerProvider::didReceiveServiceWorkerClientFetchMessage(IPC::Connection& connection, IPC::Decoder& decoder)
110 {
111     if (auto fetch = m_ongoingFetchTasks.get(decoder.destinationID()))
112         fetch->didReceiveMessage(connection, decoder);
113 }
114
115 } // namespace WebKit
116
117 #endif // ENABLE(SERVICE_WORKER)