 Chromium Code Reviews
 Chromium Code Reviews Issue 2416843002:
  Implement FetchEvent.navigationPreload  (Closed)
    
  
    Issue 2416843002:
  Implement FetchEvent.navigationPreload  (Closed) 
  | 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/ToV8.h" | 7 #include "bindings/core/v8/ToV8.h" | 
| 8 #include "bindings/core/v8/V8HiddenValue.h" | 8 #include "bindings/core/v8/V8HiddenValue.h" | 
| 9 #include "modules/fetch/BytesConsumerForDataConsumerHandle.h" | |
| 9 #include "modules/fetch/Request.h" | 10 #include "modules/fetch/Request.h" | 
| 11 #include "modules/fetch/Response.h" | |
| 12 #include "modules/serviceworkers/ServiceWorkerError.h" | |
| 10 #include "modules/serviceworkers/ServiceWorkerGlobalScope.h" | 13 #include "modules/serviceworkers/ServiceWorkerGlobalScope.h" | 
| 14 #include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h" | |
| 11 #include "wtf/RefPtr.h" | 15 #include "wtf/RefPtr.h" | 
| 12 | 16 | 
| 13 namespace blink { | 17 namespace blink { | 
| 14 | 18 | 
| 15 FetchEvent* FetchEvent::create(ScriptState* scriptState, | 19 FetchEvent* FetchEvent::create(ScriptState* scriptState, | 
| 16 const AtomicString& type, | 20 const AtomicString& type, | 
| 17 const FetchEventInit& initializer) { | 21 const FetchEventInit& initializer) { | 
| 18 return new FetchEvent(scriptState, type, initializer, nullptr, nullptr); | 22 return new FetchEvent(scriptState, type, initializer, nullptr, nullptr, | 
| 23 false); | |
| 19 } | 24 } | 
| 20 | 25 | 
| 21 FetchEvent* FetchEvent::create(ScriptState* scriptState, | 26 FetchEvent* FetchEvent::create(ScriptState* scriptState, | 
| 22 const AtomicString& type, | 27 const AtomicString& type, | 
| 23 const FetchEventInit& initializer, | 28 const FetchEventInit& initializer, | 
| 24 RespondWithObserver* respondWithObserver, | 29 RespondWithObserver* respondWithObserver, | 
| 25 WaitUntilObserver* waitUntilObserver) { | 30 WaitUntilObserver* waitUntilObserver, | 
| 31 bool navigationPreloadSent) { | |
| 26 return new FetchEvent(scriptState, type, initializer, respondWithObserver, | 32 return new FetchEvent(scriptState, type, initializer, respondWithObserver, | 
| 27 waitUntilObserver); | 33 waitUntilObserver, navigationPreloadSent); | 
| 28 } | 34 } | 
| 29 | 35 | 
| 30 Request* FetchEvent::request() const { | 36 Request* FetchEvent::request() const { | 
| 31 return m_request; | 37 return m_request; | 
| 32 } | 38 } | 
| 33 | 39 | 
| 34 String FetchEvent::clientId() const { | 40 String FetchEvent::clientId() const { | 
| 35 return m_clientId; | 41 return m_clientId; | 
| 36 } | 42 } | 
| 37 | 43 | 
| 38 bool FetchEvent::isReload() const { | 44 bool FetchEvent::isReload() const { | 
| 39 return m_isReload; | 45 return m_isReload; | 
| 40 } | 46 } | 
| 41 | 47 | 
| 42 void FetchEvent::respondWith(ScriptState* scriptState, | 48 void FetchEvent::respondWith(ScriptState* scriptState, | 
| 43 ScriptPromise scriptPromise, | 49 ScriptPromise scriptPromise, | 
| 44 ExceptionState& exceptionState) { | 50 ExceptionState& exceptionState) { | 
| 45 stopImmediatePropagation(); | 51 stopImmediatePropagation(); | 
| 46 if (m_observer) | 52 if (m_observer) | 
| 47 m_observer->respondWith(scriptState, scriptPromise, exceptionState); | 53 m_observer->respondWith(scriptState, scriptPromise, exceptionState); | 
| 48 } | 54 } | 
| 49 | 55 | 
| 56 ScriptPromise FetchEvent::navigationPreload(ScriptState* scriptState, | |
| 57 bool& isNull) { | |
| 58 if (!m_navigationPreloadProperty) { | |
| 59 isNull = true; | |
| 60 return ScriptPromise(); | |
| 61 } | |
| 62 return m_navigationPreloadProperty->promise(scriptState->world()); | |
| 63 } | |
| 64 | |
| 50 const AtomicString& FetchEvent::interfaceName() const { | 65 const AtomicString& FetchEvent::interfaceName() const { | 
| 51 return EventNames::FetchEvent; | 66 return EventNames::FetchEvent; | 
| 52 } | 67 } | 
| 53 | 68 | 
| 54 FetchEvent::FetchEvent(ScriptState* scriptState, | 69 FetchEvent::FetchEvent(ScriptState* scriptState, | 
| 55 const AtomicString& type, | 70 const AtomicString& type, | 
| 56 const FetchEventInit& initializer, | 71 const FetchEventInit& initializer, | 
| 57 RespondWithObserver* respondWithObserver, | 72 RespondWithObserver* respondWithObserver, | 
| 58 WaitUntilObserver* waitUntilObserver) | 73 WaitUntilObserver* waitUntilObserver, | 
| 74 bool navigationPreloadSent) | |
| 59 : ExtendableEvent(type, initializer, waitUntilObserver), | 75 : ExtendableEvent(type, initializer, waitUntilObserver), | 
| 60 m_observer(respondWithObserver) { | 76 m_observer(respondWithObserver) { | 
| 77 if (navigationPreloadSent) { | |
| 78 m_navigationPreloadProperty = | |
| 79 new PreloadResponseProperty(scriptState->getExecutionContext(), this, | |
| 80 PreloadResponseProperty::PreloadResponse); | |
| 81 } | |
| 82 | |
| 61 m_clientId = initializer.clientId(); | 83 m_clientId = initializer.clientId(); | 
| 62 m_isReload = initializer.isReload(); | 84 m_isReload = initializer.isReload(); | 
| 63 if (initializer.hasRequest()) { | 85 if (initializer.hasRequest()) { | 
| 64 ScriptState::Scope scope(scriptState); | 86 ScriptState::Scope scope(scriptState); | 
| 65 m_request = initializer.request(); | 87 m_request = initializer.request(); | 
| 66 v8::Local<v8::Value> request = toV8(m_request, scriptState); | 88 v8::Local<v8::Value> request = toV8(m_request, scriptState); | 
| 67 v8::Local<v8::Value> event = toV8(this, scriptState); | 89 v8::Local<v8::Value> event = toV8(this, scriptState); | 
| 68 if (event.IsEmpty()) { | 90 if (event.IsEmpty()) { | 
| 69 // |toV8| can return an empty handle when the worker is terminating. | 91 // |toV8| can return an empty handle when the worker is terminating. | 
| 70 // We don't want the renderer to crash in such cases. | 92 // We don't want the renderer to crash in such cases. | 
| 71 // TODO(yhirano): Replace this branch with an assertion when the | 93 // TODO(yhirano): Replace this branch with an assertion when the | 
| 72 // graceful shutdown mechanism is introduced. | 94 // graceful shutdown mechanism is introduced. | 
| 73 return; | 95 return; | 
| 74 } | 96 } | 
| 75 DCHECK(event->IsObject()); | 97 DCHECK(event->IsObject()); | 
| 76 // Sets a hidden value in order to teach V8 the dependency from | 98 // Sets a hidden value in order to teach V8 the dependency from | 
| 77 // the event to the request. | 99 // the event to the request. | 
| 78 V8HiddenValue::setHiddenValue( | 100 V8HiddenValue::setHiddenValue( | 
| 79 scriptState, event.As<v8::Object>(), | 101 scriptState, event.As<v8::Object>(), | 
| 80 V8HiddenValue::requestInFetchEvent(scriptState->isolate()), request); | 102 V8HiddenValue::requestInFetchEvent(scriptState->isolate()), request); | 
| 81 // From the same reason as above, setHiddenValue can return false. | 103 // From the same reason as above, setHiddenValue can return false. | 
| 82 // TODO(yhirano): Add an assertion that it returns true once the | 104 // TODO(yhirano): Add an assertion that it returns true once the | 
| 83 // graceful shutdown mechanism is introduced. | 105 // graceful shutdown mechanism is introduced. | 
| 84 } | 106 } | 
| 85 } | 107 } | 
| 86 | 108 | 
| 109 class FetchEvent::PreloadResponseCallbackImpl | |
| 110 : public WebServiceWorkerPreloadResponseCallbacks { | |
| 111 public: | |
| 112 explicit PreloadResponseCallbackImpl( | |
| 
falken
2016/10/19 06:00:13
nit: dont need explicit
 
horo
2016/10/19 07:11:45
Done.
 | |
| 113 FetchEvent::PreloadResponseProperty* preloadResponseProperty, | |
| 114 ScriptState* scriptState) | |
| 115 : m_navigationPreloadProperty(preloadResponseProperty), | |
| 116 m_scriptState(scriptState) {} | |
| 117 ~PreloadResponseCallbackImpl() override {} | |
| 118 | |
| 119 void onSuccess( | |
| 120 WebServiceWorkerPreloadResponseCallbacksResult* result) override { | |
| 121 if (!m_navigationPreloadProperty->getExecutionContext() || | |
| 122 m_navigationPreloadProperty->getExecutionContext() | |
| 123 ->activeDOMObjectsAreStopped()) { | |
| 124 return; | |
| 125 } | |
| 126 ScriptState::Scope scope(m_scriptState.get()); | |
| 127 FetchResponseData* responseData = | |
| 128 FetchResponseData::createWithBuffer(new BodyStreamBuffer( | |
| 129 m_scriptState.get(), | |
| 130 new BytesConsumerForDataConsumerHandle( | |
| 131 m_navigationPreloadProperty->getExecutionContext(), | |
| 132 std::move(result->handle)))); | |
| 133 responseData->setURL(result->response->url()); | |
| 134 responseData->setStatus(result->response->status()); | |
| 135 responseData->setStatusMessage(result->response->statusText()); | |
| 136 responseData->setResponseTime(result->response->responseTime()); | |
| 137 for (HTTPHeaderMap::const_iterator i = result->response->headers().begin(), | |
| 138 end = result->response->headers().end(); | |
| 139 i != end; ++i) { | |
| 140 responseData->headerList()->append(i->key, i->value); | |
| 141 } | |
| 142 | |
| 143 FetchResponseData* taintedResponse = | |
| 144 responseData->createBasicFilteredResponse(); | |
| 145 m_navigationPreloadProperty->resolve(Response::create( | |
| 146 m_navigationPreloadProperty->getExecutionContext(), taintedResponse)); | |
| 147 } | |
| 148 | |
| 149 void onError(WebServiceWorkerError error) override { | |
| 150 if (!m_navigationPreloadProperty->getExecutionContext() || | |
| 151 m_navigationPreloadProperty->getExecutionContext() | |
| 152 ->activeDOMObjectsAreStopped()) { | |
| 153 return; | |
| 154 } | |
| 155 m_navigationPreloadProperty->reject( | |
| 156 ServiceWorkerError::take(nullptr, error)); | |
| 157 } | |
| 158 | |
| 159 private: | |
| 160 Persistent<FetchEvent::PreloadResponseProperty> m_navigationPreloadProperty; | |
| 161 RefPtr<ScriptState> m_scriptState; | |
| 162 | |
| 163 WTF_MAKE_NONCOPYABLE(PreloadResponseCallbackImpl); | |
| 164 }; | |
| 165 | |
| 166 WebServiceWorkerPreloadResponseCallbacks* | |
| 167 FetchEvent::createPreloadResponseCallback(ScriptState* scriptState) { | |
| 168 return new PreloadResponseCallbackImpl(m_navigationPreloadProperty, | |
| 169 scriptState); | |
| 170 } | |
| 171 | |
| 87 DEFINE_TRACE(FetchEvent) { | 172 DEFINE_TRACE(FetchEvent) { | 
| 88 visitor->trace(m_observer); | 173 visitor->trace(m_observer); | 
| 89 visitor->trace(m_request); | 174 visitor->trace(m_request); | 
| 175 visitor->trace(m_navigationPreloadProperty); | |
| 90 ExtendableEvent::trace(visitor); | 176 ExtendableEvent::trace(visitor); | 
| 91 } | 177 } | 
| 92 | 178 | 
| 93 } // namespace blink | 179 } // namespace blink | 
| OLD | NEW |