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

Unified Diff: third_party/WebKit/Source/modules/serviceworkers/RespondWithObserver.cpp

Issue 2715663002: ServiceWorker: Factor out FetchEvent related logics from RespondWithObserver. (Closed)
Patch Set: ServiceWorker: Factor out FetchEvent related logics from 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/serviceworkers/RespondWithObserver.cpp
diff --git a/third_party/WebKit/Source/modules/serviceworkers/RespondWithObserver.cpp b/third_party/WebKit/Source/modules/serviceworkers/RespondWithObserver.cpp
index abde40fe3f13b834c847d000bce79648f3322295..550df7e7462e6be25e1d1aea1739f66c9b7dddda 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/RespondWithObserver.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/RespondWithObserver.cpp
@@ -4,146 +4,17 @@
#include "modules/serviceworkers/RespondWithObserver.h"
+#include <v8.h>
+
#include "bindings/core/v8/ScriptFunction.h"
#include "bindings/core/v8/ScriptPromise.h"
#include "bindings/core/v8/ScriptValue.h"
#include "bindings/core/v8/V8Binding.h"
-#include "bindings/modules/v8/V8Response.h"
-#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
-#include "core/inspector/ConsoleMessage.h"
-#include "core/streams/Stream.h"
-#include "modules/fetch/BodyStreamBuffer.h"
-#include "modules/fetch/BytesConsumer.h"
-#include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h"
-#include "platform/RuntimeEnabledFeatures.h"
+#include "modules/serviceworkers/WaitUntilObserver.h"
#include "public/platform/modules/serviceworker/WebServiceWorkerResponse.h"
-#include "v8/include/v8.h"
-#include "wtf/Assertions.h"
-#include "wtf/RefPtr.h"
namespace blink {
-namespace {
-
-// Returns the error message to let the developer know about the reason of the
-// unusual failures.
-const String getMessageForResponseError(WebServiceWorkerResponseError error,
- const KURL& requestURL) {
- String errorMessage = "The FetchEvent for \"" + requestURL.getString() +
- "\" resulted in a network error response: ";
- switch (error) {
- case WebServiceWorkerResponseErrorPromiseRejected:
- errorMessage = errorMessage + "the promise was rejected.";
- break;
- case WebServiceWorkerResponseErrorDefaultPrevented:
- errorMessage =
- errorMessage +
- "preventDefault() was called without calling respondWith().";
- break;
- case WebServiceWorkerResponseErrorNoV8Instance:
- errorMessage =
- errorMessage +
- "an object that was not a Response was passed to respondWith().";
- break;
- case WebServiceWorkerResponseErrorResponseTypeError:
- errorMessage = errorMessage +
- "the promise was resolved with an error response object.";
- break;
- case WebServiceWorkerResponseErrorResponseTypeOpaque:
- errorMessage = errorMessage +
- "an \"opaque\" response was used for a request whose type "
- "is not no-cors";
- break;
- case WebServiceWorkerResponseErrorResponseTypeNotBasicOrDefault:
- ASSERT_NOT_REACHED();
- break;
- case WebServiceWorkerResponseErrorBodyUsed:
- errorMessage = errorMessage +
- "a Response whose \"bodyUsed\" is \"true\" cannot be used "
- "to respond to a request.";
- break;
- case WebServiceWorkerResponseErrorResponseTypeOpaqueForClientRequest:
- errorMessage = errorMessage +
- "an \"opaque\" response was used for a client request.";
- break;
- case WebServiceWorkerResponseErrorResponseTypeOpaqueRedirect:
- errorMessage = errorMessage +
- "an \"opaqueredirect\" type response was used for a "
- "request whose redirect mode is not \"manual\".";
- break;
- case WebServiceWorkerResponseErrorBodyLocked:
- errorMessage = errorMessage +
- "a Response whose \"body\" is locked cannot be used to "
- "respond to a request.";
- break;
- case WebServiceWorkerResponseErrorNoForeignFetchResponse:
- errorMessage = errorMessage +
- "an object that was not a ForeignFetchResponse was passed "
- "to respondWith().";
- break;
- case WebServiceWorkerResponseErrorForeignFetchHeadersWithoutOrigin:
- errorMessage =
- errorMessage +
- "headers were specified for a response without an explicit origin.";
- break;
- case WebServiceWorkerResponseErrorForeignFetchMismatchedOrigin:
- errorMessage =
- errorMessage + "origin in response does not match origin of request.";
- break;
- case WebServiceWorkerResponseErrorRedirectedResponseForNotFollowRequest:
- errorMessage = errorMessage +
- "a redirected response was used for a request whose "
- "redirect mode is not \"follow\".";
- break;
- case WebServiceWorkerResponseErrorUnknown:
- default:
- errorMessage = errorMessage + "an unexpected error occurred.";
- break;
- }
- return errorMessage;
-}
-
-const String getErrorMessageForRedirectedResponseForNavigationRequest(
- const KURL& requestURL,
- const Vector<KURL>& responseURLList) {
- String errorMessage =
- "In Chrome 59, the navigation to \"" + requestURL.getString() + "\" " +
- "will result in a network error, because FetchEvent.respondWith() was " +
- "called with a redirected response. See https://crbug.com/658249. The " +
- "url list of the response was: [\"" + responseURLList[0].getString() +
- "\"";
- for (size_t i = 1; i < responseURLList.size(); ++i) {
- errorMessage =
- errorMessage + ", \"" + responseURLList[i].getString() + "\"";
- }
- return errorMessage + "]";
-}
-
-bool isNavigationRequest(WebURLRequest::FrameType frameType) {
- return frameType != WebURLRequest::FrameTypeNone;
-}
-
-bool isClientRequest(WebURLRequest::FrameType frameType,
- WebURLRequest::RequestContext requestContext) {
- return isNavigationRequest(frameType) ||
- requestContext == WebURLRequest::RequestContextSharedWorker ||
- requestContext == WebURLRequest::RequestContextWorker;
-}
-
-class NoopLoaderClient final
- : public GarbageCollectedFinalized<NoopLoaderClient>,
- public FetchDataLoader::Client {
- WTF_MAKE_NONCOPYABLE(NoopLoaderClient);
- USING_GARBAGE_COLLECTED_MIXIN(NoopLoaderClient);
-
- public:
- NoopLoaderClient() = default;
- void didFetchDataLoadedStream() override {}
- void didFetchDataLoadFailed() override {}
- DEFINE_INLINE_TRACE() { FetchDataLoader::Client::trace(visitor); }
-};
-
-} // namespace
class RespondWithObserver::ThenFunction final : public ScriptFunction {
public:
@@ -191,22 +62,6 @@ class RespondWithObserver::ThenFunction final : public ScriptFunction {
ResolveType m_resolveType;
};
-RespondWithObserver::~RespondWithObserver() {}
-
-RespondWithObserver* RespondWithObserver::create(
- ExecutionContext* context,
- int fetchEventID,
- const KURL& requestURL,
- WebURLRequest::FetchRequestMode requestMode,
- WebURLRequest::FetchRedirectMode redirectMode,
- WebURLRequest::FrameType frameType,
- WebURLRequest::RequestContext requestContext,
- WaitUntilObserver* observer) {
- return new RespondWithObserver(context, fetchEventID, requestURL, requestMode,
- redirectMode, frameType, requestContext,
- observer);
-}
-
void RespondWithObserver::contextDestroyed(ExecutionContext*) {
if (m_observer) {
DCHECK_EQ(Pending, m_state);
@@ -230,8 +85,7 @@ void RespondWithObserver::didDispatchEvent(DispatchEventResult dispatchResult) {
return;
}
- ServiceWorkerGlobalScopeClient::from(getExecutionContext())
- ->respondToFetchEvent(m_fetchEventID, m_eventDispatchTime);
+ onNoResponse();
m_state = Done;
m_observer.clear();
}
@@ -241,7 +95,7 @@ void RespondWithObserver::respondWith(ScriptState* scriptState,
ExceptionState& exceptionState) {
if (m_state != Initial) {
exceptionState.throwDOMException(
- InvalidStateError, "The fetch event has already been responded to.");
+ InvalidStateError, "The event has already been responded to.");
return;
}
@@ -254,126 +108,24 @@ void RespondWithObserver::respondWith(ScriptState* scriptState,
void RespondWithObserver::responseWasRejected(
WebServiceWorkerResponseError error) {
- ASSERT(getExecutionContext());
- getExecutionContext()->addConsoleMessage(
- ConsoleMessage::create(JSMessageSource, WarningMessageLevel,
- getMessageForResponseError(error, m_requestURL)));
-
- // The default value of WebServiceWorkerResponse's status is 0, which maps
- // to a network error.
- WebServiceWorkerResponse webResponse;
- webResponse.setError(error);
- ServiceWorkerGlobalScopeClient::from(getExecutionContext())
- ->respondToFetchEvent(m_fetchEventID, webResponse, m_eventDispatchTime);
+ onResponseRejected(error);
m_state = Done;
m_observer->decrementPendingActivity();
m_observer.clear();
}
void RespondWithObserver::responseWasFulfilled(const ScriptValue& value) {
- ASSERT(getExecutionContext());
- if (!V8Response::hasInstance(value.v8Value(),
- toIsolate(getExecutionContext()))) {
- responseWasRejected(WebServiceWorkerResponseErrorNoV8Instance);
- return;
- }
- Response* response = V8Response::toImplWithTypeCheck(
- toIsolate(getExecutionContext()), value.v8Value());
- // "If one of the following conditions is true, return a network error:
- // - |response|'s type is |error|.
- // - |request|'s mode is not |no-cors| and response's type is |opaque|.
- // - |request| is a client request and |response|'s type is neither
- // |basic| nor |default|."
- const FetchResponseData::Type responseType = response->response()->getType();
- if (responseType == FetchResponseData::ErrorType) {
- responseWasRejected(WebServiceWorkerResponseErrorResponseTypeError);
- return;
- }
- if (responseType == FetchResponseData::OpaqueType) {
- if (m_requestMode != WebURLRequest::FetchRequestModeNoCORS) {
- responseWasRejected(WebServiceWorkerResponseErrorResponseTypeOpaque);
- return;
- }
-
- // The request mode of client requests should be "same-origin" but it is
- // not explicitly stated in the spec yet. So we need to check here.
- // FIXME: Set the request mode of client requests to "same-origin" and
- // remove this check when the spec will be updated.
- // Spec issue: https://github.com/whatwg/fetch/issues/101
- if (isClientRequest(m_frameType, m_requestContext)) {
- responseWasRejected(
- WebServiceWorkerResponseErrorResponseTypeOpaqueForClientRequest);
- return;
- }
- }
- if (m_redirectMode != WebURLRequest::FetchRedirectModeManual &&
- responseType == FetchResponseData::OpaqueRedirectType) {
- responseWasRejected(
- WebServiceWorkerResponseErrorResponseTypeOpaqueRedirect);
- return;
- }
- if (m_redirectMode != WebURLRequest::FetchRedirectModeFollow &&
- response->redirected()) {
- if (!isNavigationRequest(m_frameType)) {
- responseWasRejected(
- WebServiceWorkerResponseErrorRedirectedResponseForNotFollowRequest);
- return;
- }
- // TODO(horo): We should just reject even if the request was a navigation.
- // Currently we measure the impact of the restriction with the use counter
- // in DocumentLoader.
- getExecutionContext()->addConsoleMessage(ConsoleMessage::create(
- JSMessageSource, ErrorMessageLevel,
- getErrorMessageForRedirectedResponseForNavigationRequest(
- m_requestURL, response->internalURLList())));
- }
- if (response->isBodyLocked()) {
- responseWasRejected(WebServiceWorkerResponseErrorBodyLocked);
- return;
- }
- if (response->bodyUsed()) {
- responseWasRejected(WebServiceWorkerResponseErrorBodyUsed);
- return;
- }
-
- WebServiceWorkerResponse webResponse;
- response->populateWebServiceWorkerResponse(webResponse);
- BodyStreamBuffer* buffer = response->internalBodyBuffer();
- if (buffer) {
- RefPtr<BlobDataHandle> blobDataHandle = buffer->drainAsBlobDataHandle(
- BytesConsumer::BlobSizePolicy::AllowBlobWithInvalidSize);
- if (blobDataHandle) {
- webResponse.setBlobDataHandle(blobDataHandle);
- } else {
- Stream* outStream = Stream::create(getExecutionContext(), "");
- webResponse.setStreamURL(outStream->url());
- buffer->startLoading(FetchDataLoader::createLoaderAsStream(outStream),
- new NoopLoaderClient);
- }
- }
- ServiceWorkerGlobalScopeClient::from(getExecutionContext())
- ->respondToFetchEvent(m_fetchEventID, webResponse, m_eventDispatchTime);
+ onResponseFulfilled(value);
m_state = Done;
m_observer->decrementPendingActivity();
m_observer.clear();
}
-RespondWithObserver::RespondWithObserver(
- ExecutionContext* context,
- int fetchEventID,
- const KURL& requestURL,
- WebURLRequest::FetchRequestMode requestMode,
- WebURLRequest::FetchRedirectMode redirectMode,
- WebURLRequest::FrameType frameType,
- WebURLRequest::RequestContext requestContext,
- WaitUntilObserver* observer)
+RespondWithObserver::RespondWithObserver(ExecutionContext* context,
+ int eventID,
+ WaitUntilObserver* observer)
: ContextLifecycleObserver(context),
- m_fetchEventID(fetchEventID),
- m_requestURL(requestURL),
- m_requestMode(requestMode),
- m_redirectMode(redirectMode),
- m_frameType(frameType),
- m_requestContext(requestContext),
+ m_eventID(eventID),
m_state(Initial),
m_observer(observer) {}

Powered by Google App Engine
This is Rietveld 408576698