void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime)
{
    ASSERT(m_fallbackRequestForServiceWorker.isNull());

    if (!m_actualRequest.isNull()) {
        // FIXME: Timeout should be applied to whole fetch, not for each of
        // preflight and actual request.
        m_timeoutTimer.stop();
        ASSERT(!m_sameOriginRequest);
        ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
        loadActualRequest();
        return;
    }

    ThreadableLoaderClient* client = m_client;
    m_client = 0;
    // Don't clear the resource as the client may need to access the downloaded
    // file which will be released when the resource is destoryed.
    if (m_async) {
        m_timeoutTimer.stop();
        m_requestStartedSeconds = 0.0;
    }
    client->didFinishLoading(identifier, finishTime);
    // |this| may be dead here in async mode.
}
void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceRequest& request)
{
    ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
    ASSERT(m_client);
    ASSERT(!resource());

    // Cross-origin requests are only allowed certain registered schemes.
    // We would catch this when checking response headers later, but there
    // is no reason to send a request, preflighted or not, that's guaranteed
    // to be denied.
    if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) {
        ThreadableLoaderClient* client = m_client;
        clear();
        client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, request.url().string(), "Cross origin requests are only supported for protocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + "."));
        // |this| may be dead here in async mode.
        return;
    }

    // We use isSimpleOrForbiddenRequest() here since |request| may have been
    // modified in the process of loading (not from the user's input). For
    // example, referrer. We need to accept them. For security, we must reject
    // forbidden headers/methods at the point we accept user's input. Not here.
    if ((m_options.preflightPolicy == ConsiderPreflight && FetchUtils::isSimpleOrForbiddenRequest(request.httpMethod(), request.httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight) {
        ResourceRequest crossOriginRequest(request);
        ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions);
        updateRequestForAccessControl(crossOriginRequest, securityOrigin(), effectiveAllowCredentials());
        // We update the credentials mode according to effectiveAllowCredentials() here for backward compatibility. But this is not correct.
        // FIXME: We should set it in the caller of DocumentThreadableLoader.
        crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() == AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRequest::FetchCredentialsModeOmit);
        loadRequest(crossOriginRequest, crossOriginOptions);
    } else {
        m_crossOriginNonSimpleRequest = true;

        ResourceRequest crossOriginRequest(request);
        ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions);
        // Do not set the Origin header for preflight requests.
        updateRequestForAccessControl(crossOriginRequest, 0, effectiveAllowCredentials());
        // We update the credentials mode according to effectiveAllowCredentials() here for backward compatibility. But this is not correct.
        // FIXME: We should set it in the caller of DocumentThreadableLoader.
        crossOriginRequest.setFetchCredentialsMode(effectiveAllowCredentials() == AllowStoredCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRequest::FetchCredentialsModeOmit);
        m_actualRequest = crossOriginRequest;
        m_actualOptions = crossOriginOptions;

        bool shouldForcePreflight = InspectorInstrumentation::shouldForceCORSPreflight(m_document);
        bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSkipPreflight(securityOrigin()->toString(), m_actualRequest.url(), effectiveAllowCredentials(), m_actualRequest.httpMethod(), m_actualRequest.httpHeaderFields());
        if (canSkipPreflight && !shouldForcePreflight) {
            loadActualRequest();
        } else {
            ResourceRequest preflightRequest = createAccessControlPreflightRequest(m_actualRequest, securityOrigin());
            // Create a ResourceLoaderOptions for preflight.
            ResourceLoaderOptions preflightOptions = m_actualOptions;
            preflightOptions.allowCredentials = DoNotAllowStoredCredentials;
            loadRequest(preflightRequest, preflightOptions);
        }
    }
}
Esempio n. 3
0
void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier,
                                                      double finishTime) {
  DCHECK(m_fallbackRequestForServiceWorker.isNull());

  if (!m_actualRequest.isNull()) {
    // FIXME: Timeout should be applied to whole fetch, not for each of
    // preflight and actual request.
    m_timeoutTimer.stop();
    DCHECK(!m_sameOriginRequest);
    DCHECK_EQ(m_options.crossOriginRequestPolicy, UseAccessControl);
    loadActualRequest();
    return;
  }

  ThreadableLoaderClient* client = m_client;
  // Protect the resource in |didFinishLoading| in order not to release the
  // downloaded file.
  Persistent<Resource> protect = resource();
  clear();
  client->didFinishLoading(identifier, finishTime);
}