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