1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "modules/serviceworkers/InstallEvent.h"
#include "core/dom/ExceptionCode.h"
#include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h"
#include "public/platform/WebSecurityOrigin.h"
namespace blink {
InstallEvent* InstallEvent::create(const AtomicString& type,
const ExtendableEventInit& eventInit) {
return new InstallEvent(type, eventInit);
}
InstallEvent* InstallEvent::create(const AtomicString& type,
const ExtendableEventInit& eventInit,
WaitUntilObserver* observer) {
return new InstallEvent(type, eventInit, observer);
}
InstallEvent::~InstallEvent() {}
void InstallEvent::registerForeignFetch(ExecutionContext* executionContext,
const ForeignFetchOptions& options,
ExceptionState& exceptionState) {
if (!isBeingDispatched()) {
exceptionState.throwDOMException(InvalidStateError,
"The event handler is already finished.");
return;
}
if (!options.hasOrigins() || options.origins().isEmpty()) {
exceptionState.throwTypeError("At least one origin is required");
return;
}
const Vector<String>& originList = options.origins();
// The origins parameter is either just a "*" to indicate all origins, or an
// explicit list of origins as absolute URLs. Internally an empty list of
// origins is used to represent the "*" case though.
Vector<RefPtr<SecurityOrigin>> parsedOrigins;
if (originList.size() != 1 || originList[0] != "*") {
parsedOrigins.resize(originList.size());
for (size_t i = 0; i < originList.size(); ++i) {
parsedOrigins[i] = SecurityOrigin::createFromString(originList[i]);
// Invalid URLs will result in a unique origin. And in general
// unique origins should not be accepted.
if (parsedOrigins[i]->isUnique()) {
exceptionState.throwTypeError("Invalid origin URL: " + originList[i]);
return;
}
}
}
ServiceWorkerGlobalScopeClient* client =
ServiceWorkerGlobalScopeClient::from(executionContext);
String scopePath = static_cast<KURL>(client->scope()).path();
RefPtr<SecurityOrigin> origin = executionContext->getSecurityOrigin();
if (!options.hasScopes() || options.scopes().isEmpty()) {
exceptionState.throwTypeError("At least one scope is required");
return;
}
const Vector<String>& subScopes = options.scopes();
Vector<KURL> subScopeURLs(subScopes.size());
for (size_t i = 0; i < subScopes.size(); ++i) {
subScopeURLs[i] = executionContext->completeURL(subScopes[i]);
if (!subScopeURLs[i].isValid()) {
exceptionState.throwTypeError("Invalid subscope URL: " + subScopes[i]);
return;
}
subScopeURLs[i].removeFragmentIdentifier();
if (!origin->canRequest(subScopeURLs[i])) {
exceptionState.throwTypeError("Subscope URL is not within scope: " +
subScopes[i]);
return;
}
String subScopePath = subScopeURLs[i].path();
if (!subScopePath.startsWith(scopePath)) {
exceptionState.throwTypeError("Subscope URL is not within scope: " +
subScopes[i]);
return;
}
}
client->registerForeignFetchScopes(subScopeURLs, parsedOrigins);
}
const AtomicString& InstallEvent::interfaceName() const {
return EventNames::InstallEvent;
}
InstallEvent::InstallEvent(const AtomicString& type,
const ExtendableEventInit& initializer)
: ExtendableEvent(type, initializer) {}
InstallEvent::InstallEvent(const AtomicString& type,
const ExtendableEventInit& initializer,
WaitUntilObserver* observer)
: ExtendableEvent(type, initializer, observer) {}
} // namespace blink
|