| 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 |