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