Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: third_party/WebKit/Source/modules/serviceworkers/FetchRespondWithObserver.cpp

Issue 2715663002: ServiceWorker: Factor out FetchEvent related logics from RespondWithObserver. (Closed)
Patch Set: RespondWithObserver Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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/RespondWithObserver.h" 5 #include "modules/serviceworkers/FetchRespondWithObserver.h"
6 6
7 #include "bindings/core/v8/ScriptFunction.h" 7 #include <v8.h>
8 #include "bindings/core/v8/ScriptPromise.h"
9 #include "bindings/core/v8/ScriptValue.h" 8 #include "bindings/core/v8/ScriptValue.h"
10 #include "bindings/core/v8/V8Binding.h" 9 #include "bindings/core/v8/V8Binding.h"
11 #include "bindings/modules/v8/V8Response.h" 10 #include "bindings/modules/v8/V8Response.h"
12 #include "core/dom/ExceptionCode.h"
13 #include "core/dom/ExecutionContext.h" 11 #include "core/dom/ExecutionContext.h"
14 #include "core/inspector/ConsoleMessage.h" 12 #include "core/inspector/ConsoleMessage.h"
13 #include "core/inspector/ConsoleTypes.h"
15 #include "core/streams/Stream.h" 14 #include "core/streams/Stream.h"
16 #include "modules/fetch/BodyStreamBuffer.h" 15 #include "modules/fetch/BodyStreamBuffer.h"
17 #include "modules/fetch/BytesConsumer.h" 16 #include "modules/fetch/BytesConsumer.h"
18 #include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h" 17 #include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h"
19 #include "platform/RuntimeEnabledFeatures.h" 18 #include "modules/serviceworkers/WaitUntilObserver.h"
20 #include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h" 19 #include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h"
21 #include "v8/include/v8.h"
22 #include "wtf/Assertions.h"
23 #include "wtf/RefPtr.h"
24 20
25 namespace blink { 21 namespace blink {
26 namespace { 22 namespace {
27 23
28 // Returns the error message to let the developer know about the reason of the 24 // Returns the error message to let the developer know about the reason of the
29 // unusual failures. 25 // unusual failures.
30 const String getMessageForResponseError(WebServiceWorkerResponseError error, 26 const String getMessageForResponseError(WebServiceWorkerResponseError error,
31 const KURL& requestURL) { 27 const KURL& requestURL) {
32 String errorMessage = "The FetchEvent for \"" + requestURL.getString() + 28 String errorMessage = "The FetchEvent for \"" + requestURL.getString() +
33 "\" resulted in a network error response: "; 29 "\" resulted in a network error response: ";
(...skipping 14 matching lines...) Expand all
48 case WebServiceWorkerResponseErrorResponseTypeError: 44 case WebServiceWorkerResponseErrorResponseTypeError:
49 errorMessage = errorMessage + 45 errorMessage = errorMessage +
50 "the promise was resolved with an error response object."; 46 "the promise was resolved with an error response object.";
51 break; 47 break;
52 case WebServiceWorkerResponseErrorResponseTypeOpaque: 48 case WebServiceWorkerResponseErrorResponseTypeOpaque:
53 errorMessage = errorMessage + 49 errorMessage = errorMessage +
54 "an \"opaque\" response was used for a request whose type " 50 "an \"opaque\" response was used for a request whose type "
55 "is not no-cors"; 51 "is not no-cors";
56 break; 52 break;
57 case WebServiceWorkerResponseErrorResponseTypeNotBasicOrDefault: 53 case WebServiceWorkerResponseErrorResponseTypeNotBasicOrDefault:
58 ASSERT_NOT_REACHED(); 54 NOTREACHED();
59 break; 55 break;
60 case WebServiceWorkerResponseErrorBodyUsed: 56 case WebServiceWorkerResponseErrorBodyUsed:
61 errorMessage = errorMessage + 57 errorMessage = errorMessage +
62 "a Response whose \"bodyUsed\" is \"true\" cannot be used " 58 "a Response whose \"bodyUsed\" is \"true\" cannot be used "
63 "to respond to a request."; 59 "to respond to a request.";
64 break; 60 break;
65 case WebServiceWorkerResponseErrorResponseTypeOpaqueForClientRequest: 61 case WebServiceWorkerResponseErrorResponseTypeOpaqueForClientRequest:
66 errorMessage = errorMessage + 62 errorMessage = errorMessage +
67 "an \"opaque\" response was used for a client request."; 63 "an \"opaque\" response was used for a client request.";
68 break; 64 break;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 134
139 public: 135 public:
140 NoopLoaderClient() = default; 136 NoopLoaderClient() = default;
141 void didFetchDataLoadedStream() override {} 137 void didFetchDataLoadedStream() override {}
142 void didFetchDataLoadFailed() override {} 138 void didFetchDataLoadFailed() override {}
143 DEFINE_INLINE_TRACE() { FetchDataLoader::Client::trace(visitor); } 139 DEFINE_INLINE_TRACE() { FetchDataLoader::Client::trace(visitor); }
144 }; 140 };
145 141
146 } // namespace 142 } // namespace
147 143
148 class RespondWithObserver::ThenFunction final : public ScriptFunction { 144 FetchRespondWithObserver::~FetchRespondWithObserver() {}
nhiroki 2017/03/08 01:49:04 = default;
zino 2017/03/10 17:57:17 Done.
149 public:
150 enum ResolveType {
151 Fulfilled,
152 Rejected,
153 };
154 145
155 static v8::Local<v8::Function> createFunction(ScriptState* scriptState, 146 FetchRespondWithObserver* FetchRespondWithObserver::create(
156 RespondWithObserver* observer,
157 ResolveType type) {
158 ThenFunction* self = new ThenFunction(scriptState, observer, type);
159 return self->bindToV8Function();
160 }
161
162 DEFINE_INLINE_VIRTUAL_TRACE() {
163 visitor->trace(m_observer);
164 ScriptFunction::trace(visitor);
165 }
166
167 private:
168 ThenFunction(ScriptState* scriptState,
169 RespondWithObserver* observer,
170 ResolveType type)
171 : ScriptFunction(scriptState),
172 m_observer(observer),
173 m_resolveType(type) {}
174
175 ScriptValue call(ScriptValue value) override {
176 ASSERT(m_observer);
177 ASSERT(m_resolveType == Fulfilled || m_resolveType == Rejected);
178 if (m_resolveType == Rejected) {
179 m_observer->responseWasRejected(
180 WebServiceWorkerResponseErrorPromiseRejected);
181 value =
182 ScriptPromise::reject(value.getScriptState(), value).getScriptValue();
183 } else {
184 m_observer->responseWasFulfilled(value);
185 }
186 m_observer = nullptr;
187 return value;
188 }
189
190 Member<RespondWithObserver> m_observer;
191 ResolveType m_resolveType;
192 };
193
194 RespondWithObserver::~RespondWithObserver() {}
195
196 RespondWithObserver* RespondWithObserver::create(
197 ExecutionContext* context, 147 ExecutionContext* context,
198 int fetchEventID, 148 int fetchEventID,
199 const KURL& requestURL, 149 const KURL& requestURL,
200 WebURLRequest::FetchRequestMode requestMode, 150 WebURLRequest::FetchRequestMode requestMode,
201 WebURLRequest::FetchRedirectMode redirectMode, 151 WebURLRequest::FetchRedirectMode redirectMode,
202 WebURLRequest::FrameType frameType, 152 WebURLRequest::FrameType frameType,
203 WebURLRequest::RequestContext requestContext, 153 WebURLRequest::RequestContext requestContext,
204 WaitUntilObserver* observer) { 154 WaitUntilObserver* observer) {
205 return new RespondWithObserver(context, fetchEventID, requestURL, requestMode, 155 return new FetchRespondWithObserver(context, fetchEventID, requestURL,
206 redirectMode, frameType, requestContext, 156 requestMode, redirectMode, frameType,
207 observer); 157 requestContext, observer);
208 } 158 }
209 159
210 void RespondWithObserver::contextDestroyed(ExecutionContext*) { 160 void FetchRespondWithObserver::didDispatchEvent(
211 if (m_observer) { 161 DispatchEventResult dispatchResult) {
212 DCHECK_EQ(Pending, m_state); 162 DCHECK(getExecutionContext());
213 m_observer.clear();
214 }
215 m_state = Done;
216 }
217
218 void RespondWithObserver::willDispatchEvent() {
219 m_eventDispatchTime = WTF::currentTime();
220 }
221
222 void RespondWithObserver::didDispatchEvent(DispatchEventResult dispatchResult) {
223 ASSERT(getExecutionContext());
224 if (m_state != Initial) 163 if (m_state != Initial)
225 return; 164 return;
226 165
227 if (dispatchResult != DispatchEventResult::NotCanceled) { 166 if (dispatchResult != DispatchEventResult::NotCanceled) {
228 m_observer->incrementPendingActivity(); 167 m_observer->incrementPendingActivity();
229 responseWasRejected(WebServiceWorkerResponseErrorDefaultPrevented); 168 responseWasRejected(WebServiceWorkerResponseErrorDefaultPrevented);
230 return; 169 return;
231 } 170 }
232 171
233 ServiceWorkerGlobalScopeClient::from(getExecutionContext()) 172 ServiceWorkerGlobalScopeClient::from(getExecutionContext())
234 ->respondToFetchEvent(m_fetchEventID, m_eventDispatchTime); 173 ->respondToFetchEvent(m_eventID, m_eventDispatchTime);
235 m_state = Done; 174 m_state = Done;
236 m_observer.clear(); 175 m_observer.clear();
nhiroki 2017/03/08 01:49:04 Is it possible to move line 174-175 into RespondWi
zino 2017/03/10 17:57:17 Anyway done. The didDispatchEvent() is no longer v
237 } 176 }
238 177
239 void RespondWithObserver::respondWith(ScriptState* scriptState, 178 void FetchRespondWithObserver::responseWasRejected(
240 ScriptPromise scriptPromise,
241 ExceptionState& exceptionState) {
242 if (m_state != Initial) {
243 exceptionState.throwDOMException(
244 InvalidStateError, "The fetch event has already been responded to.");
245 return;
246 }
247
248 m_state = Pending;
249 m_observer->incrementPendingActivity();
250 scriptPromise.then(
251 ThenFunction::createFunction(scriptState, this, ThenFunction::Fulfilled),
252 ThenFunction::createFunction(scriptState, this, ThenFunction::Rejected));
253 }
254
255 void RespondWithObserver::responseWasRejected(
256 WebServiceWorkerResponseError error) { 179 WebServiceWorkerResponseError error) {
257 ASSERT(getExecutionContext()); 180 DCHECK(getExecutionContext());
258 getExecutionContext()->addConsoleMessage( 181 getExecutionContext()->addConsoleMessage(
259 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, 182 ConsoleMessage::create(JSMessageSource, WarningMessageLevel,
260 getMessageForResponseError(error, m_requestURL))); 183 getMessageForResponseError(error, m_requestURL)));
261 184
262 // The default value of WebServiceWorkerResponse's status is 0, which maps 185 // The default value of WebServiceWorkerResponse's status is 0, which maps
263 // to a network error. 186 // to a network error.
264 WebServiceWorkerResponse webResponse; 187 WebServiceWorkerResponse webResponse;
265 webResponse.setError(error); 188 webResponse.setError(error);
266 ServiceWorkerGlobalScopeClient::from(getExecutionContext()) 189 ServiceWorkerGlobalScopeClient::from(getExecutionContext())
267 ->respondToFetchEvent(m_fetchEventID, webResponse, m_eventDispatchTime); 190 ->respondToFetchEvent(m_eventID, webResponse, m_eventDispatchTime);
268 m_state = Done; 191 RespondWithObserver::responseWasRejected(error);
269 m_observer->decrementPendingActivity();
270 m_observer.clear();
271 } 192 }
272 193
273 void RespondWithObserver::responseWasFulfilled(const ScriptValue& value) { 194 void FetchRespondWithObserver::responseWasFulfilled(const ScriptValue& value) {
274 ASSERT(getExecutionContext()); 195 DCHECK(getExecutionContext());
275 if (!V8Response::hasInstance(value.v8Value(), 196 if (!V8Response::hasInstance(value.v8Value(),
276 toIsolate(getExecutionContext()))) { 197 toIsolate(getExecutionContext()))) {
277 responseWasRejected(WebServiceWorkerResponseErrorNoV8Instance); 198 responseWasRejected(WebServiceWorkerResponseErrorNoV8Instance);
278 return; 199 return;
279 } 200 }
280 Response* response = V8Response::toImplWithTypeCheck( 201 Response* response = V8Response::toImplWithTypeCheck(
281 toIsolate(getExecutionContext()), value.v8Value()); 202 toIsolate(getExecutionContext()), value.v8Value());
282 // "If one of the following conditions is true, return a network error: 203 // "If one of the following conditions is true, return a network error:
283 // - |response|'s type is |error|. 204 // - |response|'s type is |error|.
284 // - |request|'s mode is not |no-cors| and response's type is |opaque|. 205 // - |request|'s mode is not |no-cors| and response's type is |opaque|.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 if (blobDataHandle) { 266 if (blobDataHandle) {
346 webResponse.setBlobDataHandle(blobDataHandle); 267 webResponse.setBlobDataHandle(blobDataHandle);
347 } else { 268 } else {
348 Stream* outStream = Stream::create(getExecutionContext(), ""); 269 Stream* outStream = Stream::create(getExecutionContext(), "");
349 webResponse.setStreamURL(outStream->url()); 270 webResponse.setStreamURL(outStream->url());
350 buffer->startLoading(FetchDataLoader::createLoaderAsStream(outStream), 271 buffer->startLoading(FetchDataLoader::createLoaderAsStream(outStream),
351 new NoopLoaderClient); 272 new NoopLoaderClient);
352 } 273 }
353 } 274 }
354 ServiceWorkerGlobalScopeClient::from(getExecutionContext()) 275 ServiceWorkerGlobalScopeClient::from(getExecutionContext())
355 ->respondToFetchEvent(m_fetchEventID, webResponse, m_eventDispatchTime); 276 ->respondToFetchEvent(m_eventID, webResponse, m_eventDispatchTime);
356 m_state = Done; 277 RespondWithObserver::responseWasFulfilled(value);
357 m_observer->decrementPendingActivity();
358 m_observer.clear();
359 } 278 }
360 279
361 RespondWithObserver::RespondWithObserver( 280 FetchRespondWithObserver::FetchRespondWithObserver(
362 ExecutionContext* context, 281 ExecutionContext* context,
363 int fetchEventID, 282 int fetchEventID,
364 const KURL& requestURL, 283 const KURL& requestURL,
365 WebURLRequest::FetchRequestMode requestMode, 284 WebURLRequest::FetchRequestMode requestMode,
366 WebURLRequest::FetchRedirectMode redirectMode, 285 WebURLRequest::FetchRedirectMode redirectMode,
367 WebURLRequest::FrameType frameType, 286 WebURLRequest::FrameType frameType,
368 WebURLRequest::RequestContext requestContext, 287 WebURLRequest::RequestContext requestContext,
369 WaitUntilObserver* observer) 288 WaitUntilObserver* observer)
370 : ContextLifecycleObserver(context), 289 : RespondWithObserver(context, fetchEventID, observer),
371 m_fetchEventID(fetchEventID),
372 m_requestURL(requestURL), 290 m_requestURL(requestURL),
373 m_requestMode(requestMode), 291 m_requestMode(requestMode),
374 m_redirectMode(redirectMode), 292 m_redirectMode(redirectMode),
375 m_frameType(frameType), 293 m_frameType(frameType),
376 m_requestContext(requestContext), 294 m_requestContext(requestContext) {}
377 m_state(Initial),
378 m_observer(observer) {}
379 295
380 DEFINE_TRACE(RespondWithObserver) { 296 DEFINE_TRACE(FetchRespondWithObserver) {
381 visitor->trace(m_observer); 297 RespondWithObserver::trace(visitor);
382 ContextLifecycleObserver::trace(visitor);
383 } 298 }
384 299
385 } // namespace blink 300 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698