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 |