Index: third_party/WebKit/Source/core/workers/WorkerShadowFetchContext.cpp |
diff --git a/third_party/WebKit/Source/core/workers/WorkerShadowFetchContext.cpp b/third_party/WebKit/Source/core/workers/WorkerShadowFetchContext.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3b2ea91deaed454b732b227d90f3f9e59ae1523f |
--- /dev/null |
+++ b/third_party/WebKit/Source/core/workers/WorkerShadowFetchContext.cpp |
@@ -0,0 +1,379 @@ |
+// Copyright 2017 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 "core/workers/WorkerShadowFetchContext.h" |
+ |
+#include "core/dom/ExecutionContext.h" |
+#include "core/dom/SecurityContext.h" |
+#include "core/events/EventQueue.h" |
+#include "core/frame/ContentSettingsClient.h" |
+#include "core/frame/Settings.h" |
+#include "core/inspector/ConsoleMessage.h" |
+#include "core/loader/ThreadableLoadingContext.h" |
+#include "core/loader/appcache/ApplicationCacheHost.h" |
+#include "core/workers/ParentFrameTaskRunners.h" |
+#include "platform/exported/WrappedResourceRequest.h" |
+#include "platform/heap/Handle.h" |
+#include "platform/loader/fetch/ResourceFetcher.h" |
+#include "platform/weborigin/KURL.h" |
+#include "platform/wtf/WTF.h" |
+#include "public/platform/WebCachePolicy.h" |
+#include "public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h" |
+ |
+namespace blink { |
+ |
+class WorkerShadowFetchContext::ExecutionContextImpl |
+ : public GarbageCollectedFinalized< |
+ WorkerShadowFetchContext::ExecutionContextImpl>, |
+ public SecurityContext, |
+ public ExecutionContext { |
+ USING_GARBAGE_COLLECTED_MIXIN(ExecutionContextImpl); |
+ |
+ public: |
+ ExecutionContextImpl(const KURL& url, |
+ const String& user_agent, |
+ WebAddressSpace address_space) |
+ : url_(url), user_agent_(user_agent) { |
+ // Setting up the security context. |
+ ContentSecurityPolicy* policy = ContentSecurityPolicy::Create(); |
+ SecurityContext::SetContentSecurityPolicy(policy); |
+ SecurityContext::SetSecurityOrigin(SecurityOrigin::Create(url)); |
+ SecurityContext::SetAddressSpace(address_space); |
+ policy->BindToExecutionContext(this); |
+ } |
+ ~ExecutionContextImpl() {} |
+ |
+ // ExecutionContext overrides: |
+ void DisableEval(const String&) final { |
+ // TODO(kinuko): Propagate this to the worker global scope. |
+ } |
+ String UserAgent() const final { return user_agent_; } |
+ void PostTask(TaskType, |
+ const WebTraceLocation&, |
+ std::unique_ptr<ExecutionContextTask>, |
+ const String& task_name_for_instrumentation) final { |
+ NOTREACHED(); |
+ } |
+ EventTarget* ErrorEventTarget() final { return nullptr; } |
+ EventQueue* GetEventQueue() const final { return nullptr; } |
+ bool TasksNeedSuspension() final { return tasks_need_suspension_; } |
+ void SetTasksNeedSuspension(bool flag) { tasks_need_suspension_ = flag; } |
+ SecurityContext& GetSecurityContext() final { return *this; } |
+ DOMTimerCoordinator* Timers() final { return nullptr; } |
+ void AddConsoleMessage(ConsoleMessage* message) final { |
+ // TODO(kinuko): Implement this. |
+ } |
+ void ExceptionThrown(ErrorEvent* event) final { NOTREACHED(); } |
+ bool IsSecureContext(String& error_message) const final { |
+ // Until there are APIs that are available in workers and that |
+ // require a privileged context test that checks ancestors, just do |
+ // a simple check here. |
+ if (GetSecurityOrigin()->IsPotentiallyTrustworthy()) |
+ return true; |
+ error_message = GetSecurityOrigin()->IsPotentiallyTrustworthyErrorMessage(); |
+ return false; |
+ } |
+ CoreProbeSink* GetProbeSink() final { |
+ // TODO(kinuko): Implement this! How we plumb DevTools for frame-less world |
+ // largely relies on this part. |
+ return nullptr; |
+ } |
+ |
+ // SecurityContext overrides: |
+ void DidUpdateSecurityOrigin() final { NOTREACHED(); } |
+ |
+ using SecurityContext::GetSecurityOrigin; |
+ |
+ DEFINE_INLINE_TRACE() { |
+ SecurityContext::Trace(visitor); |
+ ExecutionContext::Trace(visitor); |
+ } |
+ |
+ protected: |
+ const KURL& VirtualURL() const final { return url_; } |
+ KURL VirtualCompleteURL(const String& url) const final { |
+ if (url.IsNull()) |
+ return KURL(); |
+ return KURL(url_, url); |
+ } |
+ |
+ private: |
+ const KURL url_; |
+ const String user_agent_; |
+ bool tasks_need_suspension_ = false; |
+}; |
+ |
+class WorkerShadowFetchContext::LoadingContextImpl |
+ : public GarbageCollected<WorkerShadowFetchContext::LoadingContextImpl>, |
+ public ThreadableLoadingContext { |
+ USING_GARBAGE_COLLECTED_MIXIN(LoadingContextImpl); |
+ |
+ public: |
+ LoadingContextImpl(ExecutionContextImpl* execution_context, |
+ ParentFrameTaskRunners* task_runners, |
+ ResourceFetcher* resource_fetcher) |
+ : execution_context_(execution_context), |
+ task_runners_(task_runners), |
+ resource_fetcher_(resource_fetcher) {} |
+ bool IsContextThread() const final { return IsMainThread(); } |
+ ResourceFetcher* GetResourceFetcher() final { |
+ DCHECK(IsContextThread()); |
+ return resource_fetcher_; |
+ } |
+ SecurityOrigin* GetSecurityOrigin() final { |
+ DCHECK(IsContextThread()); |
+ return execution_context_->GetSecurityOrigin(); |
+ } |
+ bool IsSecureContext() const final { |
+ DCHECK(IsContextThread()); |
+ String unused_error_message; |
+ return execution_context_->IsSecureContext(unused_error_message); |
+ } |
+ KURL FirstPartyForCookies() const final { |
+ // TODO(kinuko): Check if this is ok. |
+ DCHECK(IsContextThread()); |
+ return execution_context_->Url(); |
+ } |
+ String UserAgent() const final { |
+ DCHECK(IsContextThread()); |
+ return execution_context_->UserAgent(); |
+ } |
+ RefPtr<WebTaskRunner> GetTaskRunner(TaskType type) final { |
+ DCHECK(IsContextThread()); |
+ return task_runners_->Get(type); |
+ } |
+ void RecordUseCount(UseCounter::Feature feature) final { |
+ DCHECK(IsContextThread()); |
+ // TODO(kinuko): Implement this. |
+ } |
+ |
+ DEFINE_INLINE_TRACE() { |
+ visitor->Trace(execution_context_); |
+ visitor->Trace(task_runners_); |
+ visitor->Trace(resource_fetcher_); |
+ ThreadableLoadingContext::Trace(visitor); |
+ } |
+ |
+ private: |
+ Member<ExecutionContextImpl> execution_context_; |
+ Member<ParentFrameTaskRunners> task_runners_; |
+ Member<ResourceFetcher> resource_fetcher_; |
+}; |
+ |
+// static |
+WorkerShadowFetchContext* WorkerShadowFetchContext::Create( |
+ const KURL& url, |
+ const String& user_agent, |
+ WebAddressSpace address_space, |
+ ApplicationCacheHost* app_cache_host, |
+ std::unique_ptr<WebServiceWorkerNetworkProvider> service_worker_provider, |
+ std::unique_ptr<Settings> settings, |
+ ParentFrameTaskRunners* task_runners) { |
+ ExecutionContextImpl* execution_context = |
+ new ExecutionContextImpl(url, user_agent, address_space); |
+ return new WorkerShadowFetchContext(execution_context, app_cache_host, |
+ std::move(service_worker_provider), |
+ std::move(settings), task_runners); |
+} |
+ |
+WorkerShadowFetchContext::~WorkerShadowFetchContext() = default; |
+ |
+void WorkerShadowFetchContext::Detach() { |
+ // TODO(kinuko): Rename this. |
+ app_cache_host_->DetachFromDocumentLoader(); |
+} |
+ |
+void WorkerShadowFetchContext::AddAdditionalRequestHeaders( |
+ ResourceRequest& request, |
+ FetchResourceType type) { |
+ BaseFetchContext::AddAdditionalRequestHeaders(request, type); |
+ |
+ // The remaining modifications are only necessary for HTTP and HTTPS. |
+ if (!request.Url().IsEmpty() && !request.Url().ProtocolIsInHTTPFamily()) |
+ return; |
+ |
+ if (GetSettings() && GetSettings()->GetDataSaverEnabled()) |
+ request.SetHTTPHeaderField("Save-Data", "on"); |
+} |
+ |
+WebCachePolicy WorkerShadowFetchContext::ResourceRequestCachePolicy( |
+ const ResourceRequest& request, |
+ Resource::Type type, |
+ FetchParameters::DeferOption defer) const { |
+ if (request.HttpMethod() == "POST") |
+ return WebCachePolicy::kValidatingCacheData; |
+ return WebCachePolicy::kUseProtocolCachePolicy; |
+} |
+ |
+void WorkerShadowFetchContext::PrepareRequest(ResourceRequest& request, |
+ RedirectType redirect_type) { |
+ WrappedResourceRequest webreq(request); |
+ service_worker_provider_->WillSendRequest(webreq); |
+ |
+ if (redirect_type == RedirectType::kNotForRedirect) |
+ app_cache_host_->WillStartLoading(request); |
+} |
+ |
+void WorkerShadowFetchContext::DispatchWillSendRequest( |
+ unsigned long identifier, |
+ ResourceRequest& request, |
+ const ResourceResponse& redirect_response, |
+ const FetchInitiatorInfo& initiator_info) { |
+ /* |
+ probe::willSendRequest(GetFrame(), identifier, MasterDocumentLoader(), |
+ request, redirect_response, initiator_info); |
+ */ |
+} |
+ |
+void WorkerShadowFetchContext::DispatchDidReceiveResponse( |
+ unsigned long identifier, |
+ const ResourceResponse& response, |
+ WebURLRequest::FrameType frame_type, |
+ WebURLRequest::RequestContext request_context, |
+ Resource* resource, |
+ ResourceResponseType response_type) { |
+ /* |
+ probe::didReceiveResourceResponse(GetFrame(), identifier, document_loader, |
+ response, resource); |
+ */ |
+} |
+ |
+void WorkerShadowFetchContext::DispatchDidReceiveData(unsigned long identifier, |
+ const char* data, |
+ int data_length) { |
+ // probe::didReceiveData(GetFrame(), identifier, data, data_length); |
+} |
+ |
+void WorkerShadowFetchContext::DispatchDidReceiveEncodedData( |
+ unsigned long identifier, |
+ int encoded_data_length) { |
+ /* |
+ probe::didReceiveEncodedDataLength(GetFrame(), identifier, |
+ encoded_data_length); |
+ */ |
+} |
+ |
+void WorkerShadowFetchContext::DispatchDidFinishLoading( |
+ unsigned long identifier, |
+ double finish_time, |
+ int64_t encoded_data_length, |
+ int64_t decoded_body_length) { |
+ /* |
+ probe::didFinishLoading(GetFrame(), identifier, finish_time, |
+ encoded_data_length, decoded_body_length); |
+ */ |
+} |
+ |
+void WorkerShadowFetchContext::DispatchDidFail(unsigned long identifier, |
+ const ResourceError& error, |
+ int64_t encoded_data_length, |
+ bool is_internal_request) { |
+ /* |
+ probe::didFailLoading(GetFrame(), identifier, error); |
+ */ |
+} |
+ |
+void WorkerShadowFetchContext::AddResourceTiming( |
+ const ResourceTimingInfo& info) { |
+ /* |
+ DOMWindowPerformance::performance(*initiator_document->domWindow()) |
+ ->AddResourceTiming(info); |
+ */ |
+} |
+ |
+bool WorkerShadowFetchContext::AllowImage(bool images_enabled, |
+ const KURL& url) const { |
+ return !GetContentSettingsClient() || |
+ GetContentSettingsClient()->AllowImage(images_enabled, url); |
+} |
+ |
+bool WorkerShadowFetchContext::IsControlledByServiceWorker() const { |
+ return service_worker_provider_->IsControlledByServiceWorker(); |
+} |
+ |
+int64_t WorkerShadowFetchContext::ServiceWorkerID() const { |
+ return service_worker_provider_->ServiceWorkerID(); |
+} |
+ |
+void WorkerShadowFetchContext::PopulateResourceRequest( |
+ const KURL& url, |
+ Resource::Type type, |
+ const ClientHintsPreferences& hints_preferences, |
+ const FetchParameters::ResourceWidth& resource_width, |
+ const ResourceLoaderOptions& options, |
+ SecurityViolationReportingPolicy reporting_policy, |
+ ResourceRequest& request) { |
+ SetFirstPartyCookieAndRequestorOrigin(request); |
+ CheckCSPForRequest(request, url, options, reporting_policy, |
+ request.GetRedirectStatus(), |
+ ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly); |
+ AddCSPHeaderIfNecessary(type, request); |
+} |
+ |
+void WorkerShadowFetchContext::SetFirstPartyCookieAndRequestorOrigin( |
+ ResourceRequest& request) { |
+ if (request.FirstPartyForCookies().IsNull()) |
+ request.SetFirstPartyForCookies(loading_context_->FirstPartyForCookies()); |
+} |
+ |
+RefPtr<WebTaskRunner> WorkerShadowFetchContext::LoadingTaskRunner() const { |
+ return loading_context_->GetTaskRunner(TaskType::kNetworking); |
+} |
+ |
+ExecutionContext& WorkerShadowFetchContext::GetExecutionContext() { |
+ return *execution_context_; |
+} |
+ |
+SecurityContext& WorkerShadowFetchContext::GetSecurityContext() { |
+ return execution_context_->GetSecurityContext(); |
+} |
+ |
+ThreadableLoadingContext& |
+WorkerShadowFetchContext::GetThreadableLoadingContext() { |
+ return *loading_context_; |
+} |
+ |
+Settings* WorkerShadowFetchContext::GetSettings() const { |
+ return settings_.get(); |
+} |
+ |
+SecurityContext* WorkerShadowFetchContext::GetParentSecurityContext() |
+ const { |
+ return execution_context_.Get(); |
+} |
+ |
+void WorkerShadowFetchContext::CountUsage(UseCounter::Feature feature) const { |
+ loading_context_->RecordUseCount(feature); |
+} |
+ |
+void WorkerShadowFetchContext::CountDeprecation( |
+ UseCounter::Feature feature) const { |
+ // As we won't show deprecation warning in {service,shared} workers |
+ // this could just be handled as a regular use count. |
+ loading_context_->RecordUseCount(feature); |
+} |
+ |
+DEFINE_TRACE(WorkerShadowFetchContext) { |
+ visitor->Trace(execution_context_); |
+ visitor->Trace(loading_context_); |
+ visitor->Trace(app_cache_host_); |
+ BaseFetchContext::Trace(visitor); |
+} |
+ |
+WorkerShadowFetchContext::WorkerShadowFetchContext( |
+ ExecutionContextImpl* execution_context, |
+ ApplicationCacheHost* app_cache_host, |
+ std::unique_ptr<WebServiceWorkerNetworkProvider> service_worker_provider, |
+ std::unique_ptr<Settings> settings, |
+ ParentFrameTaskRunners* task_runners) |
+ : BaseFetchContext(execution_context), |
+ execution_context_(execution_context), |
+ loading_context_(new LoadingContextImpl(execution_context, |
+ task_runners, |
+ ResourceFetcher::Create(this))), |
+ app_cache_host_(app_cache_host), |
+ service_worker_provider_(std::move(service_worker_provider)), |
+ settings_(std::move(settings)) {} |
+ |
+} // namespace blink |