Chromium Code Reviews| 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..cbf84617033241f524665035b8b68b1747fde043 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: |
| @@ -193,18 +64,10 @@ class RespondWithObserver::ThenFunction final : public ScriptFunction { |
| 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); |
| +RespondWithObserver* RespondWithObserver::create(ExecutionContext* context, |
| + int eventID, |
| + WaitUntilObserver* observer) { |
| + return new RespondWithObserver(context, eventID, observer); |
| } |
| void RespondWithObserver::contextDestroyed(ExecutionContext*) { |
| @@ -230,8 +93,6 @@ void RespondWithObserver::didDispatchEvent(DispatchEventResult dispatchResult) { |
| return; |
| } |
| - ServiceWorkerGlobalScopeClient::from(getExecutionContext()) |
|
shimazu
2017/03/08 01:39:03
Could you add a virtual method to notify no respon
falken
2017/03/09 04:59:00
I like something like this. See also my comment be
zino
2017/03/10 17:57:17
Done.
|
| - ->respondToFetchEvent(m_fetchEventID, m_eventDispatchTime); |
| m_state = Done; |
| m_observer.clear(); |
| } |
| @@ -241,7 +102,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 +115,22 @@ 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); |
| m_state = Done; |
| m_observer->decrementPendingActivity(); |
| m_observer.clear(); |
|
falken
2017/03/09 04:59:00
It seems unfortunate that the subclass has to reme
zino
2017/03/10 17:57:17
Done.
|
| } |
| 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); |
| 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) {} |