PassRefPtr<EntrySync> WorkerGlobalScopeFileSystem::webkitResolveLocalFileSystemSyncURL(WorkerGlobalScope* worker, const String& url, ExceptionState& exceptionState) { KURL completedURL = worker->completeURL(url); ExecutionContext* secureContext = worker->executionContext(); if (!secureContext->securityOrigin()->canAccessFileSystem() || !secureContext->securityOrigin()->canRequest(completedURL)) { exceptionState.throwSecurityError(FileError::securityErrorMessage); return 0; } if (!completedURL.isValid()) { exceptionState.throwDOMException(EncodingError, "the URL '" + url + "' is invalid."); return 0; } EntrySyncCallbackHelper resolveURLHelper; OwnPtr<AsyncFileSystemCallbacks> callbacks = ResolveURICallbacks::create(resolveURLHelper.successCallback(), resolveURLHelper.errorCallback(), worker); callbacks->setShouldBlockUntilCompletion(true); LocalFileSystem::from(worker)->resolveURL(worker, completedURL, callbacks.release()); RefPtr<EntrySync> entry = resolveURLHelper.getResult(exceptionState); if (!entry) return 0; return entry.release(); }
void WorkerGlobalScopeFileSystem::webkitResolveLocalFileSystemURL(WorkerGlobalScope* worker, const String& url, PassOwnPtr<EntryCallback> successCallback, PassOwnPtr<ErrorCallback> errorCallback) { KURL completedURL = worker->completeURL(url); ExecutionContext* secureContext = worker->executionContext(); if (!secureContext->securityOrigin()->canAccessFileSystem() || !secureContext->securityOrigin()->canRequest(completedURL)) { DOMFileSystem::scheduleCallback(worker, errorCallback, FileError::create(FileError::SECURITY_ERR)); return; } if (!completedURL.isValid()) { DOMFileSystem::scheduleCallback(worker, errorCallback, FileError::create(FileError::ENCODING_ERR)); return; } LocalFileSystem::from(worker)->resolveURL(worker, completedURL, ResolveURICallbacks::create(successCallback, errorCallback, worker)); }
ScriptPromise ServiceWorkerRegistrationNotifications::showNotification(ScriptState* scriptState, ServiceWorkerRegistration& serviceWorkerRegistration, const String& title, const NotificationOptions& options, ExceptionState& exceptionState) { ExecutionContext* executionContext = scriptState->executionContext(); // If context object's active worker is null, reject promise with a TypeError exception. if (!serviceWorkerRegistration.active()) return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "No active registration available on the ServiceWorkerRegistration.")); // If permission for notification's origin is not "granted", reject promise with a TypeError exception, and terminate these substeps. if (Notification::checkPermission(executionContext) != WebNotificationPermissionAllowed) return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "No notification permission has been granted for this origin.")); // Validate the developer-provided values to get a WebNotificationData object. WebNotificationData data = createWebNotificationData(executionContext, title, options, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); // Log number of actions developer provided in linear histogram: 0 -> underflow bucket, 1-16 -> distinct buckets, 17+ -> overflow bucket. Platform::current()->histogramEnumeration("Notifications.PersistentNotificationActionCount", options.actions().size(), 17); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebNotificationShowCallbacks* callbacks = new CallbackPromiseAdapter<void, void>(resolver); SecurityOrigin* origin = executionContext->securityOrigin(); WebNotificationManager* notificationManager = Platform::current()->notificationManager(); ASSERT(notificationManager); notificationManager->showPersistent(WebSecurityOrigin(origin), data, serviceWorkerRegistration.webRegistration(), callbacks); return promise; }
ScriptPromise ServiceWorkerContainer::registerServiceWorker(ScriptState* scriptState, const String& url, const Dictionary& dictionary) { RegistrationOptionList options(dictionary); ASSERT(RuntimeEnabledFeatures::serviceWorkerEnabled()); RefPtr<ScriptPromiseResolverWithContext> resolver = ScriptPromiseResolverWithContext::create(scriptState); ScriptPromise promise = resolver->promise(); if (!m_provider) { resolver->reject(DOMException::create(InvalidStateError, "No associated provider is available")); return promise; } ExecutionContext* executionContext = scriptState->executionContext(); RefPtr<SecurityOrigin> documentOrigin = executionContext->securityOrigin(); KURL patternURL = executionContext->completeURL(options.scope); patternURL.removeFragmentIdentifier(); if (!documentOrigin->canRequest(patternURL)) { resolver->reject(DOMException::create(SecurityError, "Can only register for patterns in the document's origin.")); return promise; } KURL scriptURL = executionContext->completeURL(url); scriptURL.removeFragmentIdentifier(); if (!documentOrigin->canRequest(scriptURL)) { resolver->reject(DOMException::create(SecurityError, "Script must be in document's origin.")); return promise; } m_provider->registerServiceWorker(patternURL, scriptURL, new CallbackPromiseAdapter<ServiceWorker, ServiceWorkerError>(resolver)); return promise; }
ScriptPromise ServiceWorkerClients::openWindow(ScriptState* scriptState, const String& url) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); ExecutionContext* context = scriptState->executionContext(); KURL parsedUrl = KURL(toWorkerGlobalScope(context)->location()->url(), url); if (!parsedUrl.isValid()) { resolver->reject(V8ThrowException::createTypeError(scriptState->isolate(), "'" + url + "' is not a valid URL.")); return promise; } if (!context->securityOrigin()->canDisplay(parsedUrl)) { resolver->reject(V8ThrowException::createTypeError(scriptState->isolate(), "'" + parsedUrl.elidedString() + "' cannot be opened.")); return promise; } if (!context->isWindowInteractionAllowed()) { resolver->reject(DOMException::create(InvalidAccessError, "Not allowed to open a window.")); return promise; } context->consumeWindowInteraction(); ServiceWorkerGlobalScopeClient::from(context)->openWindow(parsedUrl, new NavigateClientCallback(resolver)); return promise; }
void FileReaderLoader::startInternal(ExecutionContext& executionContext, const Stream* stream, PassRefPtr<BlobDataHandle> blobData) { // The blob is read by routing through the request handling layer given a temporary public url. m_urlForReading = BlobURL::createPublicURL(executionContext.securityOrigin()); if (m_urlForReading.isEmpty()) { failed(FileError::SECURITY_ERR); return; } if (blobData) { ASSERT(!stream); BlobRegistry::registerPublicBlobURL(executionContext.securityOrigin(), m_urlForReading, blobData); } else { ASSERT(stream); BlobRegistry::registerStreamURL(executionContext.securityOrigin(), m_urlForReading, stream->url()); } // Construct and load the request. ResourceRequest request(m_urlForReading); // FIXME: Should this really be 'internal'? Do we know anything about the actual request that generated this fetch? request.setRequestContext(WebURLRequest::RequestContextInternal); request.setHTTPMethod("GET"); if (m_hasRange) request.setHTTPHeaderField("Range", AtomicString(String::format("bytes=%d-%d", m_rangeStart, m_rangeEnd))); ThreadableLoaderOptions options; options.preflightPolicy = ConsiderPreflight; options.crossOriginRequestPolicy = DenyCrossOriginRequests; // FIXME: Is there a directive to which this load should be subject? options.contentSecurityPolicyEnforcement = DoNotEnforceContentSecurityPolicy; // Use special initiator to hide the request from the inspector. options.initiator = FetchInitiatorTypeNames::internal; ResourceLoaderOptions resourceLoaderOptions; resourceLoaderOptions.allowCredentials = AllowStoredCredentials; if (m_client) m_loader = ThreadableLoader::create(executionContext, this, request, options, resourceLoaderOptions); else ThreadableLoader::loadResourceSynchronously(executionContext, request, *this, options, resourceLoaderOptions); }
ScriptPromise ServiceWorkerRegistrationNotifications::showNotification(ScriptState* scriptState, ServiceWorkerRegistration& serviceWorkerRegistration, const String& title, const NotificationOptions& options, ExceptionState& exceptionState) { ExecutionContext* executionContext = scriptState->executionContext(); // If context object's active worker is null, reject promise with a TypeError exception. if (!serviceWorkerRegistration.active()) return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "No active registration available on the ServiceWorkerRegistration.")); // If permission for notification's origin is not "granted", reject promise with a TypeError exception, and terminate these substeps. if (Notification::checkPermission(executionContext) != WebNotificationPermissionAllowed) return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "No notification permission has been granted for this origin.")); if (options.hasVibrate() && options.silent()) return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Silent notifications must not specify vibration patterns.")); // FIXME: Unify the code path here with the Notification.create() function. Vector<char> dataAsWireBytes; if (options.hasData()) { RefPtr<SerializedScriptValue> data = SerializedScriptValueFactory::instance().create(options.data().isolate(), options.data(), nullptr, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); data->toWireBytes(dataAsWireBytes); } RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); // FIXME: Do the appropriate CORS checks on the icon URL. KURL iconUrl; if (options.hasIcon() && !options.icon().isEmpty()) { iconUrl = executionContext->completeURL(options.icon()); if (!iconUrl.isValid()) iconUrl = KURL(); } WebNotificationData::Direction dir = options.dir() == "rtl" ? WebNotificationData::DirectionRightToLeft : WebNotificationData::DirectionLeftToRight; NavigatorVibration::VibrationPattern vibrate = NavigatorVibration::sanitizeVibrationPattern(options.vibrate()); WebNotificationData notification(title, dir, options.lang(), options.body(), options.tag(), iconUrl, vibrate, options.silent(), dataAsWireBytes); WebNotificationShowCallbacks* callbacks = new CallbackPromiseAdapter<void, void>(resolver); SecurityOrigin* origin = executionContext->securityOrigin(); ASSERT(origin); WebNotificationManager* notificationManager = Platform::current()->notificationManager(); ASSERT(notificationManager); notificationManager->showPersistent(WebSerializedOrigin(*origin), notification, serviceWorkerRegistration.webRegistration(), callbacks); return promise; }
void WorkerGlobalScopeFileSystem::webkitRequestFileSystem(WorkerGlobalScope* worker, int type, long long size, PassOwnPtr<FileSystemCallback> successCallback, PassOwnPtr<ErrorCallback> errorCallback) { ExecutionContext* secureContext = worker->executionContext(); if (!secureContext->securityOrigin()->canAccessFileSystem()) { DOMFileSystem::scheduleCallback(worker, errorCallback, FileError::create(FileError::SECURITY_ERR)); return; } FileSystemType fileSystemType = static_cast<FileSystemType>(type); if (!DOMFileSystemBase::isValidType(fileSystemType)) { DOMFileSystem::scheduleCallback(worker, errorCallback, FileError::create(FileError::INVALID_MODIFICATION_ERR)); return; } LocalFileSystem::from(worker)->requestFileSystem(worker, fileSystemType, size, FileSystemCallbacks::create(successCallback, errorCallback, worker, fileSystemType)); }
PassRefPtr<DOMFileSystemSync> WorkerGlobalScopeFileSystem::webkitRequestFileSystemSync(WorkerGlobalScope* worker, int type, long long size, ExceptionState& exceptionState) { ExecutionContext* secureContext = worker->executionContext(); if (!secureContext->securityOrigin()->canAccessFileSystem()) { exceptionState.throwSecurityError(FileError::securityErrorMessage); return 0; } FileSystemType fileSystemType = static_cast<FileSystemType>(type); if (!DOMFileSystemBase::isValidType(fileSystemType)) { exceptionState.throwDOMException(InvalidModificationError, "the type must be TEMPORARY or PERSISTENT."); return 0; } FileSystemSyncCallbackHelper helper; OwnPtr<AsyncFileSystemCallbacks> callbacks = FileSystemCallbacks::create(helper.successCallback(), helper.errorCallback(), worker, fileSystemType); callbacks->setShouldBlockUntilCompletion(true); LocalFileSystem::from(worker)->requestFileSystem(worker, fileSystemType, size, callbacks.release()); return helper.getResult(exceptionState); }
ScriptPromise ServiceWorkerRegistrationNotifications::showNotification(ScriptState* scriptState, ServiceWorkerRegistration& serviceWorkerRegistration, const String& title, const NotificationOptions& options) { ExecutionContext* executionContext = scriptState->executionContext(); // If context object's active worker is null, reject promise with a TypeError exception. if (!serviceWorkerRegistration.active()) return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "No active registration available on the ServiceWorkerRegistration.")); // If permission for notification's origin is not "granted", reject promise with a TypeError exception, and terminate these substeps. if (Notification::checkPermission(executionContext) != WebNotificationPermissionAllowed) return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "No notification permission has been granted for this origin.")); RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); // FIXME: Do the appropriate CORS checks on the icon URL. // FIXME: Determine the text direction based on the options dictionary. KURL iconUrl; if (options.hasIcon() && !options.icon().isEmpty()) { iconUrl = executionContext->completeURL(options.icon()); if (!iconUrl.isValid()) iconUrl = KURL(); } WebNotificationData notification(title, WebNotificationData::DirectionLeftToRight, options.lang(), options.body(), options.tag(), iconUrl); WebNotificationShowCallbacks* callbacks = new CallbackPromiseAdapter<void, void>(resolver); SecurityOrigin* origin = executionContext->securityOrigin(); ASSERT(origin); WebNotificationManager* notificationManager = Platform::current()->notificationManager(); ASSERT(notificationManager); notificationManager->showPersistent(WebSerializedOrigin(*origin), notification, serviceWorkerRegistration.webRegistration(), callbacks); return promise; }