OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "core/workers/WorkerShadowFetchContext.h" |
| 6 |
| 7 #include "core/dom/ExecutionContext.h" |
| 8 #include "core/dom/SecurityContext.h" |
| 9 #include "core/events/EventQueue.h" |
| 10 #include "core/frame/ContentSettingsClient.h" |
| 11 #include "core/frame/Settings.h" |
| 12 #include "core/inspector/ConsoleMessage.h" |
| 13 #include "core/loader/ThreadableLoadingContext.h" |
| 14 #include "core/loader/appcache/ApplicationCacheHost.h" |
| 15 #include "core/workers/ParentFrameTaskRunners.h" |
| 16 #include "platform/exported/WrappedResourceRequest.h" |
| 17 #include "platform/heap/Handle.h" |
| 18 #include "platform/loader/fetch/ResourceFetcher.h" |
| 19 #include "platform/weborigin/KURL.h" |
| 20 #include "platform/wtf/WTF.h" |
| 21 #include "public/platform/WebCachePolicy.h" |
| 22 #include "public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.
h" |
| 23 |
| 24 namespace blink { |
| 25 |
| 26 class WorkerShadowFetchContext::ExecutionContextImpl |
| 27 : public GarbageCollectedFinalized< |
| 28 WorkerShadowFetchContext::ExecutionContextImpl>, |
| 29 public SecurityContext, |
| 30 public ExecutionContext { |
| 31 USING_GARBAGE_COLLECTED_MIXIN(ExecutionContextImpl); |
| 32 |
| 33 public: |
| 34 ExecutionContextImpl(const KURL& url, |
| 35 const String& user_agent, |
| 36 WebAddressSpace address_space) |
| 37 : url_(url), user_agent_(user_agent) { |
| 38 // Setting up the security context. |
| 39 ContentSecurityPolicy* policy = ContentSecurityPolicy::Create(); |
| 40 SecurityContext::SetContentSecurityPolicy(policy); |
| 41 SecurityContext::SetSecurityOrigin(SecurityOrigin::Create(url)); |
| 42 SecurityContext::SetAddressSpace(address_space); |
| 43 policy->BindToExecutionContext(this); |
| 44 } |
| 45 ~ExecutionContextImpl() {} |
| 46 |
| 47 // ExecutionContext overrides: |
| 48 void DisableEval(const String&) final { |
| 49 // TODO(kinuko): Propagate this to the worker global scope. |
| 50 } |
| 51 String UserAgent() const final { return user_agent_; } |
| 52 void PostTask(TaskType, |
| 53 const WebTraceLocation&, |
| 54 std::unique_ptr<ExecutionContextTask>, |
| 55 const String& task_name_for_instrumentation) final { |
| 56 NOTREACHED(); |
| 57 } |
| 58 EventTarget* ErrorEventTarget() final { return nullptr; } |
| 59 EventQueue* GetEventQueue() const final { return nullptr; } |
| 60 bool TasksNeedSuspension() final { return tasks_need_suspension_; } |
| 61 void SetTasksNeedSuspension(bool flag) { tasks_need_suspension_ = flag; } |
| 62 SecurityContext& GetSecurityContext() final { return *this; } |
| 63 DOMTimerCoordinator* Timers() final { return nullptr; } |
| 64 void AddConsoleMessage(ConsoleMessage* message) final { |
| 65 // TODO(kinuko): Implement this. |
| 66 } |
| 67 void ExceptionThrown(ErrorEvent* event) final { NOTREACHED(); } |
| 68 bool IsSecureContext(String& error_message) const final { |
| 69 // Until there are APIs that are available in workers and that |
| 70 // require a privileged context test that checks ancestors, just do |
| 71 // a simple check here. |
| 72 if (GetSecurityOrigin()->IsPotentiallyTrustworthy()) |
| 73 return true; |
| 74 error_message = GetSecurityOrigin()->IsPotentiallyTrustworthyErrorMessage(); |
| 75 return false; |
| 76 } |
| 77 CoreProbeSink* GetProbeSink() final { |
| 78 // TODO(kinuko): Implement this! How we plumb DevTools for frame-less world |
| 79 // largely relies on this part. |
| 80 return nullptr; |
| 81 } |
| 82 |
| 83 // SecurityContext overrides: |
| 84 void DidUpdateSecurityOrigin() final { NOTREACHED(); } |
| 85 |
| 86 using SecurityContext::GetSecurityOrigin; |
| 87 |
| 88 DEFINE_INLINE_TRACE() { |
| 89 SecurityContext::Trace(visitor); |
| 90 ExecutionContext::Trace(visitor); |
| 91 } |
| 92 |
| 93 protected: |
| 94 const KURL& VirtualURL() const final { return url_; } |
| 95 KURL VirtualCompleteURL(const String& url) const final { |
| 96 if (url.IsNull()) |
| 97 return KURL(); |
| 98 return KURL(url_, url); |
| 99 } |
| 100 |
| 101 private: |
| 102 const KURL url_; |
| 103 const String user_agent_; |
| 104 bool tasks_need_suspension_ = false; |
| 105 }; |
| 106 |
| 107 class WorkerShadowFetchContext::LoadingContextImpl |
| 108 : public GarbageCollected<WorkerShadowFetchContext::LoadingContextImpl>, |
| 109 public ThreadableLoadingContext { |
| 110 USING_GARBAGE_COLLECTED_MIXIN(LoadingContextImpl); |
| 111 |
| 112 public: |
| 113 LoadingContextImpl(ExecutionContextImpl* execution_context, |
| 114 ParentFrameTaskRunners* task_runners, |
| 115 ResourceFetcher* resource_fetcher) |
| 116 : execution_context_(execution_context), |
| 117 task_runners_(task_runners), |
| 118 resource_fetcher_(resource_fetcher) {} |
| 119 bool IsContextThread() const final { return IsMainThread(); } |
| 120 ResourceFetcher* GetResourceFetcher() final { |
| 121 DCHECK(IsContextThread()); |
| 122 return resource_fetcher_; |
| 123 } |
| 124 SecurityOrigin* GetSecurityOrigin() final { |
| 125 DCHECK(IsContextThread()); |
| 126 return execution_context_->GetSecurityOrigin(); |
| 127 } |
| 128 bool IsSecureContext() const final { |
| 129 DCHECK(IsContextThread()); |
| 130 String unused_error_message; |
| 131 return execution_context_->IsSecureContext(unused_error_message); |
| 132 } |
| 133 KURL FirstPartyForCookies() const final { |
| 134 // TODO(kinuko): Check if this is ok. |
| 135 DCHECK(IsContextThread()); |
| 136 return execution_context_->Url(); |
| 137 } |
| 138 String UserAgent() const final { |
| 139 DCHECK(IsContextThread()); |
| 140 return execution_context_->UserAgent(); |
| 141 } |
| 142 RefPtr<WebTaskRunner> GetTaskRunner(TaskType type) final { |
| 143 DCHECK(IsContextThread()); |
| 144 return task_runners_->Get(type); |
| 145 } |
| 146 void RecordUseCount(UseCounter::Feature feature) final { |
| 147 DCHECK(IsContextThread()); |
| 148 // TODO(kinuko): Implement this. |
| 149 } |
| 150 |
| 151 DEFINE_INLINE_TRACE() { |
| 152 visitor->Trace(execution_context_); |
| 153 visitor->Trace(task_runners_); |
| 154 visitor->Trace(resource_fetcher_); |
| 155 ThreadableLoadingContext::Trace(visitor); |
| 156 } |
| 157 |
| 158 private: |
| 159 Member<ExecutionContextImpl> execution_context_; |
| 160 Member<ParentFrameTaskRunners> task_runners_; |
| 161 Member<ResourceFetcher> resource_fetcher_; |
| 162 }; |
| 163 |
| 164 // static |
| 165 WorkerShadowFetchContext* WorkerShadowFetchContext::Create( |
| 166 const KURL& url, |
| 167 const String& user_agent, |
| 168 WebAddressSpace address_space, |
| 169 ApplicationCacheHost* app_cache_host, |
| 170 std::unique_ptr<WebServiceWorkerNetworkProvider> service_worker_provider, |
| 171 std::unique_ptr<Settings> settings, |
| 172 ParentFrameTaskRunners* task_runners) { |
| 173 ExecutionContextImpl* execution_context = |
| 174 new ExecutionContextImpl(url, user_agent, address_space); |
| 175 return new WorkerShadowFetchContext(execution_context, app_cache_host, |
| 176 std::move(service_worker_provider), |
| 177 std::move(settings), task_runners); |
| 178 } |
| 179 |
| 180 WorkerShadowFetchContext::~WorkerShadowFetchContext() = default; |
| 181 |
| 182 void WorkerShadowFetchContext::Detach() { |
| 183 // TODO(kinuko): Rename this. |
| 184 app_cache_host_->DetachFromDocumentLoader(); |
| 185 } |
| 186 |
| 187 void WorkerShadowFetchContext::AddAdditionalRequestHeaders( |
| 188 ResourceRequest& request, |
| 189 FetchResourceType type) { |
| 190 BaseFetchContext::AddAdditionalRequestHeaders(request, type); |
| 191 |
| 192 // The remaining modifications are only necessary for HTTP and HTTPS. |
| 193 if (!request.Url().IsEmpty() && !request.Url().ProtocolIsInHTTPFamily()) |
| 194 return; |
| 195 |
| 196 if (GetSettings() && GetSettings()->GetDataSaverEnabled()) |
| 197 request.SetHTTPHeaderField("Save-Data", "on"); |
| 198 } |
| 199 |
| 200 WebCachePolicy WorkerShadowFetchContext::ResourceRequestCachePolicy( |
| 201 const ResourceRequest& request, |
| 202 Resource::Type type, |
| 203 FetchParameters::DeferOption defer) const { |
| 204 if (request.HttpMethod() == "POST") |
| 205 return WebCachePolicy::kValidatingCacheData; |
| 206 return WebCachePolicy::kUseProtocolCachePolicy; |
| 207 } |
| 208 |
| 209 void WorkerShadowFetchContext::PrepareRequest(ResourceRequest& request, |
| 210 RedirectType redirect_type) { |
| 211 WrappedResourceRequest webreq(request); |
| 212 service_worker_provider_->WillSendRequest(webreq); |
| 213 |
| 214 if (redirect_type == RedirectType::kNotForRedirect) |
| 215 app_cache_host_->WillStartLoading(request); |
| 216 } |
| 217 |
| 218 void WorkerShadowFetchContext::DispatchWillSendRequest( |
| 219 unsigned long identifier, |
| 220 ResourceRequest& request, |
| 221 const ResourceResponse& redirect_response, |
| 222 const FetchInitiatorInfo& initiator_info) { |
| 223 /* |
| 224 probe::willSendRequest(GetFrame(), identifier, MasterDocumentLoader(), |
| 225 request, redirect_response, initiator_info); |
| 226 */ |
| 227 } |
| 228 |
| 229 void WorkerShadowFetchContext::DispatchDidReceiveResponse( |
| 230 unsigned long identifier, |
| 231 const ResourceResponse& response, |
| 232 WebURLRequest::FrameType frame_type, |
| 233 WebURLRequest::RequestContext request_context, |
| 234 Resource* resource, |
| 235 ResourceResponseType response_type) { |
| 236 /* |
| 237 probe::didReceiveResourceResponse(GetFrame(), identifier, document_loader, |
| 238 response, resource); |
| 239 */ |
| 240 } |
| 241 |
| 242 void WorkerShadowFetchContext::DispatchDidReceiveData(unsigned long identifier, |
| 243 const char* data, |
| 244 int data_length) { |
| 245 // probe::didReceiveData(GetFrame(), identifier, data, data_length); |
| 246 } |
| 247 |
| 248 void WorkerShadowFetchContext::DispatchDidReceiveEncodedData( |
| 249 unsigned long identifier, |
| 250 int encoded_data_length) { |
| 251 /* |
| 252 probe::didReceiveEncodedDataLength(GetFrame(), identifier, |
| 253 encoded_data_length); |
| 254 */ |
| 255 } |
| 256 |
| 257 void WorkerShadowFetchContext::DispatchDidFinishLoading( |
| 258 unsigned long identifier, |
| 259 double finish_time, |
| 260 int64_t encoded_data_length, |
| 261 int64_t decoded_body_length) { |
| 262 /* |
| 263 probe::didFinishLoading(GetFrame(), identifier, finish_time, |
| 264 encoded_data_length, decoded_body_length); |
| 265 */ |
| 266 } |
| 267 |
| 268 void WorkerShadowFetchContext::DispatchDidFail(unsigned long identifier, |
| 269 const ResourceError& error, |
| 270 int64_t encoded_data_length, |
| 271 bool is_internal_request) { |
| 272 /* |
| 273 probe::didFailLoading(GetFrame(), identifier, error); |
| 274 */ |
| 275 } |
| 276 |
| 277 void WorkerShadowFetchContext::AddResourceTiming( |
| 278 const ResourceTimingInfo& info) { |
| 279 /* |
| 280 DOMWindowPerformance::performance(*initiator_document->domWindow()) |
| 281 ->AddResourceTiming(info); |
| 282 */ |
| 283 } |
| 284 |
| 285 bool WorkerShadowFetchContext::AllowImage(bool images_enabled, |
| 286 const KURL& url) const { |
| 287 return !GetContentSettingsClient() || |
| 288 GetContentSettingsClient()->AllowImage(images_enabled, url); |
| 289 } |
| 290 |
| 291 bool WorkerShadowFetchContext::IsControlledByServiceWorker() const { |
| 292 return service_worker_provider_->IsControlledByServiceWorker(); |
| 293 } |
| 294 |
| 295 int64_t WorkerShadowFetchContext::ServiceWorkerID() const { |
| 296 return service_worker_provider_->ServiceWorkerID(); |
| 297 } |
| 298 |
| 299 void WorkerShadowFetchContext::PopulateResourceRequest( |
| 300 const KURL& url, |
| 301 Resource::Type type, |
| 302 const ClientHintsPreferences& hints_preferences, |
| 303 const FetchParameters::ResourceWidth& resource_width, |
| 304 const ResourceLoaderOptions& options, |
| 305 SecurityViolationReportingPolicy reporting_policy, |
| 306 ResourceRequest& request) { |
| 307 SetFirstPartyCookieAndRequestorOrigin(request); |
| 308 CheckCSPForRequest(request, url, options, reporting_policy, |
| 309 request.GetRedirectStatus(), |
| 310 ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly); |
| 311 AddCSPHeaderIfNecessary(type, request); |
| 312 } |
| 313 |
| 314 void WorkerShadowFetchContext::SetFirstPartyCookieAndRequestorOrigin( |
| 315 ResourceRequest& request) { |
| 316 if (request.FirstPartyForCookies().IsNull()) |
| 317 request.SetFirstPartyForCookies(loading_context_->FirstPartyForCookies()); |
| 318 } |
| 319 |
| 320 RefPtr<WebTaskRunner> WorkerShadowFetchContext::LoadingTaskRunner() const { |
| 321 return loading_context_->GetTaskRunner(TaskType::kNetworking); |
| 322 } |
| 323 |
| 324 ExecutionContext& WorkerShadowFetchContext::GetExecutionContext() { |
| 325 return *execution_context_; |
| 326 } |
| 327 |
| 328 SecurityContext& WorkerShadowFetchContext::GetSecurityContext() { |
| 329 return execution_context_->GetSecurityContext(); |
| 330 } |
| 331 |
| 332 ThreadableLoadingContext& |
| 333 WorkerShadowFetchContext::GetThreadableLoadingContext() { |
| 334 return *loading_context_; |
| 335 } |
| 336 |
| 337 Settings* WorkerShadowFetchContext::GetSettings() const { |
| 338 return settings_.get(); |
| 339 } |
| 340 |
| 341 SecurityContext* WorkerShadowFetchContext::GetParentSecurityContext() |
| 342 const { |
| 343 return execution_context_.Get(); |
| 344 } |
| 345 |
| 346 void WorkerShadowFetchContext::CountUsage(UseCounter::Feature feature) const { |
| 347 loading_context_->RecordUseCount(feature); |
| 348 } |
| 349 |
| 350 void WorkerShadowFetchContext::CountDeprecation( |
| 351 UseCounter::Feature feature) const { |
| 352 // As we won't show deprecation warning in {service,shared} workers |
| 353 // this could just be handled as a regular use count. |
| 354 loading_context_->RecordUseCount(feature); |
| 355 } |
| 356 |
| 357 DEFINE_TRACE(WorkerShadowFetchContext) { |
| 358 visitor->Trace(execution_context_); |
| 359 visitor->Trace(loading_context_); |
| 360 visitor->Trace(app_cache_host_); |
| 361 BaseFetchContext::Trace(visitor); |
| 362 } |
| 363 |
| 364 WorkerShadowFetchContext::WorkerShadowFetchContext( |
| 365 ExecutionContextImpl* execution_context, |
| 366 ApplicationCacheHost* app_cache_host, |
| 367 std::unique_ptr<WebServiceWorkerNetworkProvider> service_worker_provider, |
| 368 std::unique_ptr<Settings> settings, |
| 369 ParentFrameTaskRunners* task_runners) |
| 370 : BaseFetchContext(execution_context), |
| 371 execution_context_(execution_context), |
| 372 loading_context_(new LoadingContextImpl(execution_context, |
| 373 task_runners, |
| 374 ResourceFetcher::Create(this))), |
| 375 app_cache_host_(app_cache_host), |
| 376 service_worker_provider_(std::move(service_worker_provider)), |
| 377 settings_(std::move(settings)) {} |
| 378 |
| 379 } // namespace blink |
OLD | NEW |