void DocumentLoader::startLoadingMainResource()
{
    timing().markNavigationStart();
    ASSERT(!m_mainResource);
    ASSERT(m_state == NotStarted);
    m_state = Provisional;

    if (maybeLoadEmpty())
        return;

    ASSERT(timing().navigationStart());
    ASSERT(!timing().fetchStart());
    timing().markFetchStart();

    DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions,
        (DoNotBufferData, AllowStoredCredentials, ClientRequestedCredentials, CheckContentSecurityPolicy, DocumentContext));
    FetchRequest fetchRequest(m_request, FetchInitiatorTypeNames::document, mainResourceLoadOptions);
    m_mainResource = RawResource::fetchMainResource(fetchRequest, fetcher(), m_substituteData);
    if (!m_mainResource) {
        m_request = ResourceRequest(blankURL());
        maybeLoadEmpty();
        return;
    }
    // A bunch of headers are set when the underlying ResourceLoader is created, and m_request needs to include those.
    // Even when using a cached resource, we may make some modification to the request, e.g. adding the referer header.
    m_request = mainResourceLoader() ? m_mainResource->resourceRequest() : fetchRequest.resourceRequest();
    m_mainResource->addClient(this);
}
Example #2
0
TEST_F(ResourceFetcherTest, SynchronousRequest) {
    KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.png");
    URLTestHelpers::registerMockedURLLoad(url, testImageFilename, "image/png");

    ResourceFetcher* fetcher =
        ResourceFetcher::create(ResourceFetcherTestMockFetchContext::create());
    ResourceRequest resourceRequest(url);
    resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal);
    FetchRequest fetchRequest(resourceRequest, FetchInitiatorInfo());
    fetchRequest.makeSynchronous();
    Resource* resource = RawResource::fetch(fetchRequest, fetcher);
    EXPECT_TRUE(resource->isLoaded());
    EXPECT_EQ(ResourceLoadPriorityHighest,
              resource->resourceRequest().priority());

    Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
    memoryCache()->remove(resource);
}
Example #3
0
void DocumentLoader::startLoadingMainResource() {
  timing().markNavigationStart();
  DCHECK(!m_mainResource);
  DCHECK_EQ(m_state, NotStarted);
  m_state = Provisional;

  if (maybeLoadEmpty())
    return;

  DCHECK(timing().navigationStart());

  // PlzNavigate:
  // The fetch has already started in the browser. Don't mark it again.
  if (!m_frame->settings()->browserSideNavigationEnabled()) {
    DCHECK(!timing().fetchStart());
    timing().markFetchStart();
  }

  DEFINE_STATIC_LOCAL(
      ResourceLoaderOptions, mainResourceLoadOptions,
      (DoNotBufferData, AllowStoredCredentials, ClientRequestedCredentials,
       CheckContentSecurityPolicy, DocumentContext));
  FetchRequest fetchRequest(m_request, FetchInitiatorTypeNames::document,
                            mainResourceLoadOptions);
  m_mainResource =
      RawResource::fetchMainResource(fetchRequest, fetcher(), m_substituteData);

  // PlzNavigate:
  // The final access checks are still performed here, potentially rejecting
  // the "provisional" load, but the browser side already expects the renderer
  // to be able to unconditionally commit.
  if (!m_mainResource || (m_frame->settings()->browserSideNavigationEnabled() &&
                          m_mainResource->errorOccurred())) {
    m_request = ResourceRequest(blankURL());
    maybeLoadEmpty();
    return;
  }
  // A bunch of headers are set when the underlying resource load begins, and
  // m_request needs to include those. Even when using a cached resource, we may
  // make some modification to the request, e.g. adding the referer header.
  m_request = m_mainResource->isLoading() ? m_mainResource->resourceRequest()
                                          : fetchRequest.resourceRequest();
  m_mainResource->addClient(this);
}
Example #4
0
Resource* MemoryCacheCorrectnessTestHelper::fetch() {
  ResourceRequest resourceRequest(KURL(ParsedURLString, kResourceURL));
  resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal);
  FetchRequest fetchRequest(resourceRequest, FetchInitiatorInfo());
  return RawResource::fetch(fetchRequest, fetcher());
}
Example #5
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);
}
Example #6
0
void PaymentServer::handleURIOrFile(const QString& s)
{
    if (saveURIs)
    {
        savedPaymentRequests.append(s);
        return;
    }

    if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI
    {
#if QT_VERSION < 0x050000
        QUrl uri(s);
#else
        QUrlQuery uri((QUrl(s)));
#endif
        if (uri.hasQueryItem("r")) // payment request URI
        {
            QByteArray temp;
            temp.append(uri.queryItemValue("r"));
            QString decoded = QUrl::fromPercentEncoding(temp);
            QUrl fetchUrl(decoded, QUrl::StrictMode);

            if (fetchUrl.isValid())
            {
                qDebug() << "PaymentServer::handleURIOrFile: fetchRequest(" << fetchUrl << ")";
                fetchRequest(fetchUrl);
            }
            else
            {
                qWarning() << "PaymentServer::handleURIOrFile: Invalid URL: " << fetchUrl;
                Q_EMIT message(tr("URI handling"),
                    tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()),
                    CClientUIInterface::ICON_WARNING);
            }

            return;
        }
        else // normal URI
        {
            SendCoinsRecipient recipient;
            if (GUIUtil::parseBitcoinURI(s, &recipient))
            {
                if (!IsValidDestinationString(recipient.address.toStdString())) {
                    Q_EMIT message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address),
                        CClientUIInterface::MSG_ERROR);
                }
                else
                    Q_EMIT receivedPaymentRequest(recipient);
            }
            else
                Q_EMIT message(tr("URI handling"),
                    tr("URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."),
                    CClientUIInterface::ICON_WARNING);

            return;
        }
    }

    if (QFile::exists(s)) // payment request file
    {
        PaymentRequestPlus request;
        SendCoinsRecipient recipient;
        if (!readPaymentRequestFromFile(s, request))
        {
            Q_EMIT message(tr("Payment request file handling"),
                tr("Payment request file cannot be read! This can be caused by an invalid payment request file."),
                CClientUIInterface::ICON_WARNING);
        }
        else if (processPaymentRequest(request, recipient))
            Q_EMIT receivedPaymentRequest(recipient);

        return;
    }
}
Example #7
0
TEST(ImageResourceTest, ReloadIfLoFiDuringFetch) {
  KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
  ScopedRegisteredURL scopedRegisteredURL(testURL);

  ResourceRequest request(testURL);
  request.setLoFiState(WebURLRequest::LoFiOn);
  FetchRequest fetchRequest(request, FetchInitiatorInfo());
  ResourceFetcher* fetcher =
      ResourceFetcher::create(ImageResourceTestMockFetchContext::create());

  ImageResource* cachedImage = ImageResource::fetch(fetchRequest, fetcher);
  Persistent<MockImageResourceClient> client =
      new MockImageResourceClient(cachedImage);

  // Send the image response.
  Vector<unsigned char> jpeg = jpegImage();

  ResourceResponse initialResourceResponse(testURL, "image/jpeg", jpeg.size(),
                                           nullAtom, String());
  initialResourceResponse.addHTTPHeaderField("chrome-proxy", "q=low");

  cachedImage->loader()->didReceiveResponse(
      nullptr, WrappedResourceResponse(initialResourceResponse));
  cachedImage->loader()->didReceiveData(
      nullptr, reinterpret_cast<const char*>(jpeg.data()), jpeg.size(),
      jpeg.size(), jpeg.size());

  EXPECT_FALSE(cachedImage->errorOccurred());
  ASSERT_TRUE(cachedImage->hasImage());
  EXPECT_FALSE(cachedImage->getImage()->isNull());
  EXPECT_EQ(1, client->imageChangedCount());
  EXPECT_EQ(jpeg.size(), client->encodedSizeOnLastImageChanged());
  EXPECT_FALSE(client->notifyFinishedCalled());
  EXPECT_TRUE(cachedImage->getImage()->isBitmapImage());
  EXPECT_EQ(1, cachedImage->getImage()->width());
  EXPECT_EQ(1, cachedImage->getImage()->height());

  // Call reloadIfLoFi() while the image is still loading.
  cachedImage->reloadIfLoFi(fetcher);
  EXPECT_FALSE(cachedImage->errorOccurred());
  EXPECT_FALSE(cachedImage->resourceBuffer());
  EXPECT_FALSE(cachedImage->hasImage());
  EXPECT_EQ(2, client->imageChangedCount());
  EXPECT_EQ(0U, client->encodedSizeOnLastImageChanged());
  // The client should not have been notified of completion yet, since the image
  // is still loading.
  EXPECT_FALSE(client->notifyFinishedCalled());

  Vector<unsigned char> jpeg2 = jpegImage2();
  cachedImage->loader()->didReceiveResponse(
      nullptr, WrappedResourceResponse(ResourceResponse(
                   testURL, "image/jpeg", jpeg.size(), nullAtom, String())),
      nullptr);
  cachedImage->loader()->didReceiveData(
      nullptr, reinterpret_cast<const char*>(jpeg2.data()), jpeg2.size(),
      jpeg2.size(), jpeg2.size());
  cachedImage->loader()->didFinishLoading(nullptr, 0.0, jpeg2.size());

  EXPECT_FALSE(cachedImage->errorOccurred());
  ASSERT_TRUE(cachedImage->hasImage());
  EXPECT_FALSE(cachedImage->getImage()->isNull());
  EXPECT_EQ(jpeg2.size(), client->encodedSizeOnLastImageChanged());
  // The client should have been notified of completion only after the reload
  // completed.
  EXPECT_TRUE(client->notifyFinishedCalled());
  EXPECT_EQ(jpeg2.size(), client->encodedSizeOnNotifyFinished());
  EXPECT_EQ(jpeg2.size(), client->encodedSizeOnImageNotifyFinished());
  EXPECT_TRUE(cachedImage->getImage()->isBitmapImage());
  EXPECT_EQ(50, cachedImage->getImage()->width());
  EXPECT_EQ(50, cachedImage->getImage()->height());
}
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);
}
void DocumentThreadableLoader::loadRequest(const ResourceRequest& request)
{
    // 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());

    ThreadableLoaderOptions options = m_options;
    if (m_async) {
        if (m_actualRequest) {
            options.sniffContent = DoNotSniffContent;
            options.dataBufferingPolicy = BufferData;
        }

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

        FetchRequest newRequest(request, m_options.initiator, options);
        ASSERT(!resource());
        setResource(m_document->fetcher()->fetchRawResource(newRequest));
        if (resource() && resource()->loader()) {
            unsigned long identifier = resource()->identifier();
            InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client);
        }
        return;
    }

    FetchRequest fetchRequest(request, m_options.initiator, options);
    ResourcePtr<Resource> resource = m_document->fetcher()->fetchSynchronously(fetchRequest);
    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() && (!isAllowedByPolicy(response.url()) || !isAllowedRedirect(response.url()))) {
        m_client->didFailRedirectCheck();
        return;
    }

    didReceiveResponse(identifier, response);

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

    didFinishLoading(identifier, 0.0);
}