OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "config.h" | |
6 #include "modules/serviceworkers/InspectorServiceWorkerCacheAgent.h" | |
7 | |
8 #include "core/InspectorBackendDispatcher.h" | |
9 #include "core/InspectorTypeBuilder.h" | |
10 #include "modules/serviceworkers/ServiceWorkerGlobalScope.h" | |
11 #include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h" | |
12 #include "platform/JSONValues.h" | |
13 #include "platform/heap/Handle.h" | |
14 #include "platform/weborigin/DatabaseIdentifier.h" | |
15 #include "public/platform/Platform.h" | |
16 #include "public/platform/WebServiceWorkerCache.h" | |
17 #include "public/platform/WebServiceWorkerCacheError.h" | |
18 #include "public/platform/WebServiceWorkerCacheStorage.h" | |
19 #include "public/platform/WebServiceWorkerRequest.h" | |
20 #include "public/platform/WebServiceWorkerResponse.h" | |
21 #include "public/platform/WebString.h" | |
22 #include "public/platform/WebURL.h" | |
23 #include "public/platform/WebVector.h" | |
24 #include "wtf/Noncopyable.h" | |
25 #include "wtf/OwnPtr.h" | |
26 #include "wtf/PassRefPtr.h" | |
27 #include "wtf/RefCounted.h" | |
28 #include "wtf/RefPtr.h" | |
29 #include "wtf/Vector.h" | |
30 #include "wtf/text/StringBuilder.h" | |
31 | |
32 #include <algorithm> | |
33 | |
34 using blink::TypeBuilder::Array; | |
35 using blink::TypeBuilder::ServiceWorkerCache::DataEntry; | |
36 | |
37 typedef blink::InspectorBackendDispatcher::ServiceWorkerCacheCommandHandler::Del
eteCacheCallback DeleteCacheCallback; | |
38 typedef blink::InspectorBackendDispatcher::ServiceWorkerCacheCommandHandler::Req
uestCacheNamesCallback RequestCacheNamesCallback; | |
39 typedef blink::InspectorBackendDispatcher::ServiceWorkerCacheCommandHandler::Req
uestEntriesCallback RequestEntriesCallback; | |
40 typedef blink::InspectorBackendDispatcher::CallbackBase RequestCallback; | |
41 | |
42 namespace blink { | |
43 | |
44 namespace { | |
45 | |
46 PassOwnPtr<WebServiceWorkerCacheStorage> assertCacheStorage(ErrorString* errorSt
ring, ServiceWorkerGlobalScope* globalScope) | |
47 { | |
48 String identifier = createDatabaseIdentifierFromSecurityOrigin(globalScope->
securityOrigin()); | |
49 OwnPtr<WebServiceWorkerCacheStorage> caches = adoptPtr(Platform::current()->
cacheStorage(identifier)); | |
50 if (!caches) { | |
51 *errorString = "Cache Storage not available in global scope."; | |
52 return nullptr; | |
53 } | |
54 return caches.release(); | |
55 } | |
56 | |
57 CString serviceWorkerCacheErrorString(WebServiceWorkerCacheError* error) | |
58 { | |
59 switch (*error) { | |
60 case WebServiceWorkerCacheErrorNotImplemented: | |
61 return CString("not implemented."); | |
62 break; | |
63 case WebServiceWorkerCacheErrorNotFound: | |
64 return CString("not found."); | |
65 break; | |
66 case WebServiceWorkerCacheErrorExists: | |
67 return CString("cache already exists."); | |
68 break; | |
69 default: | |
70 return CString("unknown error."); | |
71 break; | |
72 } | |
73 } | |
74 | |
75 class RequestCacheNames | |
76 : public WebServiceWorkerCacheStorage::CacheStorageKeysCallbacks { | |
77 WTF_MAKE_NONCOPYABLE(RequestCacheNames); | |
78 | |
79 public: | |
80 RequestCacheNames(PassRefPtrWillBeRawPtr<RequestCacheNamesCallback> callback
) | |
81 : m_callback(callback) | |
82 { | |
83 } | |
84 | |
85 virtual ~RequestCacheNames() { } | |
86 | |
87 void onSuccess(WebVector<WebString>* caches) | |
88 { | |
89 RefPtr<TypeBuilder::Array<String>> array = TypeBuilder::Array<String>::c
reate(); | |
90 for (size_t i = 0; i < caches->size(); i++) { | |
91 array->addItem(String((*caches)[i])); | |
92 } | |
93 m_callback->sendSuccess(array); | |
94 } | |
95 | |
96 void onError(WebServiceWorkerCacheError* error) | |
97 { | |
98 m_callback->sendFailure(String::format("Error requesting cache names: %s
", serviceWorkerCacheErrorString(error).data())); | |
99 } | |
100 | |
101 private: | |
102 RefPtrWillBePersistent<RequestCacheNamesCallback> m_callback; | |
103 }; | |
104 | |
105 struct DataRequestParams { | |
106 String cacheName; | |
107 int skipCount; | |
108 int pageSize; | |
109 }; | |
110 | |
111 struct RequestResponse { | |
112 RequestResponse() { } | |
113 RequestResponse(const String& request, const String& response) | |
114 : request(request) | |
115 , response(response) | |
116 { | |
117 } | |
118 String request; | |
119 String response; | |
120 }; | |
121 | |
122 class ResponsesAccumulator : public RefCounted<ResponsesAccumulator> { | |
123 WTF_MAKE_NONCOPYABLE(ResponsesAccumulator); | |
124 | |
125 public: | |
126 ResponsesAccumulator(int numResponses, const DataRequestParams& params, Pass
RefPtrWillBeRawPtr<RequestEntriesCallback> callback) | |
127 : m_params(params) | |
128 , m_numResponsesLeft(numResponses) | |
129 , m_responses(static_cast<size_t>(numResponses)) | |
130 , m_callback(callback) | |
131 { | |
132 } | |
133 | |
134 void addRequestResponsePair(const WebServiceWorkerRequest& request, const We
bServiceWorkerResponse& response) | |
135 { | |
136 ASSERT(m_numResponsesLeft > 0); | |
137 RequestResponse& requestResponse = m_responses.at(m_responses.size() - m
_numResponsesLeft); | |
138 requestResponse.request = request.url().string(); | |
139 requestResponse.response = response.statusText(); | |
140 | |
141 if (--m_numResponsesLeft != 0) | |
142 return; | |
143 | |
144 std::sort(m_responses.begin(), m_responses.end(), | |
145 [](const RequestResponse& a, const RequestResponse& b) | |
146 { | |
147 return WTF::codePointCompareLessThan(a.request, b.request); | |
148 }); | |
149 if (m_params.skipCount > 0) | |
150 m_responses.remove(0, m_params.skipCount); | |
151 bool hasMore = false; | |
152 if (static_cast<size_t>(m_params.pageSize) < m_responses.size()) { | |
153 m_responses.remove(m_params.pageSize, m_responses.size() - m_params.
pageSize); | |
154 hasMore = true; | |
155 } | |
156 RefPtr<TypeBuilder::Array<DataEntry>> array = TypeBuilder::Array<DataEnt
ry>::create(); | |
157 for (const auto& requestResponse : m_responses) { | |
158 RefPtr<DataEntry> entry = DataEntry::create() | |
159 .setRequest(JSONString::create(requestResponse.request)->toJSONS
tring()) | |
160 .setResponse(JSONString::create(requestResponse.response)->toJSO
NString()); | |
161 array->addItem(entry); | |
162 } | |
163 m_callback->sendSuccess(array, hasMore); | |
164 } | |
165 | |
166 private: | |
167 DataRequestParams m_params; | |
168 int m_numResponsesLeft; | |
169 Vector<RequestResponse> m_responses; | |
170 RefPtrWillBePersistent<RequestEntriesCallback> m_callback; | |
171 }; | |
172 | |
173 class GetCacheResponsesForRequestData : public WebServiceWorkerCache::CacheMatch
Callbacks { | |
174 WTF_MAKE_NONCOPYABLE(GetCacheResponsesForRequestData); | |
175 | |
176 public: | |
177 GetCacheResponsesForRequestData( | |
178 const DataRequestParams& params, const WebServiceWorkerRequest& request, | |
179 PassRefPtr<ResponsesAccumulator> accum, PassRefPtrWillBeRawPtr<RequestEn
triesCallback> callback) | |
180 : m_params(params) | |
181 , m_request(request) | |
182 , m_accumulator(accum) | |
183 , m_callback(callback) | |
184 { | |
185 } | |
186 virtual ~GetCacheResponsesForRequestData() { } | |
187 | |
188 void onSuccess(WebServiceWorkerResponse* response) | |
189 { | |
190 m_accumulator->addRequestResponsePair(m_request, *response); | |
191 } | |
192 | |
193 void onError(WebServiceWorkerCacheError* error) | |
194 { | |
195 m_callback->sendFailure(String::format("Error requesting responses for c
ache %s: %s", m_params.cacheName.utf8().data(), serviceWorkerCacheErrorString(e
rror).data())); | |
196 } | |
197 | |
198 private: | |
199 DataRequestParams m_params; | |
200 WebServiceWorkerRequest m_request; | |
201 RefPtr<ResponsesAccumulator> m_accumulator; | |
202 RefPtrWillBePersistent<RequestEntriesCallback> m_callback; | |
203 }; | |
204 | |
205 class GetCacheKeysForRequestData : public WebServiceWorkerCache::CacheWithReques
tsCallbacks { | |
206 WTF_MAKE_NONCOPYABLE(GetCacheKeysForRequestData); | |
207 | |
208 public: | |
209 GetCacheKeysForRequestData(const DataRequestParams& params, PassOwnPtr<WebSe
rviceWorkerCache> cache, PassRefPtrWillBeRawPtr<RequestEntriesCallback> callback
) | |
210 : m_params(params) | |
211 , m_cache(cache) | |
212 , m_callback(callback) | |
213 { | |
214 } | |
215 virtual ~GetCacheKeysForRequestData() { } | |
216 | |
217 void onSuccess(WebVector<WebServiceWorkerRequest>* requests) | |
218 { | |
219 RefPtr<ResponsesAccumulator> accumulator = adoptRef(new ResponsesAccumul
ator(requests->size(), m_params, m_callback)); | |
220 | |
221 for (size_t i = 0; i < requests->size(); i++) { | |
222 const auto& request = (*requests)[i]; | |
223 auto* cacheRequest = new GetCacheResponsesForRequestData(m_params, r
equest, accumulator, m_callback); | |
224 m_cache->dispatchMatch(cacheRequest, request, WebServiceWorkerCache:
:QueryParams()); | |
225 } | |
226 } | |
227 | |
228 void onError(WebServiceWorkerCacheError* error) | |
229 { | |
230 m_callback->sendFailure(String::format("Error requesting requests for ca
che %s: %s", m_params.cacheName.utf8().data(), serviceWorkerCacheErrorString(err
or).data())); | |
231 } | |
232 | |
233 private: | |
234 DataRequestParams m_params; | |
235 OwnPtr<WebServiceWorkerCache> m_cache; | |
236 RefPtrWillBePersistent<RequestEntriesCallback> m_callback; | |
237 }; | |
238 | |
239 class GetCacheForRequestData | |
240 : public WebServiceWorkerCacheStorage::CacheStorageWithCacheCallbacks { | |
241 WTF_MAKE_NONCOPYABLE(GetCacheForRequestData); | |
242 | |
243 public: | |
244 GetCacheForRequestData(const DataRequestParams& params, PassRefPtrWillBeRawP
tr<RequestEntriesCallback> callback) | |
245 : m_params(params) | |
246 , m_callback(callback) | |
247 { | |
248 } | |
249 virtual ~GetCacheForRequestData() { } | |
250 | |
251 void onSuccess(WebServiceWorkerCache* cache) | |
252 { | |
253 auto* cacheRequest = new GetCacheKeysForRequestData(m_params, adoptPtr(c
ache), m_callback); | |
254 cache->dispatchKeys(cacheRequest, nullptr, WebServiceWorkerCache::QueryP
arams()); | |
255 } | |
256 | |
257 void onError(WebServiceWorkerCacheError* error) | |
258 { | |
259 m_callback->sendFailure(String::format("Error requesting cache %s: %s",
m_params.cacheName.utf8().data(), serviceWorkerCacheErrorString(error).data())); | |
260 } | |
261 | |
262 private: | |
263 DataRequestParams m_params; | |
264 RefPtrWillBePersistent<RequestEntriesCallback> m_callback; | |
265 }; | |
266 | |
267 class DeleteCache : public WebServiceWorkerCacheStorage::CacheStorageCallbacks { | |
268 WTF_MAKE_NONCOPYABLE(DeleteCache); | |
269 | |
270 public: | |
271 DeleteCache(PassRefPtrWillBeRawPtr<DeleteCacheCallback> callback) | |
272 : m_callback(callback) | |
273 { | |
274 } | |
275 virtual ~DeleteCache() { } | |
276 | |
277 void onSuccess() | |
278 { | |
279 m_callback->sendSuccess(); | |
280 } | |
281 | |
282 void onError(WebServiceWorkerCacheError* error) | |
283 { | |
284 m_callback->sendFailure(String::format("Error requesting cache names: %s
", serviceWorkerCacheErrorString(error).data())); | |
285 } | |
286 | |
287 private: | |
288 RefPtrWillBePersistent<DeleteCacheCallback> m_callback; | |
289 }; | |
290 | |
291 } // namespace | |
292 | |
293 InspectorServiceWorkerCacheAgent::InspectorServiceWorkerCacheAgent(ServiceWorker
GlobalScope* scope) | |
294 : InspectorBaseAgent<blink::InspectorServiceWorkerCacheAgent, InspectorFront
end::ServiceWorkerCache>("ServiceWorkerCache") | |
295 , m_globalScope(scope) | |
296 { | |
297 } | |
298 | |
299 InspectorServiceWorkerCacheAgent::~InspectorServiceWorkerCacheAgent() { } | |
300 | |
301 DEFINE_TRACE(InspectorServiceWorkerCacheAgent) | |
302 { | |
303 InspectorBaseAgent::trace(visitor); | |
304 } | |
305 | |
306 void InspectorServiceWorkerCacheAgent::requestCacheNames(ErrorString* errorStrin
g, PassRefPtrWillBeRawPtr<RequestCacheNamesCallback> callback) | |
307 { | |
308 OwnPtr<WebServiceWorkerCacheStorage> cache = assertCacheStorage(errorString,
m_globalScope); | |
309 if (!cache) { | |
310 callback->sendFailure(*errorString); | |
311 return; | |
312 } | |
313 cache->dispatchKeys(new RequestCacheNames(callback)); | |
314 } | |
315 | |
316 | |
317 void InspectorServiceWorkerCacheAgent::requestEntries(ErrorString* errorString,
const String& cacheName, int skipCount, int pageSize, PassRefPtrWillBeRawPtr<Req
uestEntriesCallback> callback) | |
318 { | |
319 OwnPtr<WebServiceWorkerCacheStorage> cache = assertCacheStorage(errorString,
m_globalScope); | |
320 if (!cache) { | |
321 callback->sendFailure(*errorString); | |
322 return; | |
323 } | |
324 DataRequestParams params; | |
325 params.cacheName = cacheName; | |
326 params.pageSize = pageSize; | |
327 params.skipCount = skipCount; | |
328 cache->dispatchOpen(new GetCacheForRequestData(params, callback), WebString(
cacheName)); | |
329 } | |
330 | |
331 void InspectorServiceWorkerCacheAgent::deleteCache(ErrorString* errorString, con
st String& cacheName, PassRefPtrWillBeRawPtr<DeleteCacheCallback> callback) | |
332 { | |
333 OwnPtr<WebServiceWorkerCacheStorage> cache = assertCacheStorage(errorString,
m_globalScope); | |
334 if (!cache) { | |
335 callback->sendFailure(*errorString); | |
336 return; | |
337 } | |
338 cache->dispatchDelete(new DeleteCache(callback), WebString(cacheName)); | |
339 } | |
340 | |
341 } // namespace blink | |
OLD | NEW |