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); }
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); }
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); }
Resource* MemoryCacheCorrectnessTestHelper::fetch() { ResourceRequest resourceRequest(KURL(ParsedURLString, kResourceURL)); resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal); FetchRequest fetchRequest(resourceRequest, FetchInitiatorInfo()); return RawResource::fetch(fetchRequest, fetcher()); }
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 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; } }
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); }