summaryrefslogtreecommitdiff
path: root/chromium/net/http/http_network_transaction_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/http/http_network_transaction_unittest.cc')
-rw-r--r--chromium/net/http/http_network_transaction_unittest.cc299
1 files changed, 259 insertions, 40 deletions
diff --git a/chromium/net/http/http_network_transaction_unittest.cc b/chromium/net/http/http_network_transaction_unittest.cc
index 8b56db06267..29a5c811e04 100644
--- a/chromium/net/http/http_network_transaction_unittest.cc
+++ b/chromium/net/http/http_network_transaction_unittest.cc
@@ -52,6 +52,7 @@
#include "net/base/proxy_delegate.h"
#include "net/base/proxy_server.h"
#include "net/base/request_priority.h"
+#include "net/base/schemeful_site.h"
#include "net/base/test_completion_callback.h"
#include "net/base/test_proxy_delegate.h"
#include "net/base/upload_bytes_element_reader.h"
@@ -580,8 +581,8 @@ class HttpNetworkTransactionTest : public PlatformTest,
const CommonConnectJobParams dummy_connect_job_params_;
const net::NetworkIsolationKey kNetworkIsolationKey =
- NetworkIsolationKey(url::Origin::Create(GURL("https://foo.test/")),
- url::Origin::Create(GURL("https://bar.test/")));
+ NetworkIsolationKey(SchemefulSite(GURL("https://foo.test/")),
+ SchemefulSite(GURL("https://bar.test/")));
// These clocks are defined here, even though they're only used in the
// Reporting tests below, since they need to be destroyed after
@@ -776,9 +777,6 @@ bool CheckNTLMProxyAuth(
} // namespace
-// TODO(950069): Add testing for frame_origin in NetworkIsolationKey
-// using kAppendInitiatingFrameOriginToNetworkIsolationKey.
-
TEST_F(HttpNetworkTransactionTest, Basic) {
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
@@ -4408,10 +4406,10 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyMatchesServerAuthNoTunnel) {
// affects server credentials, not proxy credentials.
TEST_F(HttpNetworkTransactionTest,
BasicAuthProxyMatchesServerAuthWithNetworkIsolationKeyNoTunnel) {
- const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
- const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
- const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
- const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
+ const SchemefulSite kSite1(GURL("https://foo.test/"));
+ const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
+ const SchemefulSite kSite2(GURL("https://bar.test/"));
+ const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
// This test would need to use a single socket without this option enabled.
// Best to use this option when it would affect a test, as it will eventually
@@ -4659,10 +4657,10 @@ TEST_F(HttpNetworkTransactionTest,
// Much like the test above, but uses tunnelled connections.
TEST_F(HttpNetworkTransactionTest,
BasicAuthProxyMatchesServerAuthWithNetworkIsolationKeyWithTunnel) {
- const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
- const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
- const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
- const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
+ const SchemefulSite kSite1(GURL("https://foo.test/"));
+ const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
+ const SchemefulSite kSite2(GURL("https://bar.test/"));
+ const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
// This test would need to use a single socket without this option enabled.
// Best to use this option when it would affect a test, as it will eventually
@@ -6288,7 +6286,7 @@ TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
// Make sure that NetworkIsolationKeys are passed down to the proxy layer.
TEST_F(HttpNetworkTransactionTest, ProxyResolvedWithNetworkIsolationKey) {
- const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.test/"));
+ const SchemefulSite kSite(GURL("https://foo.test/"));
ProxyConfig proxy_config;
proxy_config.set_auto_detect(true);
@@ -6418,6 +6416,9 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
EXPECT_EQ(100, response->headers->GetContentLength());
EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
+ // DNS aliases should be empty when using a proxy.
+ EXPECT_TRUE(response->dns_aliases.empty());
+
TransportInfo expected_transport;
expected_transport.type = TransportType::kProxied;
expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 70);
@@ -6486,6 +6487,9 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
ASSERT_TRUE(response->headers);
EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
+ // DNS aliases should be empty when using a proxy.
+ EXPECT_TRUE(response->dns_aliases.empty());
+
TransportInfo expected_transport;
expected_transport.type = TransportType::kProxied;
expected_transport.endpoint = IPEndPoint(IPAddress::IPv4Localhost(), 70);
@@ -9392,6 +9396,105 @@ TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
}
+TEST_F(HttpNetworkTransactionTest, CloseConnectionOnDestruction) {
+ enum class TestCase {
+ kReadHeaders,
+ kReadPartOfBodyRead,
+ kReadAllOfBody,
+ };
+
+ for (auto test_case : {TestCase::kReadHeaders, TestCase::kReadPartOfBodyRead,
+ TestCase::kReadAllOfBody}) {
+ SCOPED_TRACE(testing::Message()
+ << "Test case: " << static_cast<int>(test_case));
+ for (bool close_connection : {false, true}) {
+ if (test_case != TestCase::kReadAllOfBody || close_connection == false)
+ continue;
+ SCOPED_TRACE(testing::Message()
+ << "Close connection: " << close_connection);
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://foo.test/");
+ request.traffic_annotation =
+ net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ std::unique_ptr<HttpNetworkSession> session(
+ CreateSession(&session_deps_));
+
+ std::unique_ptr<HttpNetworkTransaction> trans =
+ std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
+ session.get());
+
+ MockRead data_reads[] = {
+ // A part of the response body is received with the response headers.
+ MockRead("HTTP/1.1 200 OK\r\n"
+ "Content-Length: 11\r\n\r\n"
+ "hello world"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ TestCompletionCallback callback;
+
+ int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+
+ const HttpResponseInfo* response = trans->GetResponseInfo();
+ ASSERT_TRUE(response);
+
+ EXPECT_TRUE(response->headers);
+ std::string status_line = response->headers->GetStatusLine();
+ EXPECT_EQ("HTTP/1.1 200 OK", status_line);
+
+ EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
+
+ std::string response_data;
+ switch (test_case) {
+ case TestCase::kReadHeaders: {
+ // Already read the headers, nothing else to do.
+ break;
+ }
+
+ case TestCase::kReadPartOfBodyRead: {
+ scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(5);
+ rv = trans->Read(buf.get(), 5, callback.callback());
+ ASSERT_EQ(5, callback.GetResult(rv));
+ response_data.assign(buf->data(), 5);
+ EXPECT_EQ("hello", response_data);
+ break;
+ }
+
+ case TestCase::kReadAllOfBody: {
+ rv = ReadTransaction(trans.get(), &response_data);
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_EQ("hello world", response_data);
+ break;
+ }
+ }
+
+ if (close_connection)
+ trans->CloseConnectionOnDestruction();
+ trans.reset();
+
+ // Wait for the socket to be drained and added to the socket pool or
+ // destroyed.
+ base::RunLoop().RunUntilIdle();
+
+ // In the case all the body was read, the socket will have been released
+ // before the CloseConnectionOnDestruction() call, so will not be
+ // destroyed.
+ if (close_connection && test_case != TestCase::kReadAllOfBody) {
+ EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
+ } else {
+ EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
+ }
+ }
+ }
+}
+
// Grab a socket, use it, and put it back into the pool. Then, make
// low memory notification and ensure the socket pool is flushed.
TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
@@ -13346,10 +13449,10 @@ TEST_F(HttpNetworkTransactionTest,
session_deps_.http_server_properties =
std::make_unique<HttpServerProperties>();
- const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
- const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
- const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
- const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
+ const SchemefulSite kSite1(GURL("https://foo.test/"));
+ const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
+ const SchemefulSite kSite2(GURL("https://bar.test/"));
+ const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
MockRead data_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"),
@@ -22161,10 +22264,10 @@ TEST_F(HttpNetworkTransactionTest, ClientCertSocketReuse) {
// same key, the second a different one. Checks that the requests are
// partitioned across sockets as expected.
TEST_F(HttpNetworkTransactionTest, NetworkIsolation) {
- const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
- const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
- NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
- NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
+ const SchemefulSite kSite1(GURL("http://origin1/"));
+ const SchemefulSite kSite2(GURL("http://origin2/"));
+ NetworkIsolationKey network_isolation_key1(kSite1, kSite1);
+ NetworkIsolationKey network_isolation_key2(kSite2, kSite2);
for (bool partition_connections : {false, true}) {
SCOPED_TRACE(partition_connections);
@@ -22309,10 +22412,10 @@ TEST_F(HttpNetworkTransactionTest, NetworkIsolation) {
}
TEST_F(HttpNetworkTransactionTest, NetworkIsolationH2) {
- const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
- const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
- NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
- NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
+ const SchemefulSite kSite1(GURL("http://origin1/"));
+ const SchemefulSite kSite2(GURL("http://origin2/"));
+ NetworkIsolationKey network_isolation_key1(kSite1, kSite1);
+ NetworkIsolationKey network_isolation_key2(kSite2, kSite2);
// Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
// proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
@@ -22539,12 +22642,12 @@ TEST_F(HttpNetworkTransactionTest, NetworkIsolationPreconnect) {
kDontUsePreconnect,
};
- const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
- const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
- const auto kOrigin3 = url::Origin::Create(GURL("http://origin3/"));
- NetworkIsolationKey preconnect1_isolation_key(kOrigin1, kOrigin1);
- NetworkIsolationKey preconnect2_isolation_key(kOrigin2, kOrigin2);
- NetworkIsolationKey not_preconnected_isolation_key(kOrigin3, kOrigin3);
+ const SchemefulSite kSite1(GURL("http://origin1/"));
+ const SchemefulSite kSite2(GURL("http://origin2/"));
+ const SchemefulSite kSite3(GURL("http://origin3/"));
+ NetworkIsolationKey preconnect1_isolation_key(kSite1, kSite1);
+ NetworkIsolationKey preconnect2_isolation_key(kSite2, kSite2);
+ NetworkIsolationKey not_preconnected_isolation_key(kSite3, kSite3);
// Test that only preconnects with
for (TestCase test_case :
@@ -22659,10 +22762,10 @@ TEST_F(HttpNetworkTransactionTest, NetworkIsolationSSL) {
features::kPartitionSSLSessionsByNetworkIsolationKey},
{});
- const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
- const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
- const NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
- const NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
+ const SchemefulSite kSite1(GURL("http://origin1/"));
+ const SchemefulSite kSite2(GURL("http://origin2/"));
+ const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
+ const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// The server always sends Connection: close, so each request goes over a
@@ -22781,10 +22884,10 @@ TEST_F(HttpNetworkTransactionTest, NetworkIsolationSSLProxy) {
ConfiguredProxyResolutionService::CreateFixed(
"https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
- const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
- const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
- const NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
- const NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
+ const SchemefulSite kSite1(GURL("http://origin1/"));
+ const SchemefulSite kSite2(GURL("http://origin2/"));
+ const NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
+ const NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
// Make both a tunneled and non-tunneled request.
@@ -23304,4 +23407,120 @@ TEST_F(HttpNetworkTransactionTest, PostHandshakeClientCertWithSockets) {
trans_post_auth_bar.reset();
}
+TEST_F(HttpNetworkTransactionTest, RequestWithDnsAliases) {
+ // Create a request.
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.traffic_annotation =
+ net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ // Add a rule with DNS aliases to the host resolver.
+ std::vector<std::string> aliases({"alias1", "alias2", "www.example.org"});
+ auto* rules = session_deps_.host_resolver->rules();
+ rules->AddIPLiteralRuleWithDnsAliases("www.example.org", "127.0.0.1",
+ std::move(aliases));
+ session_deps_.host_resolver->set_rules(rules);
+
+ // Create a HttpNetworkSession.
+ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+
+ // Create a transaction.
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
+
+ // Prepare the expected data to be written and read. The client should send
+ // the request below.
+ MockWrite data_writes[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ // The server should respond with the following.
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.0 200 OK\r\n"),
+ MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead("Content-Length: 100\r\n\r\n"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ StaticSocketDataProvider data(data_reads, data_writes);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+ TestCompletionCallback callback;
+
+ // Start the transaction.
+ int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+ // Wait for completion.
+ rv = callback.WaitForResult();
+ EXPECT_THAT(rv, IsOk());
+
+ // Get the response info.
+ const HttpResponseInfo* response = trans.GetResponseInfo();
+
+ // Verify that the alias list was stored in the response info as expected.
+ ASSERT_TRUE(response);
+ EXPECT_THAT(response->dns_aliases,
+ testing::ElementsAre("alias1", "alias2", "www.example.org"));
+}
+
+TEST_F(HttpNetworkTransactionTest, RequestWithNoAdditionalDnsAliases) {
+ // Create a request.
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://www.example.org/");
+ request.traffic_annotation =
+ net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ // Add a rule without DNS aliases to the host resolver. The parameter is an
+ // empty vector.
+ std::vector<std::string> aliases;
+ auto* rules = session_deps_.host_resolver->rules();
+ rules->AddIPLiteralRuleWithDnsAliases("www.example.org", "127.0.0.1",
+ std::move(aliases));
+ session_deps_.host_resolver->set_rules(rules);
+
+ // Create a HttpNetworkSession.
+ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
+
+ // Create a transaction.
+ HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
+
+ // Prepare the expected data to be written and read. The client should send
+ // the request below.
+ MockWrite data_writes[] = {
+ MockWrite("GET / HTTP/1.1\r\n"
+ "Host: www.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ // The server should respond with the following.
+ MockRead data_reads[] = {
+ MockRead("HTTP/1.0 200 OK\r\n"),
+ MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
+ MockRead("Content-Length: 100\r\n\r\n"),
+ MockRead(SYNCHRONOUS, OK),
+ };
+
+ StaticSocketDataProvider data(data_reads, data_writes);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+ TestCompletionCallback callback;
+
+ // Start the transaction.
+ int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
+ EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+ // Wait for completion.
+ rv = callback.WaitForResult();
+ EXPECT_THAT(rv, IsOk());
+
+ // Get the response info.
+ const HttpResponseInfo* response = trans.GetResponseInfo();
+
+ // Verify that the alias list was stored in the response info as expected.
+ ASSERT_TRUE(response);
+ EXPECT_THAT(response->dns_aliases, testing::ElementsAre("www.example.org"));
+}
+
} // namespace net