| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "modules/serviceworkers/FetchEvent.h" | 5 #include "modules/serviceworkers/FetchEvent.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ToV8ForCore.h" | 7 #include "bindings/core/v8/ToV8ForCore.h" |
| 8 #include "core/dom/ExecutionContext.h" | 8 #include "core/dom/ExecutionContext.h" |
| 9 #include "core/timing/WorkerGlobalScopePerformance.h" | 9 #include "core/timing/WorkerGlobalScopePerformance.h" |
| 10 #include "modules/fetch/BytesConsumerForDataConsumerHandle.h" | 10 #include "modules/fetch/BytesConsumerForDataConsumerHandle.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 } | 62 } |
| 63 | 63 |
| 64 ScriptPromise FetchEvent::preloadResponse(ScriptState* script_state) { | 64 ScriptPromise FetchEvent::preloadResponse(ScriptState* script_state) { |
| 65 return preload_response_property_->Promise(script_state->World()); | 65 return preload_response_property_->Promise(script_state->World()); |
| 66 } | 66 } |
| 67 | 67 |
| 68 const AtomicString& FetchEvent::InterfaceName() const { | 68 const AtomicString& FetchEvent::InterfaceName() const { |
| 69 return EventNames::FetchEvent; | 69 return EventNames::FetchEvent; |
| 70 } | 70 } |
| 71 | 71 |
| 72 bool FetchEvent::HasPendingActivity() const { |
| 73 // Prevent V8 from garbage collecting the wrapper object while waiting for the |
| 74 // preload response. This is in order to keep the resolver of preloadResponse |
| 75 // Promise alive. |
| 76 return waiting_for_preload_response_ && GetExecutionContext(); |
| 77 } |
| 78 |
| 72 FetchEvent::FetchEvent(ScriptState* script_state, | 79 FetchEvent::FetchEvent(ScriptState* script_state, |
| 73 const AtomicString& type, | 80 const AtomicString& type, |
| 74 const FetchEventInit& initializer, | 81 const FetchEventInit& initializer, |
| 75 FetchRespondWithObserver* respond_with_observer, | 82 FetchRespondWithObserver* respond_with_observer, |
| 76 WaitUntilObserver* wait_until_observer, | 83 WaitUntilObserver* wait_until_observer, |
| 77 bool navigation_preload_sent) | 84 bool navigation_preload_sent) |
| 78 : ExtendableEvent(type, initializer, wait_until_observer), | 85 : ExtendableEvent(type, initializer, wait_until_observer), |
| 86 ContextClient(ExecutionContext::From(script_state)), |
| 79 observer_(respond_with_observer), | 87 observer_(respond_with_observer), |
| 80 preload_response_property_(new PreloadResponseProperty( | 88 preload_response_property_(new PreloadResponseProperty( |
| 81 ExecutionContext::From(script_state), | 89 ExecutionContext::From(script_state), |
| 82 this, | 90 this, |
| 83 PreloadResponseProperty::kPreloadResponse)) { | 91 PreloadResponseProperty::kPreloadResponse)), |
| 92 waiting_for_preload_response_(navigation_preload_sent) { |
| 84 if (!navigation_preload_sent) | 93 if (!navigation_preload_sent) |
| 85 preload_response_property_->ResolveWithUndefined(); | 94 preload_response_property_->ResolveWithUndefined(); |
| 86 | 95 |
| 87 client_id_ = initializer.clientId(); | 96 client_id_ = initializer.clientId(); |
| 88 is_reload_ = initializer.isReload(); | 97 is_reload_ = initializer.isReload(); |
| 89 if (initializer.hasRequest()) { | 98 if (initializer.hasRequest()) { |
| 90 ScriptState::Scope scope(script_state); | 99 ScriptState::Scope scope(script_state); |
| 91 request_ = initializer.request(); | 100 request_ = initializer.request(); |
| 92 v8::Local<v8::Value> request = ToV8(request_, script_state); | 101 v8::Local<v8::Value> request = ToV8(request_, script_state); |
| 93 v8::Local<v8::Value> event = ToV8(this, script_state); | 102 v8::Local<v8::Value> event = ToV8(this, script_state); |
| 94 if (event.IsEmpty()) { | 103 if (event.IsEmpty()) { |
| 95 // |toV8| can return an empty handle when the worker is terminating. | 104 // |toV8| can return an empty handle when the worker is terminating. |
| 96 // We don't want the renderer to crash in such cases. | 105 // We don't want the renderer to crash in such cases. |
| 97 // TODO(yhirano): Replace this branch with an assertion when the | 106 // TODO(yhirano): Replace this branch with an assertion when the |
| 98 // graceful shutdown mechanism is introduced. | 107 // graceful shutdown mechanism is introduced. |
| 99 return; | 108 return; |
| 100 } | 109 } |
| 101 DCHECK(event->IsObject()); | 110 DCHECK(event->IsObject()); |
| 102 // Sets a hidden value in order to teach V8 the dependency from | 111 // Sets a hidden value in order to teach V8 the dependency from |
| 103 // the event to the request. | 112 // the event to the request. |
| 104 V8PrivateProperty::GetFetchEventRequest(script_state->GetIsolate()) | 113 V8PrivateProperty::GetFetchEventRequest(script_state->GetIsolate()) |
| 105 .Set(event.As<v8::Object>(), request); | 114 .Set(event.As<v8::Object>(), request); |
| 106 // From the same reason as above, setHiddenValue can return false. | 115 // From the same reason as above, setHiddenValue can return false. |
| 107 // TODO(yhirano): Add an assertion that it returns true once the | 116 // TODO(yhirano): Add an assertion that it returns true once the |
| 108 // graceful shutdown mechanism is introduced. | 117 // graceful shutdown mechanism is introduced. |
| 109 } | 118 } |
| 110 } | 119 } |
| 111 | 120 |
| 121 FetchEvent::~FetchEvent() {} |
| 122 |
| 112 void FetchEvent::OnNavigationPreloadResponse( | 123 void FetchEvent::OnNavigationPreloadResponse( |
| 113 ScriptState* script_state, | 124 ScriptState* script_state, |
| 114 std::unique_ptr<WebURLResponse> response, | 125 std::unique_ptr<WebURLResponse> response, |
| 115 std::unique_ptr<WebDataConsumerHandle> data_consume_handle) { | 126 std::unique_ptr<WebDataConsumerHandle> data_consume_handle) { |
| 116 if (!script_state->ContextIsValid()) | 127 if (!script_state->ContextIsValid()) |
| 117 return; | 128 return; |
| 118 DCHECK(preload_response_property_); | 129 DCHECK(preload_response_property_); |
| 119 DCHECK(!preload_response_); | 130 DCHECK(!preload_response_); |
| 120 ScriptState::Scope scope(script_state); | 131 ScriptState::Scope scope(script_state); |
| 121 preload_response_ = std::move(response); | 132 preload_response_ = std::move(response); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 142 NetworkUtils::IsRedirectResponseCode(preload_response_->HttpStatusCode()) | 153 NetworkUtils::IsRedirectResponseCode(preload_response_->HttpStatusCode()) |
| 143 ? response_data->CreateOpaqueRedirectFilteredResponse() | 154 ? response_data->CreateOpaqueRedirectFilteredResponse() |
| 144 : response_data->CreateBasicFilteredResponse(); | 155 : response_data->CreateBasicFilteredResponse(); |
| 145 preload_response_property_->Resolve( | 156 preload_response_property_->Resolve( |
| 146 Response::Create(ExecutionContext::From(script_state), tainted_response)); | 157 Response::Create(ExecutionContext::From(script_state), tainted_response)); |
| 147 } | 158 } |
| 148 | 159 |
| 149 void FetchEvent::OnNavigationPreloadError( | 160 void FetchEvent::OnNavigationPreloadError( |
| 150 ScriptState* script_state, | 161 ScriptState* script_state, |
| 151 std::unique_ptr<WebServiceWorkerError> error) { | 162 std::unique_ptr<WebServiceWorkerError> error) { |
| 163 waiting_for_preload_response_ = false; |
| 152 if (!script_state->ContextIsValid()) | 164 if (!script_state->ContextIsValid()) |
| 153 return; | 165 return; |
| 154 DCHECK(preload_response_property_); | 166 DCHECK(preload_response_property_); |
| 155 preload_response_property_->Reject( | 167 preload_response_property_->Reject( |
| 156 ServiceWorkerError::Take(nullptr, *error.get())); | 168 ServiceWorkerError::Take(nullptr, *error.get())); |
| 157 } | 169 } |
| 158 | 170 |
| 159 void FetchEvent::OnNavigationPreloadComplete( | 171 void FetchEvent::OnNavigationPreloadComplete( |
| 160 WorkerGlobalScope* worker_global_scope, | 172 WorkerGlobalScope* worker_global_scope, |
| 161 double completion_time, | 173 double completion_time, |
| 162 int64_t encoded_data_length, | 174 int64_t encoded_data_length, |
| 163 int64_t encoded_body_length, | 175 int64_t encoded_body_length, |
| 164 int64_t decoded_body_length) { | 176 int64_t decoded_body_length) { |
| 165 DCHECK(preload_response_); | 177 DCHECK(preload_response_); |
| 178 waiting_for_preload_response_ = false; |
| 166 std::unique_ptr<WebURLResponse> response = std::move(preload_response_); | 179 std::unique_ptr<WebURLResponse> response = std::move(preload_response_); |
| 167 ResourceResponse resource_response = response->ToResourceResponse(); | 180 ResourceResponse resource_response = response->ToResourceResponse(); |
| 168 resource_response.SetEncodedDataLength(encoded_data_length); | 181 resource_response.SetEncodedDataLength(encoded_data_length); |
| 169 resource_response.SetEncodedBodyLength(encoded_body_length); | 182 resource_response.SetEncodedBodyLength(encoded_body_length); |
| 170 resource_response.SetDecodedBodyLength(decoded_body_length); | 183 resource_response.SetDecodedBodyLength(decoded_body_length); |
| 171 // According to the current spec of Resource Timing, the initiator type of | 184 // According to the current spec of Resource Timing, the initiator type of |
| 172 // navigation preload request must be "other". But it may change when the spec | 185 // navigation preload request must be "other". But it may change when the spec |
| 173 // discussion is settled. https://github.com/w3c/resource-timing/issues/110 | 186 // discussion is settled. https://github.com/w3c/resource-timing/issues/110 |
| 174 RefPtr<ResourceTimingInfo> info = ResourceTimingInfo::Create( | 187 RefPtr<ResourceTimingInfo> info = ResourceTimingInfo::Create( |
| 175 "other", resource_response.GetResourceLoadTiming()->RequestTime(), | 188 "other", resource_response.GetResourceLoadTiming()->RequestTime(), |
| 176 false /* is_main_resource */); | 189 false /* is_main_resource */); |
| 177 info->SetNegativeAllowed(true); | 190 info->SetNegativeAllowed(true); |
| 178 info->SetLoadFinishTime(completion_time); | 191 info->SetLoadFinishTime(completion_time); |
| 179 info->SetInitialURL(request_->url()); | 192 info->SetInitialURL(request_->url()); |
| 180 info->SetFinalResponse(resource_response); | 193 info->SetFinalResponse(resource_response); |
| 181 info->AddFinalTransferSize(encoded_data_length); | 194 info->AddFinalTransferSize(encoded_data_length); |
| 182 WorkerGlobalScopePerformance::performance(*worker_global_scope) | 195 WorkerGlobalScopePerformance::performance(*worker_global_scope) |
| 183 ->AddResourceTiming(*info); | 196 ->AddResourceTiming(*info); |
| 184 } | 197 } |
| 185 | 198 |
| 186 DEFINE_TRACE(FetchEvent) { | 199 DEFINE_TRACE(FetchEvent) { |
| 187 visitor->Trace(observer_); | 200 visitor->Trace(observer_); |
| 188 visitor->Trace(request_); | 201 visitor->Trace(request_); |
| 189 visitor->Trace(preload_response_property_); | 202 visitor->Trace(preload_response_property_); |
| 190 ExtendableEvent::Trace(visitor); | 203 ExtendableEvent::Trace(visitor); |
| 204 ContextClient::Trace(visitor); |
| 191 } | 205 } |
| 192 | 206 |
| 193 } // namespace blink | 207 } // namespace blink |
| OLD | NEW |