Beispiel #1
0
void ForeignFetchRespondWithObserver::responseWasFulfilled(
    const ScriptValue& value) {
  ASSERT(getExecutionContext());
  ExceptionState exceptionState(value.isolate(), ExceptionState::UnknownContext,
                                "ForeignFetchEvent", "respondWith");
  ForeignFetchResponse foreignFetchResponse =
      ScriptValue::to<ForeignFetchResponse>(toIsolate(getExecutionContext()),
                                            value, exceptionState);
  if (exceptionState.hadException()) {
    exceptionState.clearException();
    responseWasRejected(WebServiceWorkerResponseErrorNoForeignFetchResponse);
    return;
  }

  Response* response = foreignFetchResponse.response();
  const FetchResponseData* internalResponse = response->response();
  const bool isOpaque =
      internalResponse->getType() == FetchResponseData::OpaqueType ||
      internalResponse->getType() == FetchResponseData::OpaqueRedirectType;
  if (internalResponse->getType() != FetchResponseData::DefaultType)
    internalResponse = internalResponse->internalResponse();

  if (!foreignFetchResponse.hasOrigin()) {
    if (foreignFetchResponse.hasHeaders() &&
        !foreignFetchResponse.headers().isEmpty()) {
      responseWasRejected(
          WebServiceWorkerResponseErrorForeignFetchHeadersWithoutOrigin);
      return;
    }

    // If response isn't already opaque, make it opaque.
    if (!isOpaque) {
      FetchResponseData* opaqueData =
          internalResponse->createOpaqueFilteredResponse();
      response = Response::create(getExecutionContext(), opaqueData);
    }
  } else if (m_requestOrigin->toString() != foreignFetchResponse.origin()) {
    responseWasRejected(
        WebServiceWorkerResponseErrorForeignFetchMismatchedOrigin);
    return;
  } else if (!isOpaque) {
    HTTPHeaderSet headers;
    if (foreignFetchResponse.hasHeaders()) {
      for (const String& header : foreignFetchResponse.headers())
        headers.add(header);
      if (response->response()->getType() == FetchResponseData::CORSType) {
        const HTTPHeaderSet& existingHeaders =
            response->response()->corsExposedHeaderNames();
        HTTPHeaderSet headersToRemove;
        for (HTTPHeaderSet::iterator it = headers.begin(); it != headers.end();
             ++it) {
          if (!existingHeaders.contains(*it))
            headersToRemove.add(*it);
        }
        headers.removeAll(headersToRemove);
      }
    }
    FetchResponseData* responseData =
        internalResponse->createCORSFilteredResponse(headers);
    response = Response::create(getExecutionContext(), responseData);
  }

  RespondWithObserver::responseWasFulfilled(
      ScriptValue::from(value.getScriptState(), response));
}