Chromium Code Reviews| Index: Source/web/WebEmbeddedWorkerImpl.cpp |
| diff --git a/Source/web/WebEmbeddedWorkerImpl.cpp b/Source/web/WebEmbeddedWorkerImpl.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..503f35c3b4630b5d0c08bf11dae4c1f7314e5fdd |
| --- /dev/null |
| +++ b/Source/web/WebEmbeddedWorkerImpl.cpp |
| @@ -0,0 +1,178 @@ |
| +/* |
| + * Copyright (C) 2013 Google Inc. All rights reserved. |
| + * |
| + * Redistribution and use in source and binary forms, with or without |
| + * modification, are permitted provided that the following conditions are |
| + * met: |
| + * |
| + * * Redistributions of source code must retain the above copyright |
| + * notice, this list of conditions and the following disclaimer. |
| + * * Redistributions in binary form must reproduce the above |
| + * copyright notice, this list of conditions and the following disclaimer |
| + * in the documentation and/or other materials provided with the |
| + * distribution. |
| + * * Neither the name of Google Inc. nor the names of its |
| + * contributors may be used to endorse or promote products derived from |
| + * this software without specific prior written permission. |
| + * |
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| + */ |
| + |
| +#include "config.h" |
| +#include "WebEmbeddedWorkerImpl.h" |
| + |
| +#include "WebDataSourceImpl.h" |
| +#include "WebFrameImpl.h" |
| +#include "WebServiceWorkerContextClient.h" |
| +#include "WebView.h" |
| +#include "WebWorkerPermissionClientProxy.h" |
| +#include "WorkerPermissionClient.h" |
| +#include "core/dom/Document.h" |
| +#include "core/loader/FrameLoadRequest.h" |
| +#include "core/loader/SubstituteData.h" |
| +#include "core/workers/WorkerClients.h" |
| +#include "core/workers/WorkerScriptLoader.h" |
| +#include "core/workers/WorkerThreadStartupData.h" |
| +#include "platform/NotImplemented.h" |
| +#include "platform/SharedBuffer.h" |
| + |
| +using namespace WebCore; |
| + |
| +namespace blink { |
| + |
| +WebEmbeddedWorker* WebEmbeddedWorker::create( |
| + WebServiceWorkerContextClient* client, |
| + WebWorkerPermissionClientProxy* permissionClient) |
| +{ |
| + return new WebEmbeddedWorkerImpl(adoptPtr(client), adoptPtr(permissionClient)); |
| +} |
| + |
| +WebEmbeddedWorkerImpl::WebEmbeddedWorkerImpl( |
| + PassOwnPtr<WebServiceWorkerContextClient> client, |
| + PassOwnPtr<WebWorkerPermissionClientProxy> permissionClient) |
| + : m_workerContextClient(client) |
| + , m_permissionClient(permissionClient) |
| + , m_scriptLoader(WorkerScriptLoader::create()) |
| + , m_askedToTerminate(false) |
| +{ |
| + m_scriptLoader->setTargetType(ResourceRequest::TargetIsServiceWorker); |
| +} |
| + |
| +WebEmbeddedWorkerImpl::~WebEmbeddedWorkerImpl() |
| +{ |
| + ASSERT(m_webView); |
| + // Detach the client before closing the view to avoid getting called back. |
| + toWebFrameImpl(m_mainFrame)->setClient(0); |
| + |
| + m_webView->close(); |
| + m_mainFrame->close(); |
| +} |
| + |
| +void WebEmbeddedWorkerImpl::startWorkerContext( |
| + const WebEmbeddedWorkerStartData& data) |
| +{ |
| + ASSERT(!m_askedToTerminate); |
| + ASSERT(!m_loading); |
| + m_workerStartData = data; |
| + |
| + prepareShadowPageForLoader(); |
| + |
| + m_loading = true; |
| + m_scriptLoader->loadAsynchronously(m_loadingDocument.get(), data.scriptURL, DenyCrossOriginRequests, this); |
| +} |
| + |
| +void WebEmbeddedWorkerImpl::notifyFinished() |
| +{ |
| + ASSERT(m_loading); |
| + m_loading = false; |
|
michaeln
2013/11/21 02:00:40
Once we've retrieved the results of the main scrip
kinuko
2013/11/21 06:36:05
Done.
|
| + |
| + if (m_scriptLoader->failed()) { |
| + // How could this fail in our case? |
| + m_workerContextClient->workerContextLoadFailed(); |
| + return; |
| + } |
| + |
| + if (m_askedToTerminate) { |
| + m_workerContextClient->workerContextDestroyed(); |
| + return; |
| + } |
| + |
|
michaeln
2013/11/21 02:00:40
What if the main script load involves a series of
kinuko
2013/11/21 06:36:05
Currently we do deny cross-origin request, even vi
michaeln
2013/11/21 22:14:38
That sgtm2, same-origin redirects only.
|
| + WorkerThreadStartMode startMode = m_workerStartData.startMode == WebEmbeddedWorkerStartModePauseOnStart ? PauseWorkerGlobalScopeOnStart : DontPauseWorkerGlobalScopeOnStart; |
| + OwnPtr<WorkerClients> workerClients = WorkerClients::create(); |
| + providePermissionClientToWorker(workerClients.get(), m_permissionClient.release()); |
| + |
| + OwnPtr<WorkerThreadStartupData> startupData = |
| + WorkerThreadStartupData::create( |
| + m_workerStartData.scriptURL, |
| + m_workerStartData.userAgent, |
| + m_scriptLoader->script(), |
| + startMode, |
| + m_workerStartData.contentSecurityPolicy, |
|
michaeln
2013/11/21 02:00:40
ok... so this CSP header value... i think we shoul
kinuko
2013/11/21 06:36:05
Yup. Today I had time to investigate this a bit, a
|
| + static_cast<WebCore::ContentSecurityPolicy::HeaderType>(m_workerStartData.contentSecurityPolicyType), |
| + workerClients.release()); |
| + |
| + // FIXME: Create WorkerReportingProxy, create ServiceWorkerThread and |
| + // start it with m_scripLoader->script(). |
| + notImplemented(); |
| +} |
| + |
| +void WebEmbeddedWorkerImpl::terminateWorkerContext() |
| +{ |
| + if (m_askedToTerminate) |
| + return; |
|
michaeln
2013/11/21 02:00:40
How do we abort/cancel the main script load if it'
kinuko
2013/11/21 06:36:05
Added cancel().
|
| + m_askedToTerminate = true; |
| + if (m_workerThread) |
| + m_workerThread->stop(); |
| +} |
| + |
| +void WebEmbeddedWorkerImpl::postTaskToLoader(PassOwnPtr<WebCore::ExecutionContextTask> task) |
| +{ |
| + m_loadingDocument->postTask(task); |
| +} |
| + |
| +bool WebEmbeddedWorkerImpl::postTaskForModeToWorkerGlobalScope(PassOwnPtr<WebCore::ExecutionContextTask> task, const String& mode) |
| +{ |
| + m_workerThread->runLoop().postTaskForMode(task, mode); |
| + return true; |
| +} |
| + |
| +void WebEmbeddedWorkerImpl::prepareShadowPageForLoader() |
| +{ |
| + // Create 'shadow page', which is never displayed and is used mainly to |
| + // provide a context for loading on the main thread. |
| + ASSERT(!m_webView); |
| + m_webView = WebView::create(0); |
| + m_mainFrame = WebFrame::create(this); |
| + m_webView->setMainFrame(m_mainFrame); |
| + |
| + WebFrameImpl* webFrame = toWebFrameImpl(m_webView->mainFrame()); |
| + |
| + // Construct substitute data source for the 'shadow page'. We only need it |
| + // to have same origin as the worker so the loading checks work correctly. |
| + CString content(""); |
| + int length = static_cast<int>(content.length()); |
| + RefPtr<SharedBuffer> buffer(SharedBuffer::create(content.data(), length)); |
| + webFrame->frame()->loader().load(FrameLoadRequest(0, ResourceRequest(m_workerStartData.scriptURL), SubstituteData(buffer, "text/html", "UTF-8", KURL()))); |
| + |
| + // This document will be used as 'loading context' for the worker. |
| + m_loadingDocument = webFrame->frame()->document(); |
| +} |
| + |
| +void WebEmbeddedWorkerImpl::didCreateDataSource(WebFrame*, WebDataSource* ds) |
| +{ |
| + // Tell the loader to load the data into the 'shadow page' synchronously, |
| + // so we can grab the resulting Document right after load. |
| + static_cast<WebDataSourceImpl*>(ds)->setDeferMainResourceDataLoad(false); |
| +} |
| + |
| +} // namespace blink |