Service Worker Fetch events should time out.
[WebKit-https.git] / Source / WebKit / NetworkProcess / ServiceWorker / ServiceWorkerFetchTask.h
1 /*
2  * Copyright (C) 2019 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 #pragma once
27
28 #if ENABLE(SERVICE_WORKER)
29
30 #include <WebCore/FetchIdentifier.h>
31 #include <WebCore/ServiceWorkerTypes.h>
32 #include <WebCore/Timer.h>
33 #include <pal/SessionID.h>
34 #include <wtf/RefCounted.h>
35
36 namespace WebCore {
37 class ResourceError;
38 class ResourceResponse;
39 }
40
41 namespace IPC {
42 class Connection;
43 class DataReference;
44 class Decoder;
45 class FormDataReference;
46 }
47
48 namespace WebKit {
49
50 class WebSWServerConnection;
51 class WebSWServerToContextConnection;
52
53 class ServiceWorkerFetchTask : public RefCounted<ServiceWorkerFetchTask> {
54 public:
55     template<typename... Args> static Ref<ServiceWorkerFetchTask> create(Args&&... args)
56     {
57         return adoptRef(*new ServiceWorkerFetchTask(std::forward<Args>(args)...));
58     }
59
60     void didNotHandle();
61     void fail(const WebCore::ResourceError& error) { didFail(error); }
62     void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
63
64     struct Identifier {
65         WebCore::SWServerConnectionIdentifier connectionIdentifier;
66         WebCore::FetchIdentifier fetchIdentifier;
67         
68         unsigned hash() const
69         {
70             unsigned hashes[2];
71             hashes[0] = WTF::intHash(connectionIdentifier.toUInt64());
72             hashes[1] = WTF::intHash(fetchIdentifier.toUInt64());
73             return StringHasher::hashMemory(hashes, sizeof(hashes));
74         }
75     };
76
77     const Identifier& identifier() const { return m_identifier; }
78     const WebCore::ServiceWorkerIdentifier& serviceWorkerIdentifier() const { return m_serviceWorkerIdentifier; }
79     bool wasHandled() const { return m_wasHandled; }
80
81 private:
82     ServiceWorkerFetchTask(PAL::SessionID, WebSWServerConnection&, WebSWServerToContextConnection&, WebCore::FetchIdentifier, WebCore::ServiceWorkerIdentifier, Seconds timeout);
83
84     void didReceiveRedirectResponse(const WebCore::ResourceResponse&);
85     void didReceiveResponse(const WebCore::ResourceResponse&, bool needsContinueDidReceiveResponseMessage);
86     void didReceiveData(const IPC::DataReference&, int64_t encodedDataLength);
87     void didReceiveFormData(const IPC::FormDataReference&);
88     void didFinish();
89     void didFail(const WebCore::ResourceError&);
90     void timeoutTimerFired();
91
92     PAL::SessionID m_sessionID;
93     WeakPtr<WebSWServerConnection> m_connection;
94     WebSWServerToContextConnection& m_contextConnection;
95     Identifier m_identifier;
96     WebCore::ServiceWorkerIdentifier m_serviceWorkerIdentifier;
97     Seconds m_timeout;
98     WebCore::Timer m_timeoutTimer;
99     bool m_wasHandled { false };
100     bool m_didReachTerminalState { false };
101 };
102
103 inline bool operator==(const ServiceWorkerFetchTask::Identifier& a, const ServiceWorkerFetchTask::Identifier& b)
104 {
105     return a.connectionIdentifier == b.connectionIdentifier &&  a.fetchIdentifier == b.fetchIdentifier;
106 }
107
108 } // namespace WebKit
109
110
111 namespace WTF {
112
113 struct ServiceWorkerFetchTaskIdentifierHash {
114     static unsigned hash(const WebKit::ServiceWorkerFetchTask::Identifier& key) { return key.hash(); }
115     static bool equal(const WebKit::ServiceWorkerFetchTask::Identifier& a, const WebKit::ServiceWorkerFetchTask::Identifier& b) { return a == b; }
116     static const bool safeToCompareToEmptyOrDeleted = true;
117 };
118
119 template<> struct HashTraits<WebKit::ServiceWorkerFetchTask::Identifier> : GenericHashTraits<WebKit::ServiceWorkerFetchTask::Identifier> {
120     static WebKit::ServiceWorkerFetchTask::Identifier emptyValue() { return { }; }
121     
122     static void constructDeletedValue(WebKit::ServiceWorkerFetchTask::Identifier& slot) { slot.connectionIdentifier = makeObjectIdentifier<WebCore::SWServerConnectionIdentifierType>(std::numeric_limits<uint64_t>::max()); }
123     
124     static bool isDeletedValue(const WebKit::ServiceWorkerFetchTask::Identifier& slot) { return slot.connectionIdentifier.toUInt64() == std::numeric_limits<uint64_t>::max(); }
125 };
126
127 template<> struct DefaultHash<WebKit::ServiceWorkerFetchTask::Identifier> {
128     using Hash = ServiceWorkerFetchTaskIdentifierHash;
129 };
130
131 }
132
133 #endif // ENABLE(SERVICE_WORKER)