
This reverts commit8bd07a6cf9
. Reason for revert: This revert was incorrect and breaks the build. Original change's description: > Revert "Move base/test/bind_test_util.h to base/test/bind.h" > > This reverts commita4493a6f80
. > > Reason for revert: This CL breaks internal builds (e.g. /chrome/browser/media/kaleidoscope/internal/kaleidoscope_browsertest.cc). > > Original change's description: > > Move base/test/bind_test_util.h to base/test/bind.h > > > > Stop relying on us to remember arcane file names when writing tests, > > and repeating the directory hierarchy into the file name. > > > > R=dcheng@chromium.org > > TBR= > > NOPRESUBMIT=true > > > > Change-Id: I49c951162939c7dcef44883bee740f94b2f49e09 > > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2523099 > > Commit-Queue: danakj <danakj@chromium.org> > > Reviewed-by: Daniel Cheng <dcheng@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#825145} > > TBR=danakj@chromium.org,dcheng@chromium.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Change-Id: If165b8443662baa564895e994ea0d772348e6da6 > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2526102 > Reviewed-by: Denis Kuznetsov [CET] <antrim@chromium.org> > Commit-Queue: Denis Kuznetsov [CET] <antrim@chromium.org> > Cr-Commit-Position: refs/heads/master@{#825328} TBR=danakj@chromium.org,dcheng@chromium.org,antrim@chromium.org # Not skipping CQ checks because this is a reland. NOPRESUBMIT=true NOTREECHECK=true No-Try: True Change-Id: I6a8c0c8bbb1c8f87cc7f2df7a8b3388971292975 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2526683 Commit-Queue: Guido Urdaneta <guidou@chromium.org> Reviewed-by: Guido Urdaneta <guidou@chromium.org> Cr-Commit-Position: refs/heads/master@{#825329}
329 lines
13 KiB
C++
329 lines
13 KiB
C++
// Copyright 2017 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "content/browser/storage_partition_impl.h"
|
|
|
|
#include <string>
|
|
|
|
#include "base/test/bind.h"
|
|
#include "build/build_config.h"
|
|
#include "content/public/browser/browser_context.h"
|
|
#include "content/public/browser/client_certificate_delegate.h"
|
|
#include "content/public/browser/navigation_controller.h"
|
|
#include "content/public/browser/web_contents.h"
|
|
#include "content/public/common/content_client.h"
|
|
#include "content/public/test/browser_test.h"
|
|
#include "content/public/test/content_browser_test.h"
|
|
#include "content/public/test/simple_url_loader_test_helper.h"
|
|
#include "content/public/test/url_loader_interceptor.h"
|
|
#include "content/shell/browser/shell.h"
|
|
#include "content/shell/browser/shell_browser_context.h"
|
|
#include "content/test/io_thread_shared_url_loader_factory_owner.h"
|
|
#include "net/http/http_response_headers.h"
|
|
#include "net/http/http_status_code.h"
|
|
#include "net/ssl/client_cert_identity.h"
|
|
#include "net/test/embedded_test_server/embedded_test_server.h"
|
|
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
|
|
#include "services/network/public/cpp/simple_url_loader.h"
|
|
#include "services/network/public/mojom/network_service.mojom.h"
|
|
#include "services/network/public/mojom/url_loader.mojom.h"
|
|
#include "services/network/public/mojom/url_loader_factory.mojom.h"
|
|
#include "services/network/public/mojom/url_response_head.mojom.h"
|
|
#include "services/network/test/test_url_loader_client.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "url/gurl.h"
|
|
|
|
namespace content {
|
|
|
|
namespace {
|
|
|
|
class StoragePartitionImplBrowsertest : public ContentBrowserTest {
|
|
public:
|
|
StoragePartitionImplBrowsertest() = default;
|
|
~StoragePartitionImplBrowsertest() override = default;
|
|
|
|
GURL GetTestURL() const {
|
|
// Use '/echoheader' instead of '/echo' to avoid a disk_cache bug.
|
|
// See https://crbug.com/792255.
|
|
return embedded_test_server()->GetURL("/echoheader");
|
|
}
|
|
|
|
private:
|
|
};
|
|
|
|
class ClientCertBrowserClient : public ContentBrowserClient {
|
|
public:
|
|
explicit ClientCertBrowserClient(
|
|
base::OnceClosure select_certificate_callback,
|
|
base::OnceClosure delete_delegate_callback)
|
|
: select_certificate_callback_(std::move(select_certificate_callback)),
|
|
delete_delegate_callback_(std::move(delete_delegate_callback)) {}
|
|
|
|
~ClientCertBrowserClient() override = default;
|
|
|
|
// Returns a cancellation callback for the imaginary client certificate
|
|
// dialog. The callback simulates Android's cancellation callback by deleting
|
|
// |delegate|.
|
|
base::OnceClosure SelectClientCertificate(
|
|
WebContents* web_contents,
|
|
net::SSLCertRequestInfo* cert_request_info,
|
|
net::ClientCertIdentityList client_certs,
|
|
std::unique_ptr<ClientCertificateDelegate> delegate) override {
|
|
std::move(select_certificate_callback_).Run(); // Unblock the test.
|
|
return base::BindOnce(&ClientCertBrowserClient::DeleteDelegateOnCancel,
|
|
base::Unretained(this), std::move(delegate));
|
|
}
|
|
|
|
void DeleteDelegateOnCancel(
|
|
std::unique_ptr<ClientCertificateDelegate> delegate) {
|
|
std::move(delete_delegate_callback_).Run();
|
|
}
|
|
|
|
private:
|
|
scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
|
base::OnceClosure select_certificate_callback_;
|
|
base::OnceClosure delete_delegate_callback_;
|
|
DISALLOW_COPY_AND_ASSIGN(ClientCertBrowserClient);
|
|
};
|
|
|
|
class ClientCertBrowserTest : public ContentBrowserTest {
|
|
public:
|
|
ClientCertBrowserTest()
|
|
: https_test_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
|
|
// Configure test server to request client certificates.
|
|
net::SSLServerConfig ssl_server_config;
|
|
ssl_server_config.client_cert_type =
|
|
net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
|
|
https_test_server_.SetSSLConfig(
|
|
net::EmbeddedTestServer::CERT_COMMON_NAME_IS_DOMAIN, ssl_server_config);
|
|
https_test_server_.ServeFilesFromSourceDirectory(GetTestDataFilePath());
|
|
}
|
|
|
|
~ClientCertBrowserTest() override = default;
|
|
|
|
protected:
|
|
void SetUpOnMainThread() override {
|
|
ContentBrowserTest::SetUpOnMainThread();
|
|
|
|
select_certificate_run_loop_ = std::make_unique<base::RunLoop>();
|
|
delete_delegate_run_loop_ = std::make_unique<base::RunLoop>();
|
|
|
|
client_ = std::make_unique<ClientCertBrowserClient>(
|
|
select_certificate_run_loop_->QuitClosure(),
|
|
delete_delegate_run_loop_->QuitClosure());
|
|
|
|
content::SetBrowserClientForTesting(client_.get());
|
|
}
|
|
|
|
net::EmbeddedTestServer https_test_server_;
|
|
std::unique_ptr<ClientCertBrowserClient> client_;
|
|
std::unique_ptr<base::RunLoop> select_certificate_run_loop_;
|
|
std::unique_ptr<base::RunLoop> delete_delegate_run_loop_;
|
|
};
|
|
|
|
// Creates a SimpleURLLoader and starts it to download |url|. Blocks until the
|
|
// load is complete.
|
|
std::unique_ptr<network::SimpleURLLoader> DownloadUrl(
|
|
const GURL& url,
|
|
StoragePartition* partition) {
|
|
auto request = std::make_unique<network::ResourceRequest>();
|
|
request->url = url;
|
|
std::unique_ptr<network::SimpleURLLoader> url_loader =
|
|
network::SimpleURLLoader::Create(std::move(request),
|
|
TRAFFIC_ANNOTATION_FOR_TESTS);
|
|
SimpleURLLoaderTestHelper url_loader_helper;
|
|
url_loader->DownloadToString(
|
|
partition->GetURLLoaderFactoryForBrowserProcess().get(),
|
|
url_loader_helper.GetCallback(),
|
|
/*max_body_size=*/1024 * 1024);
|
|
url_loader_helper.WaitForCallback();
|
|
return url_loader;
|
|
}
|
|
|
|
void CheckSimpleURLLoaderState(network::SimpleURLLoader* url_loader,
|
|
int net_error,
|
|
net::HttpStatusCode http_status_code) {
|
|
EXPECT_EQ(net_error, url_loader->NetError());
|
|
if (net_error != net::OK)
|
|
return;
|
|
ASSERT_TRUE(url_loader->ResponseInfo());
|
|
ASSERT_TRUE(url_loader->ResponseInfo()->headers);
|
|
EXPECT_EQ(http_status_code,
|
|
url_loader->ResponseInfo()->headers->response_code());
|
|
}
|
|
|
|
} // namespace
|
|
|
|
// Make sure that the NetworkContext returned by a StoragePartition works, both
|
|
// with the network service enabled and with it disabled, when one is created
|
|
// that wraps the URLRequestContext created by the BrowserContext.
|
|
IN_PROC_BROWSER_TEST_F(StoragePartitionImplBrowsertest, NetworkContext) {
|
|
ASSERT_TRUE(embedded_test_server()->Start());
|
|
|
|
network::mojom::URLLoaderFactoryParamsPtr params =
|
|
network::mojom::URLLoaderFactoryParams::New();
|
|
params->process_id = network::mojom::kBrowserProcessId;
|
|
params->automatically_assign_isolation_info = true;
|
|
params->is_corb_enabled = false;
|
|
mojo::Remote<network::mojom::URLLoaderFactory> loader_factory;
|
|
BrowserContext::GetDefaultStoragePartition(
|
|
shell()->web_contents()->GetBrowserContext())
|
|
->GetNetworkContext()
|
|
->CreateURLLoaderFactory(loader_factory.BindNewPipeAndPassReceiver(),
|
|
std::move(params));
|
|
|
|
network::ResourceRequest request;
|
|
network::TestURLLoaderClient client;
|
|
request.url = embedded_test_server()->GetURL("/set-header?foo: bar");
|
|
request.method = "GET";
|
|
mojo::PendingRemote<network::mojom::URLLoader> loader;
|
|
loader_factory->CreateLoaderAndStart(
|
|
loader.InitWithNewPipeAndPassReceiver(), 2, 1,
|
|
network::mojom::kURLLoadOptionNone, request, client.CreateRemote(),
|
|
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
|
|
|
|
// Just wait until headers are received - if the right headers are received,
|
|
// no need to read the body.
|
|
client.RunUntilResponseBodyArrived();
|
|
ASSERT_TRUE(client.response_head()->headers);
|
|
EXPECT_EQ(200, client.response_head()->headers->response_code());
|
|
|
|
std::string foo_header_value;
|
|
ASSERT_TRUE(client.response_head()->headers->GetNormalizedHeader(
|
|
"foo", &foo_header_value));
|
|
EXPECT_EQ("bar", foo_header_value);
|
|
}
|
|
|
|
// Make sure the factory info returned from
|
|
// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| works.
|
|
IN_PROC_BROWSER_TEST_F(StoragePartitionImplBrowsertest,
|
|
GetURLLoaderFactoryForBrowserProcessIOThread) {
|
|
ASSERT_TRUE(embedded_test_server()->Start());
|
|
|
|
base::ScopedAllowBlockingForTesting allow_blocking;
|
|
auto pending_shared_url_loader_factory =
|
|
BrowserContext::GetDefaultStoragePartition(
|
|
shell()->web_contents()->GetBrowserContext())
|
|
->GetURLLoaderFactoryForBrowserProcessIOThread();
|
|
|
|
auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
|
|
std::move(pending_shared_url_loader_factory));
|
|
|
|
EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
|
|
}
|
|
|
|
// Make sure the factory info returned from
|
|
// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| doesn't
|
|
// crash if it's called after the StoragePartition is deleted.
|
|
IN_PROC_BROWSER_TEST_F(StoragePartitionImplBrowsertest,
|
|
BrowserIOPendingFactoryAfterStoragePartitionGone) {
|
|
ASSERT_TRUE(embedded_test_server()->Start());
|
|
|
|
base::ScopedAllowBlockingForTesting allow_blocking;
|
|
std::unique_ptr<ShellBrowserContext> browser_context =
|
|
std::make_unique<ShellBrowserContext>(true);
|
|
auto* partition =
|
|
BrowserContext::GetDefaultStoragePartition(browser_context.get());
|
|
auto pending_shared_url_loader_factory =
|
|
partition->GetURLLoaderFactoryForBrowserProcessIOThread();
|
|
|
|
browser_context.reset();
|
|
|
|
auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
|
|
std::move(pending_shared_url_loader_factory));
|
|
|
|
EXPECT_EQ(net::ERR_FAILED,
|
|
factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
|
|
}
|
|
|
|
// Make sure the factory constructed from
|
|
// |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| doesn't
|
|
// crash if it's called after the StoragePartition is deleted.
|
|
IN_PROC_BROWSER_TEST_F(StoragePartitionImplBrowsertest,
|
|
BrowserIOFactoryAfterStoragePartitionGone) {
|
|
ASSERT_TRUE(embedded_test_server()->Start());
|
|
|
|
base::ScopedAllowBlockingForTesting allow_blocking;
|
|
std::unique_ptr<ShellBrowserContext> browser_context =
|
|
std::make_unique<ShellBrowserContext>(true);
|
|
auto* partition =
|
|
BrowserContext::GetDefaultStoragePartition(browser_context.get());
|
|
auto factory_owner = IOThreadSharedURLLoaderFactoryOwner::Create(
|
|
partition->GetURLLoaderFactoryForBrowserProcessIOThread());
|
|
|
|
EXPECT_EQ(net::OK, factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
|
|
|
|
browser_context.reset();
|
|
|
|
EXPECT_EQ(net::ERR_FAILED,
|
|
factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
|
|
}
|
|
|
|
// Checks that the network::URLLoaderIntercpetor works as expected with the
|
|
// SharedURLLoaderFactory returned by StoragePartitionImpl.
|
|
IN_PROC_BROWSER_TEST_F(StoragePartitionImplBrowsertest, URLLoaderInterceptor) {
|
|
ASSERT_TRUE(embedded_test_server()->Start());
|
|
const GURL kEchoUrl(embedded_test_server()->GetURL("/echo"));
|
|
|
|
base::ScopedAllowBlockingForTesting allow_blocking;
|
|
std::unique_ptr<ShellBrowserContext> browser_context =
|
|
std::make_unique<ShellBrowserContext>(true);
|
|
auto* partition =
|
|
BrowserContext::GetDefaultStoragePartition(browser_context.get());
|
|
|
|
// Run a request the first time without the interceptor set, as the
|
|
// StoragePartitionImpl lazily creates the factory and we want to make sure
|
|
// it will create a new one once the interceptor is set (and not simply reuse
|
|
// the cached one).
|
|
{
|
|
std::unique_ptr<network::SimpleURLLoader> url_loader =
|
|
DownloadUrl(kEchoUrl, partition);
|
|
CheckSimpleURLLoaderState(url_loader.get(), net::OK, net::HTTP_OK);
|
|
}
|
|
|
|
// Use a URLLoaderInterceptor to simulate an error.
|
|
{
|
|
URLLoaderInterceptor interceptor(base::BindLambdaForTesting(
|
|
[&](URLLoaderInterceptor::RequestParams* params) -> bool {
|
|
if (params->url_request.url != kEchoUrl)
|
|
return false;
|
|
params->client->OnComplete(
|
|
network::URLLoaderCompletionStatus(net::ERR_NOT_IMPLEMENTED));
|
|
return true;
|
|
}));
|
|
std::unique_ptr<network::SimpleURLLoader> url_loader =
|
|
DownloadUrl(kEchoUrl, partition);
|
|
CheckSimpleURLLoaderState(url_loader.get(), net::ERR_NOT_IMPLEMENTED,
|
|
net::HTTP_OK);
|
|
}
|
|
|
|
// Run one more time without the interceptor, we should be back to the
|
|
// original behavior.
|
|
{
|
|
std::unique_ptr<network::SimpleURLLoader> url_loader =
|
|
DownloadUrl(kEchoUrl, partition);
|
|
CheckSimpleURLLoaderState(url_loader.get(), net::OK, net::HTTP_OK);
|
|
}
|
|
}
|
|
|
|
IN_PROC_BROWSER_TEST_F(ClientCertBrowserTest,
|
|
InvokeClientCertCancellationCallback) {
|
|
ASSERT_TRUE(https_test_server_.Start());
|
|
|
|
// Navigate to "/echo". We expect this to get blocked on the client cert.
|
|
shell()->LoadURL(https_test_server_.GetURL("/echo"));
|
|
|
|
// Wait for SelectClientCertificate() to be invoked.
|
|
select_certificate_run_loop_->Run();
|
|
|
|
// Navigate away to cancel the original request, triggering the cancellation
|
|
// callback that was returned by SelectClientCertificate.
|
|
shell()->LoadURL(GURL("about:blank"));
|
|
|
|
// Wait for DeleteDelegateOnCancel() to be invoked.
|
|
delete_delegate_run_loop_->Run();
|
|
}
|
|
|
|
} // namespace content
|