OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <windows.h> | 8 #include <windows.h> |
9 #include <shlobj.h> | 9 #include <shlobj.h> |
10 #endif | 10 #endif |
11 | 11 |
12 #include <stdint.h> | 12 #include <stdint.h> |
13 | 13 |
14 #include <algorithm> | 14 #include <algorithm> |
15 | 15 |
16 #include "base/basictypes.h" | 16 #include "base/basictypes.h" |
17 #include "base/bind.h" | 17 #include "base/bind.h" |
18 #include "base/compiler_specific.h" | 18 #include "base/compiler_specific.h" |
19 #include "base/files/file_path.h" | 19 #include "base/files/file_path.h" |
20 #include "base/files/file_util.h" | 20 #include "base/files/file_util.h" |
21 #include "base/files/scoped_temp_dir.h" | 21 #include "base/files/scoped_temp_dir.h" |
22 #include "base/format_macros.h" | 22 #include "base/format_macros.h" |
| 23 #include "base/json/json_reader.h" |
23 #include "base/location.h" | 24 #include "base/location.h" |
24 #include "base/memory/scoped_ptr.h" | 25 #include "base/memory/scoped_ptr.h" |
25 #include "base/memory/weak_ptr.h" | 26 #include "base/memory/weak_ptr.h" |
26 #include "base/message_loop/message_loop.h" | 27 #include "base/message_loop/message_loop.h" |
27 #include "base/path_service.h" | 28 #include "base/path_service.h" |
28 #include "base/run_loop.h" | 29 #include "base/run_loop.h" |
29 #include "base/single_thread_task_runner.h" | 30 #include "base/single_thread_task_runner.h" |
30 #include "base/strings/string_number_conversions.h" | 31 #include "base/strings/string_number_conversions.h" |
31 #include "base/strings/string_piece.h" | 32 #include "base/strings/string_piece.h" |
32 #include "base/strings/string_split.h" | 33 #include "base/strings/string_split.h" |
33 #include "base/strings/string_util.h" | 34 #include "base/strings/string_util.h" |
34 #include "base/strings/stringprintf.h" | 35 #include "base/strings/stringprintf.h" |
35 #include "base/strings/utf_string_conversions.h" | 36 #include "base/strings/utf_string_conversions.h" |
36 #include "base/test/histogram_tester.h" | 37 #include "base/test/histogram_tester.h" |
37 #include "base/thread_task_runner_handle.h" | 38 #include "base/thread_task_runner_handle.h" |
| 39 #include "base/values.h" |
38 #include "net/base/chunked_upload_data_stream.h" | 40 #include "net/base/chunked_upload_data_stream.h" |
39 #include "net/base/elements_upload_data_stream.h" | 41 #include "net/base/elements_upload_data_stream.h" |
40 #include "net/base/load_flags.h" | 42 #include "net/base/load_flags.h" |
41 #include "net/base/load_timing_info.h" | 43 #include "net/base/load_timing_info.h" |
42 #include "net/base/load_timing_info_test_util.h" | 44 #include "net/base/load_timing_info_test_util.h" |
43 #include "net/base/net_errors.h" | 45 #include "net/base/net_errors.h" |
44 #include "net/base/net_module.h" | 46 #include "net/base/net_module.h" |
45 #include "net/base/net_util.h" | 47 #include "net/base/net_util.h" |
46 #include "net/base/network_quality.h" | 48 #include "net/base/network_quality.h" |
47 #include "net/base/network_quality_estimator.h" | 49 #include "net/base/network_quality_estimator.h" |
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 TestURLRequestContextWithProxy(const std::string& proxy, | 613 TestURLRequestContextWithProxy(const std::string& proxy, |
612 NetworkDelegate* delegate) | 614 NetworkDelegate* delegate) |
613 : TestURLRequestContext(true) { | 615 : TestURLRequestContext(true) { |
614 context_storage_.set_proxy_service(ProxyService::CreateFixed(proxy)); | 616 context_storage_.set_proxy_service(ProxyService::CreateFixed(proxy)); |
615 set_network_delegate(delegate); | 617 set_network_delegate(delegate); |
616 Init(); | 618 Init(); |
617 } | 619 } |
618 ~TestURLRequestContextWithProxy() override {} | 620 ~TestURLRequestContextWithProxy() override {} |
619 }; | 621 }; |
620 | 622 |
| 623 // A mock ReportSender that just remembers the latest report |
| 624 // URI and report to be sent. |
| 625 class MockCertificateReportSender |
| 626 : public TransportSecurityState::ReportSender { |
| 627 public: |
| 628 MockCertificateReportSender() {} |
| 629 ~MockCertificateReportSender() override {} |
| 630 |
| 631 void Send(const GURL& report_uri, const std::string& report) override { |
| 632 latest_report_uri_ = report_uri; |
| 633 latest_report_ = report; |
| 634 } |
| 635 |
| 636 const GURL& latest_report_uri() { return latest_report_uri_; } |
| 637 const std::string& latest_report() { return latest_report_; } |
| 638 |
| 639 private: |
| 640 GURL latest_report_uri_; |
| 641 std::string latest_report_; |
| 642 }; |
| 643 |
621 } // namespace | 644 } // namespace |
622 | 645 |
623 // Inherit PlatformTest since we require the autorelease pool on Mac OS X. | 646 // Inherit PlatformTest since we require the autorelease pool on Mac OS X. |
624 class URLRequestTest : public PlatformTest { | 647 class URLRequestTest : public PlatformTest { |
625 public: | 648 public: |
626 URLRequestTest() : default_context_(true) { | 649 URLRequestTest() : default_context_(true) { |
627 default_context_.set_network_delegate(&default_network_delegate_); | 650 default_context_.set_network_delegate(&default_network_delegate_); |
628 default_context_.set_net_log(&net_log_); | 651 default_context_.set_net_log(&net_log_); |
629 job_factory_impl_ = new URLRequestJobFactoryImpl(); | 652 job_factory_impl_ = new URLRequestJobFactoryImpl(); |
630 job_factory_.reset(job_factory_impl_); | 653 job_factory_.reset(job_factory_impl_); |
(...skipping 4723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5354 TransportSecurityState::STSState sts_state; | 5377 TransportSecurityState::STSState sts_state; |
5355 EXPECT_FALSE( | 5378 EXPECT_FALSE( |
5356 security_state->GetDynamicSTSState(test_server_hostname, &sts_state)); | 5379 security_state->GetDynamicSTSState(test_server_hostname, &sts_state)); |
5357 } | 5380 } |
5358 | 5381 |
5359 // Android's CertVerifyProc does not (yet) handle pins. Therefore, it will | 5382 // Android's CertVerifyProc does not (yet) handle pins. Therefore, it will |
5360 // reject HPKP headers, and a test setting only HPKP headers will fail (no | 5383 // reject HPKP headers, and a test setting only HPKP headers will fail (no |
5361 // PKPState present because header rejected). | 5384 // PKPState present because header rejected). |
5362 #if defined(OS_ANDROID) | 5385 #if defined(OS_ANDROID) |
5363 #define MAYBE_ProcessPKP DISABLED_ProcessPKP | 5386 #define MAYBE_ProcessPKP DISABLED_ProcessPKP |
| 5387 #define MAYBE_ProcessPKPAndSendReport DISABLED_ProcessPKPAndSendReport |
| 5388 #define MAYBE_ProcessPKPReportOnly DISABLED_ProcessPKPReportOnly |
| 5389 #define MAYBE_ProcessPKPReportOnlyWithNoViolation \ |
| 5390 DISABLED_ProcessPKPReportOnlyWithNoViolation |
5364 #else | 5391 #else |
5365 #define MAYBE_ProcessPKP ProcessPKP | 5392 #define MAYBE_ProcessPKP ProcessPKP |
| 5393 #define MAYBE_ProcessPKPAndSendReport ProcessPKPAndSendReport |
| 5394 #define MAYBE_ProcessPKPReportOnly ProcessPKPReportOnly |
| 5395 #define MAYBE_ProcessPKPReportOnlyWithNoViolation \ |
| 5396 ProcessPKPReportOnlyWithNoViolation |
5366 #endif | 5397 #endif |
5367 | 5398 |
| 5399 namespace { |
| 5400 const char kHPKPReportUri[] = "https://hpkp-report.test"; |
| 5401 } // namespace |
| 5402 |
5368 // Tests that enabling HPKP on a domain does not affect the HSTS | 5403 // Tests that enabling HPKP on a domain does not affect the HSTS |
5369 // validity/expiration. | 5404 // validity/expiration. |
5370 TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKP) { | 5405 TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKP) { |
| 5406 GURL report_uri(kHPKPReportUri); |
5371 SpawnedTestServer::SSLOptions ssl_options( | 5407 SpawnedTestServer::SSLOptions ssl_options( |
5372 SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN); | 5408 SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN); |
5373 SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS, | 5409 SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS, |
5374 ssl_options, | 5410 ssl_options, |
5375 base::FilePath(kTestFilePath)); | 5411 base::FilePath(kTestFilePath)); |
5376 ASSERT_TRUE(https_test_server.Start()); | 5412 ASSERT_TRUE(https_test_server.Start()); |
5377 | 5413 |
5378 std::string test_server_hostname = https_test_server.GetURL("").host(); | 5414 std::string test_server_hostname = https_test_server.GetURL("").host(); |
5379 | 5415 |
5380 TestDelegate d; | 5416 TestDelegate d; |
5381 scoped_ptr<URLRequest> request(default_context_.CreateRequest( | 5417 scoped_ptr<URLRequest> request(default_context_.CreateRequest( |
5382 https_test_server.GetURL("files/hpkp-headers.html"), DEFAULT_PRIORITY, | 5418 https_test_server.GetURL("files/hpkp-headers.html"), DEFAULT_PRIORITY, |
5383 &d)); | 5419 &d)); |
5384 request->Start(); | 5420 request->Start(); |
5385 base::RunLoop().Run(); | 5421 base::RunLoop().Run(); |
5386 | 5422 |
5387 TransportSecurityState* security_state = | 5423 TransportSecurityState* security_state = |
5388 default_context_.transport_security_state(); | 5424 default_context_.transport_security_state(); |
5389 TransportSecurityState::STSState sts_state; | 5425 TransportSecurityState::STSState sts_state; |
5390 TransportSecurityState::PKPState pkp_state; | 5426 TransportSecurityState::PKPState pkp_state; |
5391 EXPECT_FALSE( | 5427 EXPECT_FALSE( |
5392 security_state->GetDynamicSTSState(test_server_hostname, &sts_state)); | 5428 security_state->GetDynamicSTSState(test_server_hostname, &sts_state)); |
5393 EXPECT_TRUE( | 5429 EXPECT_TRUE( |
5394 security_state->GetDynamicPKPState(test_server_hostname, &pkp_state)); | 5430 security_state->GetDynamicPKPState(test_server_hostname, &pkp_state)); |
5395 EXPECT_EQ(TransportSecurityState::STSState::MODE_DEFAULT, | 5431 EXPECT_EQ(TransportSecurityState::STSState::MODE_DEFAULT, |
5396 sts_state.upgrade_mode); | 5432 sts_state.upgrade_mode); |
5397 EXPECT_FALSE(sts_state.include_subdomains); | 5433 EXPECT_FALSE(sts_state.include_subdomains); |
5398 EXPECT_FALSE(pkp_state.include_subdomains); | 5434 EXPECT_FALSE(pkp_state.include_subdomains); |
5399 EXPECT_TRUE(pkp_state.HasPublicKeyPins()); | 5435 EXPECT_TRUE(pkp_state.HasPublicKeyPins()); |
| 5436 EXPECT_EQ(report_uri, pkp_state.report_uri); |
5400 EXPECT_NE(sts_state.expiry, pkp_state.expiry); | 5437 EXPECT_NE(sts_state.expiry, pkp_state.expiry); |
5401 } | 5438 } |
5402 | 5439 |
| 5440 // Tests that reports get sent on HPKP violations when a report-uri is set. |
| 5441 TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPAndSendReport) { |
| 5442 GURL report_uri(kHPKPReportUri); |
| 5443 SpawnedTestServer::SSLOptions ssl_options( |
| 5444 SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN); |
| 5445 SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS, |
| 5446 ssl_options, |
| 5447 base::FilePath(kTestFilePath)); |
| 5448 |
| 5449 ASSERT_TRUE(https_test_server.Start()); |
| 5450 |
| 5451 std::string test_server_hostname = https_test_server.GetURL("").host(); |
| 5452 |
| 5453 // Set up a pin for |test_server_hostname|. |
| 5454 TransportSecurityState security_state; |
| 5455 const base::Time current_time(base::Time::Now()); |
| 5456 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
| 5457 HashValueVector hashes; |
| 5458 HashValue hash1; |
| 5459 HashValue hash2; |
| 5460 // The values here don't matter, as long as they are different from |
| 5461 // the mocked CertVerifyResult below. |
| 5462 ASSERT_TRUE(hash1.FromString("sha1/111111111111111111111111111=")); |
| 5463 ASSERT_TRUE(hash2.FromString("sha1/222222222222222222222222222=")); |
| 5464 hashes.push_back(hash1); |
| 5465 hashes.push_back(hash2); |
| 5466 security_state.AddHPKP(test_server_hostname, expiry, |
| 5467 false, /* include subdomains */ |
| 5468 hashes, report_uri); |
| 5469 |
| 5470 MockCertificateReportSender mock_report_sender; |
| 5471 security_state.SetReportSender(&mock_report_sender); |
| 5472 |
| 5473 // Set up a MockCertVerifier to trigger a violation of the previously |
| 5474 // set pin. |
| 5475 scoped_refptr<X509Certificate> cert = https_test_server.GetCertificate(); |
| 5476 ASSERT_TRUE(cert); |
| 5477 |
| 5478 MockCertVerifier cert_verifier; |
| 5479 CertVerifyResult verify_result; |
| 5480 verify_result.verified_cert = cert; |
| 5481 verify_result.is_issued_by_known_root = true; |
| 5482 HashValue hash3; |
| 5483 ASSERT_TRUE(hash3.FromString("sha1/333333333333333333333333333=")); |
| 5484 verify_result.public_key_hashes.push_back(hash3); |
| 5485 cert_verifier.AddResultForCert(cert.get(), verify_result, OK); |
| 5486 |
| 5487 TestNetworkDelegate network_delegate; |
| 5488 TestURLRequestContext context(true); |
| 5489 context.set_transport_security_state(&security_state); |
| 5490 context.set_network_delegate(&network_delegate); |
| 5491 context.set_cert_verifier(&cert_verifier); |
| 5492 context.Init(); |
| 5493 |
| 5494 // Now send a request to trigger the violation. |
| 5495 TestDelegate d; |
| 5496 scoped_ptr<URLRequest> violating_request(context.CreateRequest( |
| 5497 https_test_server.GetURL("files/simple.html"), DEFAULT_PRIORITY, &d)); |
| 5498 violating_request->Start(); |
| 5499 base::RunLoop().Run(); |
| 5500 |
| 5501 // Check that a report was sent. |
| 5502 EXPECT_EQ(report_uri, mock_report_sender.latest_report_uri()); |
| 5503 ASSERT_FALSE(mock_report_sender.latest_report().empty()); |
| 5504 scoped_ptr<base::Value> value( |
| 5505 base::JSONReader::Read(mock_report_sender.latest_report())); |
| 5506 ASSERT_TRUE(value); |
| 5507 ASSERT_TRUE(value->IsType(base::Value::TYPE_DICTIONARY)); |
| 5508 base::DictionaryValue* report_dict; |
| 5509 ASSERT_TRUE(value->GetAsDictionary(&report_dict)); |
| 5510 std::string report_hostname; |
| 5511 EXPECT_TRUE(report_dict->GetString("hostname", &report_hostname)); |
| 5512 EXPECT_EQ(test_server_hostname, report_hostname); |
| 5513 } |
| 5514 |
| 5515 // Tests that reports get sent on requests with |
| 5516 // Public-Key-Pins-Report-Only headers. |
| 5517 TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPReportOnly) { |
| 5518 GURL report_uri(kHPKPReportUri); |
| 5519 SpawnedTestServer::SSLOptions ssl_options( |
| 5520 SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN); |
| 5521 SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS, |
| 5522 ssl_options, |
| 5523 base::FilePath(kTestFilePath)); |
| 5524 |
| 5525 ASSERT_TRUE(https_test_server.Start()); |
| 5526 |
| 5527 std::string test_server_hostname = https_test_server.GetURL("").host(); |
| 5528 |
| 5529 TransportSecurityState security_state; |
| 5530 MockCertificateReportSender mock_report_sender; |
| 5531 security_state.SetReportSender(&mock_report_sender); |
| 5532 |
| 5533 // Set up a MockCertVerifier to violate the pin in the Report-Only |
| 5534 // header. |
| 5535 scoped_refptr<X509Certificate> cert = https_test_server.GetCertificate(); |
| 5536 ASSERT_TRUE(cert); |
| 5537 |
| 5538 MockCertVerifier cert_verifier; |
| 5539 CertVerifyResult verify_result; |
| 5540 verify_result.verified_cert = cert; |
| 5541 verify_result.is_issued_by_known_root = true; |
| 5542 HashValue hash; |
| 5543 // This value doesn't matter, as long as it is different from the pins |
| 5544 // for the request to hpkp-headers-report-only.html. |
| 5545 ASSERT_TRUE(hash.FromString("sha1/111111111111111111111111111=")); |
| 5546 verify_result.public_key_hashes.push_back(hash); |
| 5547 cert_verifier.AddResultForCert(cert.get(), verify_result, OK); |
| 5548 |
| 5549 TestNetworkDelegate network_delegate; |
| 5550 TestURLRequestContext context(true); |
| 5551 context.set_transport_security_state(&security_state); |
| 5552 context.set_network_delegate(&network_delegate); |
| 5553 context.set_cert_verifier(&cert_verifier); |
| 5554 context.Init(); |
| 5555 |
| 5556 // Now send a request to trigger the violation. |
| 5557 TestDelegate d; |
| 5558 scoped_ptr<URLRequest> violating_request(context.CreateRequest( |
| 5559 https_test_server.GetURL("files/hpkp-headers-report-only.html"), |
| 5560 DEFAULT_PRIORITY, &d)); |
| 5561 violating_request->Start(); |
| 5562 base::RunLoop().Run(); |
| 5563 |
| 5564 // Check that a report was sent. |
| 5565 EXPECT_EQ(report_uri, mock_report_sender.latest_report_uri()); |
| 5566 ASSERT_FALSE(mock_report_sender.latest_report().empty()); |
| 5567 scoped_ptr<base::Value> value( |
| 5568 base::JSONReader::Read(mock_report_sender.latest_report())); |
| 5569 ASSERT_TRUE(value); |
| 5570 ASSERT_TRUE(value->IsType(base::Value::TYPE_DICTIONARY)); |
| 5571 base::DictionaryValue* report_dict; |
| 5572 ASSERT_TRUE(value->GetAsDictionary(&report_dict)); |
| 5573 std::string report_hostname; |
| 5574 EXPECT_TRUE(report_dict->GetString("hostname", &report_hostname)); |
| 5575 EXPECT_EQ(test_server_hostname, report_hostname); |
| 5576 } |
| 5577 |
| 5578 // Tests that reports do not get sent on requests with |
| 5579 // Public-Key-Pins-Report-Only headers that don't have pin violations. |
| 5580 TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPReportOnlyWithNoViolation) { |
| 5581 GURL report_uri(kHPKPReportUri); |
| 5582 SpawnedTestServer::SSLOptions ssl_options( |
| 5583 SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN); |
| 5584 SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS, |
| 5585 ssl_options, |
| 5586 base::FilePath(kTestFilePath)); |
| 5587 |
| 5588 ASSERT_TRUE(https_test_server.Start()); |
| 5589 |
| 5590 std::string test_server_hostname = https_test_server.GetURL("").host(); |
| 5591 |
| 5592 TransportSecurityState security_state; |
| 5593 MockCertificateReportSender mock_report_sender; |
| 5594 security_state.SetReportSender(&mock_report_sender); |
| 5595 |
| 5596 TestNetworkDelegate network_delegate; |
| 5597 MockCertVerifier mock_cert_verifier; |
| 5598 TestURLRequestContext context(true); |
| 5599 context.set_transport_security_state(&security_state); |
| 5600 context.set_network_delegate(&network_delegate); |
| 5601 context.set_cert_verifier(&mock_cert_verifier); |
| 5602 mock_cert_verifier.set_default_result(OK); |
| 5603 context.Init(); |
| 5604 |
| 5605 // Now send a request that does not trigger the violation. |
| 5606 TestDelegate d; |
| 5607 scoped_ptr<URLRequest> request(context.CreateRequest( |
| 5608 https_test_server.GetURL("files/hpkp-headers-report-only.html"), |
| 5609 DEFAULT_PRIORITY, &d)); |
| 5610 request->Start(); |
| 5611 base::RunLoop().Run(); |
| 5612 |
| 5613 // Check that a report was not sent. |
| 5614 EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri()); |
| 5615 EXPECT_EQ(std::string(), mock_report_sender.latest_report()); |
| 5616 } |
| 5617 |
5403 TEST_F(URLRequestTestHTTP, PKPNotProcessedOnIP) { | 5618 TEST_F(URLRequestTestHTTP, PKPNotProcessedOnIP) { |
5404 SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS, | 5619 SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS, |
5405 SpawnedTestServer::SSLOptions(), | 5620 SpawnedTestServer::SSLOptions(), |
5406 base::FilePath(kTestFilePath)); | 5621 base::FilePath(kTestFilePath)); |
5407 ASSERT_TRUE(https_test_server.Start()); | 5622 ASSERT_TRUE(https_test_server.Start()); |
5408 // Make sure this test fails if the test server is changed to not | 5623 // Make sure this test fails if the test server is changed to not |
5409 // listen on an IP by default. | 5624 // listen on an IP by default. |
5410 ASSERT_TRUE(https_test_server.GetURL("").HostIsIPAddress()); | 5625 ASSERT_TRUE(https_test_server.GetURL("").HostIsIPAddress()); |
5411 std::string test_server_hostname = https_test_server.GetURL("").host(); | 5626 std::string test_server_hostname = https_test_server.GetURL("").host(); |
5412 | 5627 |
(...skipping 3810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9223 | 9438 |
9224 req->Start(); | 9439 req->Start(); |
9225 req->Cancel(); | 9440 req->Cancel(); |
9226 job->DetachRequest(); | 9441 job->DetachRequest(); |
9227 base::RunLoop().RunUntilIdle(); | 9442 base::RunLoop().RunUntilIdle(); |
9228 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); | 9443 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); |
9229 EXPECT_EQ(0, d.received_redirect_count()); | 9444 EXPECT_EQ(0, d.received_redirect_count()); |
9230 } | 9445 } |
9231 | 9446 |
9232 } // namespace net | 9447 } // namespace net |
OLD | NEW |