OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 #include "modules/serviceworkers/ServiceWorkerError.h" | 49 #include "modules/serviceworkers/ServiceWorkerError.h" |
50 #include "modules/serviceworkers/ServiceWorkerMessageEvent.h" | 50 #include "modules/serviceworkers/ServiceWorkerMessageEvent.h" |
51 #include "modules/serviceworkers/ServiceWorkerRegistration.h" | 51 #include "modules/serviceworkers/ServiceWorkerRegistration.h" |
52 #include "platform/RuntimeEnabledFeatures.h" | 52 #include "platform/RuntimeEnabledFeatures.h" |
53 #include "platform/weborigin/SchemeRegistry.h" | 53 #include "platform/weborigin/SchemeRegistry.h" |
54 #include "public/platform/WebString.h" | 54 #include "public/platform/WebString.h" |
55 #include "public/platform/WebURL.h" | 55 #include "public/platform/WebURL.h" |
56 #include "public/platform/modules/serviceworker/WebServiceWorker.h" | 56 #include "public/platform/modules/serviceworker/WebServiceWorker.h" |
57 #include "public/platform/modules/serviceworker/WebServiceWorkerProvider.h" | 57 #include "public/platform/modules/serviceworker/WebServiceWorkerProvider.h" |
58 #include "public/platform/modules/serviceworker/WebServiceWorkerRegistration.h" | 58 #include "public/platform/modules/serviceworker/WebServiceWorkerRegistration.h" |
59 #include "wtf/PtrUtil.h" | |
60 #include <memory> | |
61 | 59 |
62 namespace blink { | 60 namespace blink { |
63 | 61 |
64 class RegistrationCallback : public WebServiceWorkerProvider::WebServiceWorkerRe
gistrationCallbacks { | 62 class RegistrationCallback : public WebServiceWorkerProvider::WebServiceWorkerRe
gistrationCallbacks { |
65 public: | 63 public: |
66 explicit RegistrationCallback(ScriptPromiseResolver* resolver) | 64 explicit RegistrationCallback(ScriptPromiseResolver* resolver) |
67 : m_resolver(resolver) { } | 65 : m_resolver(resolver) { } |
68 ~RegistrationCallback() override { } | 66 ~RegistrationCallback() override { } |
69 | 67 |
70 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> handle)
override | 68 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> handle)
override |
71 { | 69 { |
72 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 70 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
73 return; | 71 return; |
74 m_resolver->resolve(ServiceWorkerRegistration::getOrCreate(m_resolver->g
etExecutionContext(), wrapUnique(handle.release()))); | 72 m_resolver->resolve(ServiceWorkerRegistration::getOrCreate(m_resolver->g
etExecutionContext(), adoptPtr(handle.release()))); |
75 } | 73 } |
76 | 74 |
77 void onError(const WebServiceWorkerError& error) override | 75 void onError(const WebServiceWorkerError& error) override |
78 { | 76 { |
79 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 77 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
80 return; | 78 return; |
81 if (error.errorType == WebServiceWorkerError::ErrorTypeType) { | 79 if (error.errorType == WebServiceWorkerError::ErrorTypeType) { |
82 m_resolver->reject(V8ThrowException::createTypeError(m_resolver->get
ScriptState()->isolate(), error.message)); | 80 m_resolver->reject(V8ThrowException::createTypeError(m_resolver->get
ScriptState()->isolate(), error.message)); |
83 } else { | 81 } else { |
84 m_resolver->reject(ServiceWorkerError::take(m_resolver.get(), error)
); | 82 m_resolver->reject(ServiceWorkerError::take(m_resolver.get(), error)
); |
85 } | 83 } |
86 } | 84 } |
87 | 85 |
88 private: | 86 private: |
89 Persistent<ScriptPromiseResolver> m_resolver; | 87 Persistent<ScriptPromiseResolver> m_resolver; |
90 WTF_MAKE_NONCOPYABLE(RegistrationCallback); | 88 WTF_MAKE_NONCOPYABLE(RegistrationCallback); |
91 }; | 89 }; |
92 | 90 |
93 class GetRegistrationCallback : public WebServiceWorkerProvider::WebServiceWorke
rGetRegistrationCallbacks { | 91 class GetRegistrationCallback : public WebServiceWorkerProvider::WebServiceWorke
rGetRegistrationCallbacks { |
94 public: | 92 public: |
95 explicit GetRegistrationCallback(ScriptPromiseResolver* resolver) | 93 explicit GetRegistrationCallback(ScriptPromiseResolver* resolver) |
96 : m_resolver(resolver) { } | 94 : m_resolver(resolver) { } |
97 ~GetRegistrationCallback() override { } | 95 ~GetRegistrationCallback() override { } |
98 | 96 |
99 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> webPass
Handle) override | 97 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> webPass
Handle) override |
100 { | 98 { |
101 std::unique_ptr<WebServiceWorkerRegistration::Handle> handle = wrapUniqu
e(webPassHandle.release()); | 99 OwnPtr<WebServiceWorkerRegistration::Handle> handle = adoptPtr(webPassHa
ndle.release()); |
102 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 100 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
103 return; | 101 return; |
104 if (!handle) { | 102 if (!handle) { |
105 // Resolve the promise with undefined. | 103 // Resolve the promise with undefined. |
106 m_resolver->resolve(); | 104 m_resolver->resolve(); |
107 return; | 105 return; |
108 } | 106 } |
109 m_resolver->resolve(ServiceWorkerRegistration::getOrCreate(m_resolver->g
etExecutionContext(), std::move(handle))); | 107 m_resolver->resolve(ServiceWorkerRegistration::getOrCreate(m_resolver->g
etExecutionContext(), std::move(handle))); |
110 } | 108 } |
111 | 109 |
(...skipping 10 matching lines...) Expand all Loading... |
122 }; | 120 }; |
123 | 121 |
124 class GetRegistrationsCallback : public WebServiceWorkerProvider::WebServiceWork
erGetRegistrationsCallbacks { | 122 class GetRegistrationsCallback : public WebServiceWorkerProvider::WebServiceWork
erGetRegistrationsCallbacks { |
125 public: | 123 public: |
126 explicit GetRegistrationsCallback(ScriptPromiseResolver* resolver) | 124 explicit GetRegistrationsCallback(ScriptPromiseResolver* resolver) |
127 : m_resolver(resolver) { } | 125 : m_resolver(resolver) { } |
128 ~GetRegistrationsCallback() override { } | 126 ~GetRegistrationsCallback() override { } |
129 | 127 |
130 void onSuccess(std::unique_ptr<WebVector<WebServiceWorkerRegistration::Handl
e*>> webPassRegistrations) override | 128 void onSuccess(std::unique_ptr<WebVector<WebServiceWorkerRegistration::Handl
e*>> webPassRegistrations) override |
131 { | 129 { |
132 Vector<std::unique_ptr<WebServiceWorkerRegistration::Handle>> handles; | 130 Vector<OwnPtr<WebServiceWorkerRegistration::Handle>> handles; |
133 std::unique_ptr<WebVector<WebServiceWorkerRegistration::Handle*>> webReg
istrations = wrapUnique(webPassRegistrations.release()); | 131 OwnPtr<WebVector<WebServiceWorkerRegistration::Handle*>> webRegistration
s = adoptPtr(webPassRegistrations.release()); |
134 for (auto& handle : *webRegistrations) { | 132 for (auto& handle : *webRegistrations) { |
135 handles.append(wrapUnique(handle)); | 133 handles.append(adoptPtr(handle)); |
136 } | 134 } |
137 | 135 |
138 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 136 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
139 return; | 137 return; |
140 m_resolver->resolve(ServiceWorkerRegistrationArray::take(m_resolver.get(
), &handles)); | 138 m_resolver->resolve(ServiceWorkerRegistrationArray::take(m_resolver.get(
), &handles)); |
141 } | 139 } |
142 | 140 |
143 void onError(const WebServiceWorkerError& error) override | 141 void onError(const WebServiceWorkerError& error) override |
144 { | 142 { |
145 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 143 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
(...skipping 10 matching lines...) Expand all Loading... |
156 public: | 154 public: |
157 explicit GetRegistrationForReadyCallback(ReadyProperty* ready) | 155 explicit GetRegistrationForReadyCallback(ReadyProperty* ready) |
158 : m_ready(ready) { } | 156 : m_ready(ready) { } |
159 ~GetRegistrationForReadyCallback() override { } | 157 ~GetRegistrationForReadyCallback() override { } |
160 | 158 |
161 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> handle)
override | 159 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> handle)
override |
162 { | 160 { |
163 ASSERT(m_ready->getState() == ReadyProperty::Pending); | 161 ASSERT(m_ready->getState() == ReadyProperty::Pending); |
164 | 162 |
165 if (m_ready->getExecutionContext() && !m_ready->getExecutionContext()->a
ctiveDOMObjectsAreStopped()) | 163 if (m_ready->getExecutionContext() && !m_ready->getExecutionContext()->a
ctiveDOMObjectsAreStopped()) |
166 m_ready->resolve(ServiceWorkerRegistration::getOrCreate(m_ready->get
ExecutionContext(), wrapUnique(handle.release()))); | 164 m_ready->resolve(ServiceWorkerRegistration::getOrCreate(m_ready->get
ExecutionContext(), adoptPtr(handle.release()))); |
167 } | 165 } |
168 | 166 |
169 private: | 167 private: |
170 Persistent<ReadyProperty> m_ready; | 168 Persistent<ReadyProperty> m_ready; |
171 WTF_MAKE_NONCOPYABLE(GetRegistrationForReadyCallback); | 169 WTF_MAKE_NONCOPYABLE(GetRegistrationForReadyCallback); |
172 }; | 170 }; |
173 | 171 |
174 ServiceWorkerContainer* ServiceWorkerContainer::create(ExecutionContext* executi
onContext) | 172 ServiceWorkerContainer* ServiceWorkerContainer::create(ExecutionContext* executi
onContext) |
175 { | 173 { |
176 return new ServiceWorkerContainer(executionContext); | 174 return new ServiceWorkerContainer(executionContext); |
(...skipping 13 matching lines...) Expand all Loading... |
190 } | 188 } |
191 | 189 |
192 DEFINE_TRACE(ServiceWorkerContainer) | 190 DEFINE_TRACE(ServiceWorkerContainer) |
193 { | 191 { |
194 visitor->trace(m_controller); | 192 visitor->trace(m_controller); |
195 visitor->trace(m_ready); | 193 visitor->trace(m_ready); |
196 EventTargetWithInlineData::trace(visitor); | 194 EventTargetWithInlineData::trace(visitor); |
197 ContextLifecycleObserver::trace(visitor); | 195 ContextLifecycleObserver::trace(visitor); |
198 } | 196 } |
199 | 197 |
200 void ServiceWorkerContainer::registerServiceWorkerImpl(ExecutionContext* executi
onContext, const KURL& rawScriptURL, const KURL& scope, std::unique_ptr<Registra
tionCallbacks> callbacks) | 198 void ServiceWorkerContainer::registerServiceWorkerImpl(ExecutionContext* executi
onContext, const KURL& rawScriptURL, const KURL& scope, PassOwnPtr<RegistrationC
allbacks> callbacks) |
201 { | 199 { |
202 if (!m_provider) { | 200 if (!m_provider) { |
203 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eState, "Failed to register a ServiceWorker: The document is in an invalid state
.")); | 201 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eState, "Failed to register a ServiceWorker: The document is in an invalid state
.")); |
204 return; | 202 return; |
205 } | 203 } |
206 | 204 |
207 RefPtr<SecurityOrigin> documentOrigin = executionContext->getSecurityOrigin(
); | 205 RefPtr<SecurityOrigin> documentOrigin = executionContext->getSecurityOrigin(
); |
208 String errorMessage; | 206 String errorMessage; |
209 // Restrict to secure origins: https://w3c.github.io/webappsec/specs/powerfu
lfeatures/#settings-privileged | 207 // Restrict to secure origins: https://w3c.github.io/webappsec/specs/powerfu
lfeatures/#settings-privileged |
210 if (!executionContext->isSecureContext(errorMessage)) { | 208 if (!executionContext->isSecureContext(errorMessage)) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 } | 248 } |
251 | 249 |
252 ContentSecurityPolicy* csp = executionContext->contentSecurityPolicy(); | 250 ContentSecurityPolicy* csp = executionContext->contentSecurityPolicy(); |
253 if (csp) { | 251 if (csp) { |
254 if (!csp->allowWorkerContextFromSource(scriptURL, ResourceRequest::Redir
ectStatus::NoRedirect, ContentSecurityPolicy::SendReport)) { | 252 if (!csp->allowWorkerContextFromSource(scriptURL, ResourceRequest::Redir
ectStatus::NoRedirect, ContentSecurityPolicy::SendReport)) { |
255 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::Erro
rTypeSecurity, String("Failed to register a ServiceWorker: The provided scriptUR
L ('" + scriptURL.getString() + "') violates the Content Security Policy."))); | 253 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::Erro
rTypeSecurity, String("Failed to register a ServiceWorker: The provided scriptUR
L ('" + scriptURL.getString() + "') violates the Content Security Policy."))); |
256 return; | 254 return; |
257 } | 255 } |
258 } | 256 } |
259 | 257 |
260 m_provider->registerServiceWorker(patternURL, scriptURL, callbacks.release()
); | 258 m_provider->registerServiceWorker(patternURL, scriptURL, callbacks.leakPtr()
); |
261 } | 259 } |
262 | 260 |
263 ScriptPromise ServiceWorkerContainer::registerServiceWorker(ScriptState* scriptS
tate, const String& url, const RegistrationOptions& options) | 261 ScriptPromise ServiceWorkerContainer::registerServiceWorker(ScriptState* scriptS
tate, const String& url, const RegistrationOptions& options) |
264 { | 262 { |
265 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 263 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
266 ScriptPromise promise = resolver->promise(); | 264 ScriptPromise promise = resolver->promise(); |
267 | 265 |
268 if (!m_provider) { | 266 if (!m_provider) { |
269 resolver->reject(DOMException::create(InvalidStateError, "Failed to regi
ster a ServiceWorker: The document is in an invalid state.")); | 267 resolver->reject(DOMException::create(InvalidStateError, "Failed to regi
ster a ServiceWorker: The document is in an invalid state.")); |
270 return promise; | 268 return promise; |
271 } | 269 } |
272 | 270 |
273 ExecutionContext* executionContext = scriptState->getExecutionContext(); | 271 ExecutionContext* executionContext = scriptState->getExecutionContext(); |
274 // FIXME: May be null due to worker termination: http://crbug.com/413518. | 272 // FIXME: May be null due to worker termination: http://crbug.com/413518. |
275 if (!executionContext) | 273 if (!executionContext) |
276 return ScriptPromise(); | 274 return ScriptPromise(); |
277 | 275 |
278 KURL scriptURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(url); | 276 KURL scriptURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(url); |
279 scriptURL.removeFragmentIdentifier(); | 277 scriptURL.removeFragmentIdentifier(); |
280 | 278 |
281 KURL patternURL; | 279 KURL patternURL; |
282 if (options.scope().isNull()) | 280 if (options.scope().isNull()) |
283 patternURL = KURL(scriptURL, "./"); | 281 patternURL = KURL(scriptURL, "./"); |
284 else | 282 else |
285 patternURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(options.scope()); | 283 patternURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(options.scope()); |
286 | 284 |
287 registerServiceWorkerImpl(executionContext, scriptURL, patternURL, wrapUniqu
e(new RegistrationCallback(resolver))); | 285 registerServiceWorkerImpl(executionContext, scriptURL, patternURL, adoptPtr(
new RegistrationCallback(resolver))); |
288 | 286 |
289 return promise; | 287 return promise; |
290 } | 288 } |
291 | 289 |
292 ScriptPromise ServiceWorkerContainer::getRegistration(ScriptState* scriptState,
const String& documentURL) | 290 ScriptPromise ServiceWorkerContainer::getRegistration(ScriptState* scriptState,
const String& documentURL) |
293 { | 291 { |
294 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 292 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
295 ScriptPromise promise = resolver->promise(); | 293 ScriptPromise promise = resolver->promise(); |
296 | 294 |
297 if (!m_provider) { | 295 if (!m_provider) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 m_provider->getRegistrationForReady(new GetRegistrationForReadyCallb
ack(m_ready.get())); | 378 m_provider->getRegistrationForReady(new GetRegistrationForReadyCallb
ack(m_ready.get())); |
381 } | 379 } |
382 | 380 |
383 return m_ready->promise(callerState->world()); | 381 return m_ready->promise(callerState->world()); |
384 } | 382 } |
385 | 383 |
386 void ServiceWorkerContainer::setController(std::unique_ptr<WebServiceWorker::Han
dle> handle, bool shouldNotifyControllerChange) | 384 void ServiceWorkerContainer::setController(std::unique_ptr<WebServiceWorker::Han
dle> handle, bool shouldNotifyControllerChange) |
387 { | 385 { |
388 if (!getExecutionContext()) | 386 if (!getExecutionContext()) |
389 return; | 387 return; |
390 m_controller = ServiceWorker::from(getExecutionContext(), wrapUnique(handle.
release())); | 388 m_controller = ServiceWorker::from(getExecutionContext(), adoptPtr(handle.re
lease())); |
391 if (m_controller) | 389 if (m_controller) |
392 UseCounter::count(getExecutionContext(), UseCounter::ServiceWorkerContro
lledPage); | 390 UseCounter::count(getExecutionContext(), UseCounter::ServiceWorkerContro
lledPage); |
393 if (shouldNotifyControllerChange) | 391 if (shouldNotifyControllerChange) |
394 dispatchEvent(Event::create(EventTypeNames::controllerchange)); | 392 dispatchEvent(Event::create(EventTypeNames::controllerchange)); |
395 } | 393 } |
396 | 394 |
397 void ServiceWorkerContainer::dispatchMessageEvent(std::unique_ptr<WebServiceWork
er::Handle> handle, const WebString& message, const WebMessagePortChannelArray&
webChannels) | 395 void ServiceWorkerContainer::dispatchMessageEvent(std::unique_ptr<WebServiceWork
er::Handle> handle, const WebString& message, const WebMessagePortChannelArray&
webChannels) |
398 { | 396 { |
399 if (!getExecutionContext() || !getExecutionContext()->executingWindow()) | 397 if (!getExecutionContext() || !getExecutionContext()->executingWindow()) |
400 return; | 398 return; |
401 | 399 |
402 MessagePortArray* ports = MessagePort::toMessagePortArray(getExecutionContex
t(), webChannels); | 400 MessagePortArray* ports = MessagePort::toMessagePortArray(getExecutionContex
t(), webChannels); |
403 RefPtr<SerializedScriptValue> value = SerializedScriptValue::create(message)
; | 401 RefPtr<SerializedScriptValue> value = SerializedScriptValue::create(message)
; |
404 ServiceWorker* source = ServiceWorker::from(getExecutionContext(), wrapUniqu
e(handle.release())); | 402 ServiceWorker* source = ServiceWorker::from(getExecutionContext(), adoptPtr(
handle.release())); |
405 dispatchEvent(ServiceWorkerMessageEvent::create(ports, value, source, getExe
cutionContext()->getSecurityOrigin()->toString())); | 403 dispatchEvent(ServiceWorkerMessageEvent::create(ports, value, source, getExe
cutionContext()->getSecurityOrigin()->toString())); |
406 } | 404 } |
407 | 405 |
408 const AtomicString& ServiceWorkerContainer::interfaceName() const | 406 const AtomicString& ServiceWorkerContainer::interfaceName() const |
409 { | 407 { |
410 return EventTargetNames::ServiceWorkerContainer; | 408 return EventTargetNames::ServiceWorkerContainer; |
411 } | 409 } |
412 | 410 |
413 ServiceWorkerContainer::ServiceWorkerContainer(ExecutionContext* executionContex
t) | 411 ServiceWorkerContainer::ServiceWorkerContainer(ExecutionContext* executionContex
t) |
414 : ContextLifecycleObserver(executionContext) | 412 : ContextLifecycleObserver(executionContext) |
415 , m_provider(0) | 413 , m_provider(0) |
416 { | 414 { |
417 | 415 |
418 if (!executionContext) | 416 if (!executionContext) |
419 return; | 417 return; |
420 | 418 |
421 if (ServiceWorkerContainerClient* client = ServiceWorkerContainerClient::fro
m(executionContext)) { | 419 if (ServiceWorkerContainerClient* client = ServiceWorkerContainerClient::fro
m(executionContext)) { |
422 m_provider = client->provider(); | 420 m_provider = client->provider(); |
423 if (m_provider) | 421 if (m_provider) |
424 m_provider->setClient(this); | 422 m_provider->setClient(this); |
425 } | 423 } |
426 } | 424 } |
427 | 425 |
428 } // namespace blink | 426 } // namespace blink |
OLD | NEW |