Example #1
0
void DocumentThreadableLoader::notifyFinished(Resource* resource) {
  DCHECK(m_client);
  DCHECK_EQ(resource, this->resource());
  DCHECK(m_async);

  m_checker.notifyFinished(resource);

  if (resource->errorOccurred()) {
    handleError(resource->resourceError());
  } else {
    handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime());
  }
}
void DocumentThreadableLoader::notifyFinished(Resource* resource)
{
    ASSERT(m_client);
    ASSERT(resource == this->resource());
    ASSERT(m_async);

    if (resource->errorOccurred()) {
        handleError(resource->resourceError());
        // |this| may be dead here.
    } else {
        handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime());
        // |this| may be dead here.
    }
}
Example #3
0
void DocumentThreadableLoader::loadRequestSync(
    const ResourceRequest& request,
    ResourceLoaderOptions resourceLoaderOptions) {
  FetchRequest fetchRequest(request, m_options.initiator,
                            resourceLoaderOptions);
  if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests)
    fetchRequest.setOriginRestriction(FetchRequest::NoOriginRestriction);
  Resource* resource =
      RawResource::fetchSynchronously(fetchRequest, document().fetcher());
  ResourceResponse response =
      resource ? resource->response() : ResourceResponse();
  unsigned long identifier = resource
                                 ? resource->identifier()
                                 : std::numeric_limits<unsigned long>::max();
  ResourceError error = resource ? resource->resourceError() : ResourceError();

  InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(
      m_document, identifier, m_client);
  ThreadableLoaderClient* client = m_client;

  if (!resource) {
    m_client = nullptr;
    client->didFail(error);
    return;
  }

  const KURL& requestURL = request.url();

  // No exception for file:/// resources, see <rdar://problem/4962298>. Also, if
  // we have an HTTP response, then it wasn't a network error in fact.
  if (!error.isNull() && !requestURL.isLocalFile() &&
      response.httpStatusCode() <= 0) {
    m_client = nullptr;
    client->didFail(error);
    return;
  }

  // FIXME: A synchronous request does not tell us whether a redirect happened
  // or not, so we guess by comparing the request and response URLs. This isn't
  // a perfect test though, since a server can serve a redirect to the same URL
  // that was requested. Also comparing the request and response URLs as strings
  // will fail if the requestURL still has its credentials.
  if (requestURL != response.url() && !isAllowedRedirect(response.url())) {
    m_client = nullptr;
    client->didFailRedirectCheck();
    return;
  }

  handleResponse(identifier, response, nullptr);

  // handleResponse() may detect an error. In such a case (check |m_client| as
  // it gets reset by clear() call), skip the rest.
  //
  // |this| is alive here since loadResourceSynchronously() keeps it alive until
  // the end of the function.
  if (!m_client)
    return;

  RefPtr<const SharedBuffer> data = resource->resourceBuffer();
  if (data)
    handleReceivedData(data->data(), data->size());

  // The client may cancel this loader in handleReceivedData(). In such a case,
  // skip the rest.
  if (!m_client)
    return;

  handleSuccessfulFinish(identifier, 0.0);
}
void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, ResourceLoaderOptions resourceLoaderOptions)
{
    // Any credential should have been removed from the cross-site requests.
    const KURL& requestURL = request.url();
    ASSERT(m_sameOriginRequest || requestURL.user().isEmpty());
    ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty());

    // Update resourceLoaderOptions with enforced values.
    if (m_forceDoNotAllowStoredCredentials)
        resourceLoaderOptions.allowCredentials = DoNotAllowStoredCredentials;
    resourceLoaderOptions.securityOrigin = m_securityOrigin;
    if (m_async) {
        if (!m_actualRequest.isNull())
            resourceLoaderOptions.dataBufferingPolicy = BufferData;

        if (m_options.timeoutMilliseconds > 0)
            m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0, BLINK_FROM_HERE);

        FetchRequest newRequest(request, m_options.initiator, resourceLoaderOptions);
        if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests)
            newRequest.setOriginRestriction(FetchRequest::NoOriginRestriction);
        ASSERT(!resource());
        if (request.requestContext() == WebURLRequest::RequestContextVideo || request.requestContext() == WebURLRequest::RequestContextAudio)
            setResource(RawResource::fetchMedia(newRequest, document().fetcher()));
        else if (request.requestContext() == WebURLRequest::RequestContextManifest)
            setResource(RawResource::fetchManifest(newRequest, document().fetcher()));
        else
            setResource(RawResource::fetch(newRequest, document().fetcher()));
        if (resource() && resource()->loader()) {
            unsigned long identifier = resource()->identifier();
            InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client);
        }
        return;
    }

    FetchRequest fetchRequest(request, m_options.initiator, resourceLoaderOptions);
    if (m_options.crossOriginRequestPolicy == AllowCrossOriginRequests)
        fetchRequest.setOriginRestriction(FetchRequest::NoOriginRestriction);
    ResourcePtr<Resource> resource = RawResource::fetchSynchronously(fetchRequest, document().fetcher());
    ResourceResponse response = resource ? resource->response() : ResourceResponse();
    unsigned long identifier = resource ? resource->identifier() : std::numeric_limits<unsigned long>::max();
    ResourceError error = resource ? resource->resourceError() : ResourceError();

    InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client);

    if (!resource) {
        m_client->didFail(error);
        return;
    }

    // No exception for file:/// resources, see <rdar://problem/4962298>.
    // Also, if we have an HTTP response, then it wasn't a network error in fact.
    if (!error.isNull() && !requestURL.isLocalFile() && response.httpStatusCode() <= 0) {
        m_client->didFail(error);
        return;
    }

    // FIXME: A synchronous request does not tell us whether a redirect happened or not, so we guess by comparing the
    // request and response URLs. This isn't a perfect test though, since a server can serve a redirect to the same URL that was
    // requested. Also comparing the request and response URLs as strings will fail if the requestURL still has its credentials.
    if (requestURL != response.url() && (!isAllowedByContentSecurityPolicy(response.url(), ContentSecurityPolicy::DidRedirect) || !isAllowedRedirect(response.url()))) {
        m_client->didFailRedirectCheck();
        return;
    }

    handleResponse(identifier, response, nullptr);

    // handleResponse() may detect an error. In such a case (check |m_client|
    // as it gets reset by clear() call), skip the rest.
    //
    // |this| is alive here since loadResourceSynchronously() keeps it alive
    // until the end of the function.
    if (!m_client)
        return;

    SharedBuffer* data = resource->resourceBuffer();
    if (data)
        handleReceivedData(data->data(), data->size());

    // The client may cancel this loader in handleReceivedData(). In such a
    // case, skip the rest.
    if (!m_client)
        return;

    handleSuccessfulFinish(identifier, 0.0);
}