#include "net/url_request/url_request_http_job.h"
#include <stdint.h>
#include <cstddef>
#include <memory>
#include <utility>
#include <vector>
#include "base/compiler_specific.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "net/base/auth.h"
#include "net/base/features.h"
#include "net/base/isolation_info.h"
#include "net/base/load_flags.h"
#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/base/proxy_string_util.h"
#include "net/base/request_priority.h"
#include "net/base/test_proxy_delegate.h"
#include "net/cert/ct_policy_status.h"
#include "net/cookies/canonical_cookie_test_helpers.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store_test_callbacks.h"
#include "net/cookies/cookie_store_test_helpers.h"
#include "net/cookies/test_cookie_access_delegate.h"
#include "net/http/http_transaction_factory.h"
#include "net/http/http_transaction_test_util.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log_event_type.h"
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_util.h"
#include "net/net_buildflags.h"
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
#include "net/socket/next_proto.h"
#include "net/socket/socket_test_util.h"
#include "net/test/cert_test_util.h"
#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
#include "net/test/test_with_task_environment.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_test_util.h"
#include "net/url_request/websocket_handshake_userdata_key.h"
#include "net/websockets/websocket_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/url_constants.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/android/jni_android.h"
#include "net/android/net_test_support_jni/AndroidNetworkLibraryTestUtil_jni.h"
#endif
#if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
#include "net/device_bound_sessions/session_service.h"
#include "net/device_bound_sessions/test_util.h"
#endif
IsError;
IsOk;
namespace net {
namespace {
_;
Return;
UnorderedElementsAre;
const char kSimpleGetMockWrite[] = …;
const char kSimpleHeadMockWrite[] = …;
const char kTrustAnchorRequestHistogram[] = …;
class TestURLRequestHttpJob : public URLRequestHttpJob { … };
class URLRequestHttpJobSetUpSourceTest : public TestWithTaskEnvironment { … };
TEST_F(URLRequestHttpJobSetUpSourceTest, SetUpSourceFails) { … }
TEST_F(URLRequestHttpJobSetUpSourceTest, UnknownEncoding) { … }
URLRequestHttpJobWithProxyTest;
class URLRequestHttpJobWithProxy { … };
TEST_F(URLRequestHttpJobWithProxyTest, TestFailureWithoutProxy) { … }
TEST_F(URLRequestHttpJobWithProxyTest, TestSuccessfulWithOneProxy) { … }
TEST_F(URLRequestHttpJobWithProxyTest,
TestContentLengthSuccessfulRequestWithTwoProxies) { … }
TEST_F(URLRequestHttpJobWithProxyTest, IpProtectionDirectProxyMetricsRecorded) { … }
class URLRequestHttpJobTest : public TestWithTaskEnvironment { … };
class URLRequestHttpJobWithMockSocketsTest : public TestWithTaskEnvironment { … };
TEST_F(URLRequestHttpJobWithMockSocketsTest,
TestContentLengthSuccessfulRequest) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest, TestSuccessfulHead) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest, TestSuccessfulHeadWithContent) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest, TestSuccessfulCachedHeadRequest) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest,
TestContentLengthSuccessfulHttp09Request) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest, TestContentLengthFailedRequest) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest,
TestContentLengthCancelledRequest) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest,
TestNetworkBytesRedirectedRequest) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest,
TestNetworkBytesCancelledAfterHeaders) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest,
TestNetworkBytesCancelledImmediately) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest, TestHttpTimeToFirstByte) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest,
TestHttpTimeToFirstByteForCancelledTask) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest,
TestHttpJobSuccessPriorityKeyedTotalTime) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest,
TestHttpJobRecordsTrustAnchorHistograms) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest,
TestHttpJobDoesNotRecordTrustAnchorHistogramsWhenNoNetworkLoad) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest,
TestHttpJobRecordsMostSpecificTrustAnchorHistograms) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest, EncodingAdvertisementOnRange) { … }
TEST_F(URLRequestHttpJobWithMockSocketsTest, RangeRequestOverrideEncoding) { … }
TEST_F(URLRequestHttpJobTest, TestCancelWhileReadingCookies) { … }
TEST_F(URLRequestHttpJobTest, SetPriorityBasic) { … }
TEST_F(URLRequestHttpJobTest, SetTransactionPriorityOnStart) { … }
TEST_F(URLRequestHttpJobTest, SetTransactionPriority) { … }
TEST_F(URLRequestHttpJobTest, HSTSInternalRedirectTest) { … }
TEST_F(URLRequestHttpJobTest, ShouldBypassHSTS) { … }
#if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
class URLRequestHttpJobWithMockSocketsDeviceBoundSessionServiceTest
: public TestWithTaskEnvironment {
protected:
URLRequestHttpJobWithMockSocketsDeviceBoundSessionServiceTest() {
auto context_builder = CreateTestURLRequestContextBuilder();
context_builder->set_client_socket_factory_for_testing(&socket_factory_);
context_builder->set_device_bound_session_service(
std::make_unique<
testing::StrictMock<device_bound_sessions::SessionServiceMock>>());
context_ = context_builder->Build();
request_ = context_->CreateRequest(GURL("http://www.example.com"),
DEFAULT_PRIORITY, &delegate_,
TRAFFIC_ANNOTATION_FOR_TESTS);
}
device_bound_sessions::SessionServiceMock& GetMockService() {
return *static_cast<device_bound_sessions::SessionServiceMock*>(
context_->device_bound_session_service());
}
MockClientSocketFactory socket_factory_;
std::unique_ptr<URLRequestContext> context_;
TestDelegate delegate_;
std::unique_ptr<URLRequest> request_;
};
TEST_F(URLRequestHttpJobWithMockSocketsDeviceBoundSessionServiceTest,
ShouldRespondToDeviceBoundSessionHeader) {
const MockWrite writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
"Host: www.example.com\r\n"
"Connection: keep-alive\r\n"
"User-Agent: \r\n"
"Accept-Encoding: gzip, deflate\r\n"
"Accept-Language: en-us,fr\r\n\r\n")};
const MockRead reads[] = {
MockRead("HTTP/1.1 200 OK\r\n"
"Accept-Ranges: bytes\r\n"
"Sec-Session-Registration: (ES256);path=\"new\";"
"challenge=\"test\"\r\n"
"Content-Length: 12\r\n\r\n"),
MockRead("Test Content")};
StaticSocketDataProvider socket_data(reads, writes);
socket_factory_.AddSocketDataProvider(&socket_data);
request_->Start();
EXPECT_CALL(GetMockService(), RegisterBoundSession).Times(1);
delegate_.RunUntilComplete();
EXPECT_THAT(delegate_.request_status(), IsOk());
}
TEST_F(URLRequestHttpJobWithMockSocketsDeviceBoundSessionServiceTest,
ShouldNotRespondWithoutDeviceBoundSessionHeader) {
const MockWrite writes[] = {
MockWrite("GET / HTTP/1.1\r\n"
"Host: www.example.com\r\n"
"Connection: keep-alive\r\n"
"User-Agent: \r\n"
"Accept-Encoding: gzip, deflate\r\n"
"Accept-Language: en-us,fr\r\n\r\n")};
const MockRead reads[] = {MockRead("HTTP/1.1 200 OK\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 12\r\n\r\n"),
MockRead("Test Content")};
StaticSocketDataProvider socket_data(reads, writes);
socket_factory_.AddSocketDataProvider(&socket_data);
request_->Start();
EXPECT_CALL(GetMockService(), RegisterBoundSession).Times(0);
delegate_.RunUntilComplete();
EXPECT_THAT(delegate_.request_status(), IsOk());
}
#endif
namespace {
std::unique_ptr<test_server::HttpResponse> HandleRequest(
const std::string_view& content,
const test_server::HttpRequest& request) { … }
}
TEST_F(URLRequestHttpJobTest, ShouldBypassHSTSResponseAndConnectionNotReused) { … }
TEST_F(URLRequestHttpJobTest, HSTSInternalRedirectCallback) { … }
class URLRequestHttpJobWithBrotliSupportTest : public TestWithTaskEnvironment { … };
TEST_F(URLRequestHttpJobWithBrotliSupportTest, NoBrotliAdvertisementOverHttp) { … }
TEST_F(URLRequestHttpJobWithBrotliSupportTest, BrotliAdvertisement) { … }
TEST_F(URLRequestHttpJobWithBrotliSupportTest, DefaultAcceptEncodingOverriden) { … }
#if BUILDFLAG(IS_ANDROID)
class URLRequestHttpJobWithCheckClearTextPermittedTest
: public TestWithTaskEnvironment {
protected:
URLRequestHttpJobWithCheckClearTextPermittedTest() {
auto context_builder = CreateTestURLRequestContextBuilder();
context_builder->SetHttpTransactionFactoryForTesting(
std::make_unique<MockNetworkLayer>());
context_builder->set_check_cleartext_permitted(true);
context_builder->set_client_socket_factory_for_testing(&socket_factory_);
context_ = context_builder->Build();
}
MockClientSocketFactory socket_factory_;
std::unique_ptr<URLRequestContext> context_;
};
TEST_F(URLRequestHttpJobWithCheckClearTextPermittedTest,
AndroidCleartextPermittedTest) {
static constexpr struct TestCase {
const char* url;
bool cleartext_permitted;
bool should_block;
int expected_per_host_call_count;
int expected_default_call_count;
} kTestCases[] = {
{"http://unblocked.test/", true, false, 1, 0},
{"https://unblocked.test/", true, false, 0, 0},
{"http://blocked.test/", false, true, 1, 0},
{"https://blocked.test/", false, false, 0, 0},
{"http://./", false, true, 1, 1},
{"http://./", true, false, 1, 1},
{"https://./", false, false, 0, 0},
};
JNIEnv* env = base::android::AttachCurrentThread();
for (const TestCase& test : kTestCases) {
Java_AndroidNetworkLibraryTestUtil_setUpSecurityPolicyForTesting(
env, test.cleartext_permitted);
TestDelegate delegate;
std::unique_ptr<URLRequest> request =
context_->CreateRequest(GURL(test.url), DEFAULT_PRIORITY, &delegate,
TRAFFIC_ANNOTATION_FOR_TESTS);
request->Start();
delegate.RunUntilComplete();
if (test.should_block) {
EXPECT_THAT(delegate.request_status(),
IsError(ERR_CLEARTEXT_NOT_PERMITTED));
} else {
EXPECT_THAT(delegate.request_status(), IsError(ERR_FAILED));
}
EXPECT_EQ(
Java_AndroidNetworkLibraryTestUtil_getPerHostCleartextCheckCount(env),
test.expected_per_host_call_count);
EXPECT_EQ(
Java_AndroidNetworkLibraryTestUtil_getDefaultCleartextCheckCount(env),
test.expected_default_call_count);
}
}
#endif
#if BUILDFLAG(ENABLE_WEBSOCKETS)
class URLRequestHttpJobWebSocketTest : public TestWithTaskEnvironment { … };
TEST_F(URLRequestHttpJobWebSocketTest, RejectedWithoutCreateHelper) { … }
TEST_F(URLRequestHttpJobWebSocketTest, CreateHelperPassedThrough) { … }
#endif
bool SetAllCookies(CookieMonster* cm, const CookieList& list) { … }
bool CreateAndSetCookie(CookieStore* cs,
const GURL& url,
const std::string& cookie_line) { … }
void RunRequest(URLRequestContext* context, const GURL& url) { … }
}
TEST_F(URLRequestHttpJobTest, CookieSchemeRequestSchemeHistogram) { … }
TEST_F(URLRequestHttpJobTest, PrivacyMode_ExclusionReason) { … }
TEST_F(URLRequestHttpJobTest, IndividuallyBlockedCookies) { … }
namespace {
int content_count = …;
std::unique_ptr<test_server::HttpResponse> IncreaseOnRequest(
const test_server::HttpRequest& request) { … }
void ResetContentCount() { … }
}
TEST_F(URLRequestHttpJobTest, GetFirstPartySetsCacheFilterMatchInfo) { … }
TEST_F(URLRequestHttpJobTest, SetPartitionedCookie) { … }
TEST_F(URLRequestHttpJobTest, PartitionedCookiePrivacyMode) { … }
}