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) {} |