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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 { | 68 { |
69 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 69 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
70 return; | 70 return; |
71 m_resolver->resolve(ServiceWorkerRegistration::getOrCreate(m_resolver->g
etExecutionContext(), handle.release())); | 71 m_resolver->resolve(ServiceWorkerRegistration::getOrCreate(m_resolver->g
etExecutionContext(), handle.release())); |
72 } | 72 } |
73 | 73 |
74 void onError(const WebServiceWorkerError& error) override | 74 void onError(const WebServiceWorkerError& error) override |
75 { | 75 { |
76 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 76 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
77 return; | 77 return; |
78 m_resolver->reject(ServiceWorkerError::take(m_resolver.get(), error)); | 78 if (error.errorType == WebServiceWorkerError::ErrorTypeType) { |
| 79 m_resolver->reject(V8ThrowException::createTypeError(m_resolver->get
ScriptState()->isolate(), error.message)); |
| 80 } else { |
| 81 m_resolver->reject(ServiceWorkerError::take(m_resolver.get(), error)
); |
| 82 } |
79 } | 83 } |
80 | 84 |
81 private: | 85 private: |
82 Persistent<ScriptPromiseResolver> m_resolver; | 86 Persistent<ScriptPromiseResolver> m_resolver; |
83 WTF_MAKE_NONCOPYABLE(RegistrationCallback); | 87 WTF_MAKE_NONCOPYABLE(RegistrationCallback); |
84 }; | 88 }; |
85 | 89 |
86 class GetRegistrationCallback : public WebServiceWorkerProvider::WebServiceWorke
rGetRegistrationCallbacks { | 90 class GetRegistrationCallback : public WebServiceWorkerProvider::WebServiceWorke
rGetRegistrationCallbacks { |
87 public: | 91 public: |
88 explicit GetRegistrationCallback(ScriptPromiseResolver* resolver) | 92 explicit GetRegistrationCallback(ScriptPromiseResolver* resolver) |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 } | 187 } |
184 | 188 |
185 DEFINE_TRACE(ServiceWorkerContainer) | 189 DEFINE_TRACE(ServiceWorkerContainer) |
186 { | 190 { |
187 visitor->trace(m_controller); | 191 visitor->trace(m_controller); |
188 visitor->trace(m_ready); | 192 visitor->trace(m_ready); |
189 RefCountedGarbageCollectedEventTargetWithInlineData<ServiceWorkerContainer>:
:trace(visitor); | 193 RefCountedGarbageCollectedEventTargetWithInlineData<ServiceWorkerContainer>:
:trace(visitor); |
190 ContextLifecycleObserver::trace(visitor); | 194 ContextLifecycleObserver::trace(visitor); |
191 } | 195 } |
192 | 196 |
| 197 void ServiceWorkerContainer::registerServiceWorkerImpl(ExecutionContext* executi
onContext, const KURL& rawScriptURL, const KURL& scope, PassOwnPtr<RegistrationC
allbacks> callbacks) |
| 198 { |
| 199 if (!m_provider) { |
| 200 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eState, "Failed to register a ServiceWorker: The document is in an invalid state
.")); |
| 201 return; |
| 202 } |
| 203 |
| 204 RefPtr<SecurityOrigin> documentOrigin = executionContext->getSecurityOrigin(
); |
| 205 String errorMessage; |
| 206 // Restrict to secure origins: https://w3c.github.io/webappsec/specs/powerfu
lfeatures/#settings-privileged |
| 207 if (!executionContext->isSecureContext(errorMessage)) { |
| 208 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eSecurity, errorMessage)); |
| 209 return; |
| 210 } |
| 211 |
| 212 KURL pageURL = KURL(KURL(), documentOrigin->toString()); |
| 213 if (!SchemeRegistry::shouldTreatURLSchemeAsAllowingServiceWorkers(pageURL.pr
otocol())) { |
| 214 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eSecurity, String("Failed to register a ServiceWorker: The URL protocol of the c
urrent origin ('" + documentOrigin->toString() + "') is not supported."))); |
| 215 return; |
| 216 } |
| 217 |
| 218 KURL scriptURL = rawScriptURL; |
| 219 scriptURL.removeFragmentIdentifier(); |
| 220 if (!documentOrigin->canRequest(scriptURL)) { |
| 221 RefPtr<SecurityOrigin> scriptOrigin = SecurityOrigin::create(scriptURL); |
| 222 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eSecurity, String("Failed to register a ServiceWorker: The origin of the provide
d scriptURL ('" + scriptOrigin->toString() + "') does not match the current orig
in ('" + documentOrigin->toString() + "')."))); |
| 223 return; |
| 224 } |
| 225 if (!SchemeRegistry::shouldTreatURLSchemeAsAllowingServiceWorkers(scriptURL.
protocol())) { |
| 226 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eSecurity, String("Failed to register a ServiceWorker: The URL protocol of the s
cript ('" + scriptURL.getString() + "') is not supported."))); |
| 227 return; |
| 228 } |
| 229 |
| 230 KURL patternURL = scope; |
| 231 patternURL.removeFragmentIdentifier(); |
| 232 |
| 233 if (!documentOrigin->canRequest(patternURL)) { |
| 234 RefPtr<SecurityOrigin> patternOrigin = SecurityOrigin::create(patternURL
); |
| 235 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eSecurity, String("Failed to register a ServiceWorker: The origin of the provide
d scope ('" + patternOrigin->toString() + "') does not match the current origin
('" + documentOrigin->toString() + "')."))); |
| 236 return; |
| 237 } |
| 238 if (!SchemeRegistry::shouldTreatURLSchemeAsAllowingServiceWorkers(patternURL
.protocol())) { |
| 239 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eSecurity, String("Failed to register a ServiceWorker: The URL protocol of the s
cope ('" + patternURL.getString() + "') is not supported."))); |
| 240 return; |
| 241 } |
| 242 |
| 243 WebString webErrorMessage; |
| 244 if (!m_provider->validateScopeAndScriptURL(patternURL, scriptURL, &webErrorM
essage)) { |
| 245 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eType, WebString::fromUTF8("Failed to register a ServiceWorker: " + webErrorMess
age.utf8()))); |
| 246 return; |
| 247 } |
| 248 |
| 249 m_provider->registerServiceWorker(patternURL, scriptURL, callbacks.leakPtr()
); |
| 250 } |
| 251 |
193 ScriptPromise ServiceWorkerContainer::registerServiceWorker(ScriptState* scriptS
tate, const String& url, const RegistrationOptions& options) | 252 ScriptPromise ServiceWorkerContainer::registerServiceWorker(ScriptState* scriptS
tate, const String& url, const RegistrationOptions& options) |
194 { | 253 { |
195 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 254 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
196 ScriptPromise promise = resolver->promise(); | 255 ScriptPromise promise = resolver->promise(); |
197 | 256 |
198 if (!m_provider) { | 257 if (!m_provider) { |
199 resolver->reject(DOMException::create(InvalidStateError, "Failed to regi
ster a ServiceWorker: The document is in an invalid state.")); | 258 resolver->reject(DOMException::create(InvalidStateError, "Failed to regi
ster a ServiceWorker: The document is in an invalid state.")); |
200 return promise; | 259 return promise; |
201 } | 260 } |
202 | 261 |
203 ExecutionContext* executionContext = scriptState->getExecutionContext(); | 262 ExecutionContext* executionContext = scriptState->getExecutionContext(); |
204 // FIXME: May be null due to worker termination: http://crbug.com/413518. | 263 // FIXME: May be null due to worker termination: http://crbug.com/413518. |
205 if (!executionContext) | 264 if (!executionContext) |
206 return ScriptPromise(); | 265 return ScriptPromise(); |
207 | 266 |
208 RefPtr<SecurityOrigin> documentOrigin = executionContext->getSecurityOrigin(
); | |
209 String errorMessage; | |
210 // Restrict to secure origins: https://w3c.github.io/webappsec/specs/powerfu
lfeatures/#settings-privileged | |
211 if (!executionContext->isSecureContext(errorMessage)) { | |
212 resolver->reject(DOMException::create(SecurityError, errorMessage)); | |
213 return promise; | |
214 } | |
215 | |
216 KURL pageURL = KURL(KURL(), documentOrigin->toString()); | |
217 if (!SchemeRegistry::shouldTreatURLSchemeAsAllowingServiceWorkers(pageURL.pr
otocol())) { | |
218 resolver->reject(DOMException::create(SecurityError, "Failed to register
a ServiceWorker: The URL protocol of the current origin ('" + documentOrigin->t
oString() + "') is not supported.")); | |
219 return promise; | |
220 } | |
221 | |
222 KURL scriptURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(url); | 267 KURL scriptURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(url); |
223 scriptURL.removeFragmentIdentifier(); | 268 scriptURL.removeFragmentIdentifier(); |
224 if (!documentOrigin->canRequest(scriptURL)) { | |
225 RefPtr<SecurityOrigin> scriptOrigin = SecurityOrigin::create(scriptURL); | |
226 resolver->reject(DOMException::create(SecurityError, "Failed to register
a ServiceWorker: The origin of the provided scriptURL ('" + scriptOrigin->toStr
ing() + "') does not match the current origin ('" + documentOrigin->toString() +
"').")); | |
227 return promise; | |
228 } | |
229 if (!SchemeRegistry::shouldTreatURLSchemeAsAllowingServiceWorkers(scriptURL.
protocol())) { | |
230 resolver->reject(DOMException::create(SecurityError, "Failed to register
a ServiceWorker: The URL protocol of the script ('" + scriptURL.getString() + "
') is not supported.")); | |
231 return promise; | |
232 } | |
233 | 269 |
234 KURL patternURL; | 270 KURL patternURL; |
235 if (options.scope().isNull()) | 271 if (options.scope().isNull()) |
236 patternURL = KURL(scriptURL, "./"); | 272 patternURL = KURL(scriptURL, "./"); |
237 else | 273 else |
238 patternURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(options.scope()); | 274 patternURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(options.scope()); |
239 patternURL.removeFragmentIdentifier(); | |
240 | 275 |
241 if (!documentOrigin->canRequest(patternURL)) { | 276 registerServiceWorkerImpl(executionContext, scriptURL, patternURL, adoptPtr(
new RegistrationCallback(resolver))); |
242 RefPtr<SecurityOrigin> patternOrigin = SecurityOrigin::create(patternURL
); | |
243 resolver->reject(DOMException::create(SecurityError, "Failed to register
a ServiceWorker: The origin of the provided scope ('" + patternOrigin->toString
() + "') does not match the current origin ('" + documentOrigin->toString() + "'
).")); | |
244 return promise; | |
245 } | |
246 if (!SchemeRegistry::shouldTreatURLSchemeAsAllowingServiceWorkers(patternURL
.protocol())) { | |
247 resolver->reject(DOMException::create(SecurityError, "Failed to register
a ServiceWorker: The URL protocol of the scope ('" + patternURL.getString() + "
') is not supported.")); | |
248 return promise; | |
249 } | |
250 | |
251 WebString webErrorMessage; | |
252 if (!m_provider->validateScopeAndScriptURL(patternURL, scriptURL, &webErrorM
essage)) { | |
253 resolver->reject(V8ThrowException::createTypeError(scriptState->isolate(
), WebString::fromUTF8("Failed to register a ServiceWorker: " + webErrorMessage.
utf8()))); | |
254 return promise; | |
255 } | |
256 | |
257 m_provider->registerServiceWorker(patternURL, scriptURL, new RegistrationCal
lback(resolver)); | |
258 | 277 |
259 return promise; | 278 return promise; |
260 } | 279 } |
261 | 280 |
262 ScriptPromise ServiceWorkerContainer::getRegistration(ScriptState* scriptState,
const String& documentURL) | 281 ScriptPromise ServiceWorkerContainer::getRegistration(ScriptState* scriptState,
const String& documentURL) |
263 { | 282 { |
264 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 283 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
265 ScriptPromise promise = resolver->promise(); | 284 ScriptPromise promise = resolver->promise(); |
266 | 285 |
267 if (!m_provider) { | 286 if (!m_provider) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 return; | 408 return; |
390 | 409 |
391 if (ServiceWorkerContainerClient* client = ServiceWorkerContainerClient::fro
m(executionContext)) { | 410 if (ServiceWorkerContainerClient* client = ServiceWorkerContainerClient::fro
m(executionContext)) { |
392 m_provider = client->provider(); | 411 m_provider = client->provider(); |
393 if (m_provider) | 412 if (m_provider) |
394 m_provider->setClient(this); | 413 m_provider->setClient(this); |
395 } | 414 } |
396 } | 415 } |
397 | 416 |
398 } // namespace blink | 417 } // namespace blink |
OLD | NEW |