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 |
(...skipping 4941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4952 TestDelegate d; | 4952 TestDelegate d; |
4953 URLRequest request(https_test_server.GetURL("files/hsts-headers.html"), | 4953 URLRequest request(https_test_server.GetURL("files/hsts-headers.html"), |
4954 DEFAULT_PRIORITY, | 4954 DEFAULT_PRIORITY, |
4955 &d, | 4955 &d, |
4956 &default_context_); | 4956 &default_context_); |
4957 request.Start(); | 4957 request.Start(); |
4958 base::RunLoop().Run(); | 4958 base::RunLoop().Run(); |
4959 | 4959 |
4960 TransportSecurityState* security_state = | 4960 TransportSecurityState* security_state = |
4961 default_context_.transport_security_state(); | 4961 default_context_.transport_security_state(); |
4962 bool sni_available = true; | |
4963 TransportSecurityState::DomainState domain_state; | 4962 TransportSecurityState::DomainState domain_state; |
4964 EXPECT_TRUE(security_state->GetDomainState( | 4963 EXPECT_TRUE(security_state->GetDynamicDomainState( |
4965 SpawnedTestServer::kLocalhost, sni_available, &domain_state)); | 4964 SpawnedTestServer::kLocalhost, &domain_state)); |
4966 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, | 4965 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, |
4967 domain_state.upgrade_mode); | 4966 domain_state.sts.upgrade_mode); |
4968 EXPECT_TRUE(domain_state.sts_include_subdomains); | 4967 EXPECT_TRUE(domain_state.sts.include_subdomains); |
4969 EXPECT_FALSE(domain_state.pkp_include_subdomains); | 4968 EXPECT_FALSE(domain_state.pkp.include_subdomains); |
4970 #if defined(OS_ANDROID) | 4969 #if defined(OS_ANDROID) |
4971 // Android's CertVerifyProc does not (yet) handle pins. | 4970 // Android's CertVerifyProc does not (yet) handle pins. |
4972 #else | 4971 #else |
4973 EXPECT_FALSE(domain_state.HasPublicKeyPins()); | 4972 EXPECT_FALSE(domain_state.HasPublicKeyPins()); |
4974 #endif | 4973 #endif |
4975 } | 4974 } |
4976 | 4975 |
4977 // Android's CertVerifyProc does not (yet) handle pins. Therefore, it will | 4976 // Android's CertVerifyProc does not (yet) handle pins. Therefore, it will |
4978 // reject HPKP headers, and a test setting only HPKP headers will fail (no | 4977 // reject HPKP headers, and a test setting only HPKP headers will fail (no |
4979 // DomainState present because header rejected). | 4978 // DomainState present because header rejected). |
(...skipping 16 matching lines...) Expand all Loading... |
4996 TestDelegate d; | 4995 TestDelegate d; |
4997 URLRequest request(https_test_server.GetURL("files/hpkp-headers.html"), | 4996 URLRequest request(https_test_server.GetURL("files/hpkp-headers.html"), |
4998 DEFAULT_PRIORITY, | 4997 DEFAULT_PRIORITY, |
4999 &d, | 4998 &d, |
5000 &default_context_); | 4999 &default_context_); |
5001 request.Start(); | 5000 request.Start(); |
5002 base::RunLoop().Run(); | 5001 base::RunLoop().Run(); |
5003 | 5002 |
5004 TransportSecurityState* security_state = | 5003 TransportSecurityState* security_state = |
5005 default_context_.transport_security_state(); | 5004 default_context_.transport_security_state(); |
5006 bool sni_available = true; | |
5007 TransportSecurityState::DomainState domain_state; | 5005 TransportSecurityState::DomainState domain_state; |
5008 EXPECT_TRUE(security_state->GetDomainState( | 5006 EXPECT_TRUE(security_state->GetDynamicDomainState( |
5009 SpawnedTestServer::kLocalhost, sni_available, &domain_state)); | 5007 SpawnedTestServer::kLocalhost, &domain_state)); |
5010 EXPECT_EQ(TransportSecurityState::DomainState::MODE_DEFAULT, | 5008 EXPECT_EQ(TransportSecurityState::DomainState::MODE_DEFAULT, |
5011 domain_state.upgrade_mode); | 5009 domain_state.sts.upgrade_mode); |
5012 EXPECT_FALSE(domain_state.sts_include_subdomains); | 5010 EXPECT_FALSE(domain_state.sts.include_subdomains); |
5013 EXPECT_FALSE(domain_state.pkp_include_subdomains); | 5011 EXPECT_FALSE(domain_state.pkp.include_subdomains); |
5014 EXPECT_TRUE(domain_state.HasPublicKeyPins()); | 5012 EXPECT_TRUE(domain_state.HasPublicKeyPins()); |
5015 EXPECT_NE(domain_state.upgrade_expiry, | 5013 EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry); |
5016 domain_state.dynamic_spki_hashes_expiry); | |
5017 } | 5014 } |
5018 | 5015 |
5019 TEST_F(URLRequestTestHTTP, ProcessSTSOnce) { | 5016 TEST_F(URLRequestTestHTTP, ProcessSTSOnce) { |
5020 SpawnedTestServer::SSLOptions ssl_options; | 5017 SpawnedTestServer::SSLOptions ssl_options; |
5021 SpawnedTestServer https_test_server( | 5018 SpawnedTestServer https_test_server( |
5022 SpawnedTestServer::TYPE_HTTPS, | 5019 SpawnedTestServer::TYPE_HTTPS, |
5023 ssl_options, | 5020 ssl_options, |
5024 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | 5021 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
5025 ASSERT_TRUE(https_test_server.Start()); | 5022 ASSERT_TRUE(https_test_server.Start()); |
5026 | 5023 |
5027 TestDelegate d; | 5024 TestDelegate d; |
5028 URLRequest request( | 5025 URLRequest request( |
5029 https_test_server.GetURL("files/hsts-multiple-headers.html"), | 5026 https_test_server.GetURL("files/hsts-multiple-headers.html"), |
5030 DEFAULT_PRIORITY, | 5027 DEFAULT_PRIORITY, |
5031 &d, | 5028 &d, |
5032 &default_context_); | 5029 &default_context_); |
5033 request.Start(); | 5030 request.Start(); |
5034 base::RunLoop().Run(); | 5031 base::RunLoop().Run(); |
5035 | 5032 |
5036 // We should have set parameters from the first header, not the second. | 5033 // We should have set parameters from the first header, not the second. |
5037 TransportSecurityState* security_state = | 5034 TransportSecurityState* security_state = |
5038 default_context_.transport_security_state(); | 5035 default_context_.transport_security_state(); |
5039 bool sni_available = true; | |
5040 TransportSecurityState::DomainState domain_state; | 5036 TransportSecurityState::DomainState domain_state; |
5041 EXPECT_TRUE(security_state->GetDomainState( | 5037 EXPECT_TRUE(security_state->GetDynamicDomainState( |
5042 SpawnedTestServer::kLocalhost, sni_available, &domain_state)); | 5038 SpawnedTestServer::kLocalhost, &domain_state)); |
5043 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, | 5039 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, |
5044 domain_state.upgrade_mode); | 5040 domain_state.sts.upgrade_mode); |
5045 EXPECT_FALSE(domain_state.sts_include_subdomains); | 5041 EXPECT_FALSE(domain_state.sts.include_subdomains); |
5046 EXPECT_FALSE(domain_state.pkp_include_subdomains); | 5042 EXPECT_FALSE(domain_state.pkp.include_subdomains); |
5047 } | 5043 } |
5048 | 5044 |
5049 TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP) { | 5045 TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP) { |
5050 SpawnedTestServer::SSLOptions ssl_options; | 5046 SpawnedTestServer::SSLOptions ssl_options; |
5051 SpawnedTestServer https_test_server( | 5047 SpawnedTestServer https_test_server( |
5052 SpawnedTestServer::TYPE_HTTPS, | 5048 SpawnedTestServer::TYPE_HTTPS, |
5053 ssl_options, | 5049 ssl_options, |
5054 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | 5050 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
5055 ASSERT_TRUE(https_test_server.Start()); | 5051 ASSERT_TRUE(https_test_server.Start()); |
5056 | 5052 |
5057 TestDelegate d; | 5053 TestDelegate d; |
5058 URLRequest request( | 5054 URLRequest request( |
5059 https_test_server.GetURL("files/hsts-and-hpkp-headers.html"), | 5055 https_test_server.GetURL("files/hsts-and-hpkp-headers.html"), |
5060 DEFAULT_PRIORITY, | 5056 DEFAULT_PRIORITY, |
5061 &d, | 5057 &d, |
5062 &default_context_); | 5058 &default_context_); |
5063 request.Start(); | 5059 request.Start(); |
5064 base::RunLoop().Run(); | 5060 base::RunLoop().Run(); |
5065 | 5061 |
5066 // We should have set parameters from the first header, not the second. | 5062 // We should have set parameters from the first header, not the second. |
5067 TransportSecurityState* security_state = | 5063 TransportSecurityState* security_state = |
5068 default_context_.transport_security_state(); | 5064 default_context_.transport_security_state(); |
5069 bool sni_available = true; | |
5070 TransportSecurityState::DomainState domain_state; | 5065 TransportSecurityState::DomainState domain_state; |
5071 EXPECT_TRUE(security_state->GetDomainState( | 5066 EXPECT_TRUE(security_state->GetDynamicDomainState( |
5072 SpawnedTestServer::kLocalhost, sni_available, &domain_state)); | 5067 SpawnedTestServer::kLocalhost, &domain_state)); |
5073 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, | 5068 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, |
5074 domain_state.upgrade_mode); | 5069 domain_state.sts.upgrade_mode); |
5075 #if defined(OS_ANDROID) | 5070 #if defined(OS_ANDROID) |
5076 // Android's CertVerifyProc does not (yet) handle pins. | 5071 // Android's CertVerifyProc does not (yet) handle pins. |
5077 #else | 5072 #else |
5078 EXPECT_TRUE(domain_state.HasPublicKeyPins()); | 5073 EXPECT_TRUE(domain_state.HasPublicKeyPins()); |
5079 #endif | 5074 #endif |
5080 EXPECT_NE(domain_state.upgrade_expiry, | 5075 EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry); |
5081 domain_state.dynamic_spki_hashes_expiry); | |
5082 | 5076 |
5083 // Even though there is an HSTS header asserting includeSubdomains, it is | 5077 // Even though there is an HSTS header asserting includeSubdomains, it is |
5084 // the *second* such header, and we MUST process only the first. | 5078 // the *second* such header, and we MUST process only the first. |
5085 EXPECT_FALSE(domain_state.sts_include_subdomains); | 5079 EXPECT_FALSE(domain_state.sts.include_subdomains); |
5086 // includeSubdomains does not occur in the test HPKP header. | 5080 // includeSubdomains does not occur in the test HPKP header. |
5087 EXPECT_FALSE(domain_state.pkp_include_subdomains); | 5081 EXPECT_FALSE(domain_state.pkp.include_subdomains); |
5088 } | 5082 } |
5089 | 5083 |
5090 // Tests that when multiple HPKP headers are present, asserting different | 5084 // Tests that when multiple HPKP headers are present, asserting different |
5091 // policies, that only the first such policy is processed. | 5085 // policies, that only the first such policy is processed. |
5092 TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP2) { | 5086 TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP2) { |
5093 SpawnedTestServer::SSLOptions ssl_options; | 5087 SpawnedTestServer::SSLOptions ssl_options; |
5094 SpawnedTestServer https_test_server( | 5088 SpawnedTestServer https_test_server( |
5095 SpawnedTestServer::TYPE_HTTPS, | 5089 SpawnedTestServer::TYPE_HTTPS, |
5096 ssl_options, | 5090 ssl_options, |
5097 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | 5091 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
5098 ASSERT_TRUE(https_test_server.Start()); | 5092 ASSERT_TRUE(https_test_server.Start()); |
5099 | 5093 |
5100 TestDelegate d; | 5094 TestDelegate d; |
5101 URLRequest request( | 5095 URLRequest request( |
5102 https_test_server.GetURL("files/hsts-and-hpkp-headers2.html"), | 5096 https_test_server.GetURL("files/hsts-and-hpkp-headers2.html"), |
5103 DEFAULT_PRIORITY, | 5097 DEFAULT_PRIORITY, |
5104 &d, | 5098 &d, |
5105 &default_context_); | 5099 &default_context_); |
5106 request.Start(); | 5100 request.Start(); |
5107 base::RunLoop().Run(); | 5101 base::RunLoop().Run(); |
5108 | 5102 |
5109 TransportSecurityState* security_state = | 5103 TransportSecurityState* security_state = |
5110 default_context_.transport_security_state(); | 5104 default_context_.transport_security_state(); |
5111 bool sni_available = true; | |
5112 TransportSecurityState::DomainState domain_state; | 5105 TransportSecurityState::DomainState domain_state; |
5113 EXPECT_TRUE(security_state->GetDomainState( | 5106 EXPECT_TRUE(security_state->GetDynamicDomainState( |
5114 SpawnedTestServer::kLocalhost, sni_available, &domain_state)); | 5107 SpawnedTestServer::kLocalhost, &domain_state)); |
5115 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, | 5108 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, |
5116 domain_state.upgrade_mode); | 5109 domain_state.sts.upgrade_mode); |
5117 #if defined(OS_ANDROID) | 5110 #if defined(OS_ANDROID) |
5118 // Android's CertVerifyProc does not (yet) handle pins. | 5111 // Android's CertVerifyProc does not (yet) handle pins. |
5119 #else | 5112 #else |
5120 EXPECT_TRUE(domain_state.HasPublicKeyPins()); | 5113 EXPECT_TRUE(domain_state.HasPublicKeyPins()); |
5121 #endif | 5114 #endif |
5122 EXPECT_NE(domain_state.upgrade_expiry, | 5115 EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry); |
5123 domain_state.dynamic_spki_hashes_expiry); | |
5124 | 5116 |
5125 EXPECT_TRUE(domain_state.sts_include_subdomains); | 5117 EXPECT_TRUE(domain_state.sts.include_subdomains); |
5126 EXPECT_FALSE(domain_state.pkp_include_subdomains); | 5118 EXPECT_FALSE(domain_state.pkp.include_subdomains); |
5127 } | 5119 } |
5128 | 5120 |
5129 TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) { | 5121 TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) { |
5130 ASSERT_TRUE(test_server_.Start()); | 5122 ASSERT_TRUE(test_server_.Start()); |
5131 | 5123 |
5132 TestDelegate d; | 5124 TestDelegate d; |
5133 URLRequest req(test_server_.GetURL("files/content-type-normalization.html"), | 5125 URLRequest req(test_server_.GetURL("files/content-type-normalization.html"), |
5134 DEFAULT_PRIORITY, | 5126 DEFAULT_PRIORITY, |
5135 &d, | 5127 &d, |
5136 &default_context_); | 5128 &default_context_); |
(...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6637 // MockHostResolver in order to direct www.google.com to the testserver. | 6629 // MockHostResolver in order to direct www.google.com to the testserver. |
6638 // By default, MockHostResolver maps all hosts to 127.0.0.1. | 6630 // By default, MockHostResolver maps all hosts to 127.0.0.1. |
6639 | 6631 |
6640 MockHostResolver host_resolver; | 6632 MockHostResolver host_resolver; |
6641 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | 6633 TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
6642 TestURLRequestContext context(true); | 6634 TestURLRequestContext context(true); |
6643 context.set_network_delegate(&network_delegate); | 6635 context.set_network_delegate(&network_delegate); |
6644 context.set_host_resolver(&host_resolver); | 6636 context.set_host_resolver(&host_resolver); |
6645 TransportSecurityState transport_security_state; | 6637 TransportSecurityState transport_security_state; |
6646 TransportSecurityState::DomainState domain_state; | 6638 TransportSecurityState::DomainState domain_state; |
6647 EXPECT_TRUE(transport_security_state.GetDomainState("www.google.com", true, | 6639 EXPECT_TRUE(transport_security_state.GetStaticDomainState( |
6648 &domain_state)); | 6640 "www.google.com", true, &domain_state)); |
6649 context.set_transport_security_state(&transport_security_state); | 6641 context.set_transport_security_state(&transport_security_state); |
6650 context.Init(); | 6642 context.Init(); |
6651 | 6643 |
6652 TestDelegate d; | 6644 TestDelegate d; |
6653 URLRequest r(GURL(base::StringPrintf("https://www.google.com:%d", | 6645 URLRequest r(GURL(base::StringPrintf("https://www.google.com:%d", |
6654 test_server.host_port_pair().port())), | 6646 test_server.host_port_pair().port())), |
6655 DEFAULT_PRIORITY, | 6647 DEFAULT_PRIORITY, |
6656 &d, | 6648 &d, |
6657 &context); | 6649 &context); |
6658 | 6650 |
6659 r.Start(); | 6651 r.Start(); |
6660 EXPECT_TRUE(r.is_pending()); | 6652 EXPECT_TRUE(r.is_pending()); |
6661 | 6653 |
6662 base::RunLoop().Run(); | 6654 base::RunLoop().Run(); |
6663 | 6655 |
6664 EXPECT_EQ(1, d.response_started_count()); | 6656 EXPECT_EQ(1, d.response_started_count()); |
6665 EXPECT_FALSE(d.received_data_before_response()); | 6657 EXPECT_FALSE(d.received_data_before_response()); |
6666 EXPECT_TRUE(d.have_certificate_errors()); | 6658 EXPECT_TRUE(d.have_certificate_errors()); |
6667 EXPECT_TRUE(d.certificate_errors_are_fatal()); | 6659 EXPECT_TRUE(d.certificate_errors_are_fatal()); |
6668 | 6660 |
6669 // Get a fresh copy of the state, and check that it hasn't been updated. | 6661 // Get a fresh copy of the state, and check that it hasn't been updated. |
6670 TransportSecurityState::DomainState new_domain_state; | 6662 TransportSecurityState::DomainState new_static_domain_state; |
6671 EXPECT_TRUE(transport_security_state.GetDomainState("www.google.com", true, | 6663 EXPECT_TRUE(transport_security_state.GetStaticDomainState( |
6672 &new_domain_state)); | 6664 "www.google.com", true, &new_static_domain_state)); |
6673 EXPECT_EQ(new_domain_state.upgrade_mode, domain_state.upgrade_mode); | 6665 TransportSecurityState::DomainState new_dynamic_domain_state; |
6674 EXPECT_EQ(new_domain_state.sts_include_subdomains, | 6666 EXPECT_TRUE(transport_security_state.GetDynamicDomainState( |
6675 domain_state.sts_include_subdomains); | 6667 "www.google.com", &new_dynamic_domain_state)); |
6676 EXPECT_EQ(new_domain_state.pkp_include_subdomains, | 6668 |
6677 domain_state.pkp_include_subdomains); | 6669 // TODO(palmer): domain_state should be static_domain_state and |
6678 EXPECT_TRUE(FingerprintsEqual(new_domain_state.static_spki_hashes, | 6670 // dynamic_domain_state. Test that both static and dynamic are NOT |
6679 domain_state.static_spki_hashes)); | 6671 // updated. |
6680 EXPECT_TRUE(FingerprintsEqual(new_domain_state.dynamic_spki_hashes, | 6672 EXPECT_EQ(new_dynamic_domain_state.sts.upgrade_mode, |
6681 domain_state.dynamic_spki_hashes)); | 6673 domain_state.sts.upgrade_mode); |
6682 EXPECT_TRUE(FingerprintsEqual(new_domain_state.bad_static_spki_hashes, | 6674 EXPECT_EQ(new_dynamic_domain_state.sts.include_subdomains, |
6683 domain_state.bad_static_spki_hashes)); | 6675 domain_state.sts.include_subdomains); |
| 6676 EXPECT_EQ(new_dynamic_domain_state.pkp.include_subdomains, |
| 6677 domain_state.pkp.include_subdomains); |
| 6678 EXPECT_TRUE(FingerprintsEqual(new_static_domain_state.pkp.spki_hashes, |
| 6679 domain_state.pkp.spki_hashes)); |
| 6680 EXPECT_TRUE(FingerprintsEqual(new_dynamic_domain_state.pkp.spki_hashes, |
| 6681 domain_state.pkp.spki_hashes)); |
| 6682 EXPECT_TRUE(FingerprintsEqual(new_static_domain_state.pkp.bad_spki_hashes, |
| 6683 domain_state.pkp.bad_spki_hashes)); |
6684 } | 6684 } |
6685 | 6685 |
6686 // Make sure HSTS preserves a POST request's method and body. | 6686 // Make sure HSTS preserves a POST request's method and body. |
6687 TEST_F(HTTPSRequestTest, HSTSPreservesPosts) { | 6687 TEST_F(HTTPSRequestTest, HSTSPreservesPosts) { |
6688 static const char kData[] = "hello world"; | 6688 static const char kData[] = "hello world"; |
6689 | 6689 |
6690 SpawnedTestServer::SSLOptions ssl_options( | 6690 SpawnedTestServer::SSLOptions ssl_options( |
6691 SpawnedTestServer::SSLOptions::CERT_OK); | 6691 SpawnedTestServer::SSLOptions::CERT_OK); |
6692 SpawnedTestServer test_server( | 6692 SpawnedTestServer test_server( |
6693 SpawnedTestServer::TYPE_HTTPS, | 6693 SpawnedTestServer::TYPE_HTTPS, |
(...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7963 | 7963 |
7964 EXPECT_FALSE(r.is_pending()); | 7964 EXPECT_FALSE(r.is_pending()); |
7965 EXPECT_EQ(1, d->response_started_count()); | 7965 EXPECT_EQ(1, d->response_started_count()); |
7966 EXPECT_FALSE(d->received_data_before_response()); | 7966 EXPECT_FALSE(d->received_data_before_response()); |
7967 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); | 7967 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); |
7968 } | 7968 } |
7969 } | 7969 } |
7970 #endif // !defined(DISABLE_FTP_SUPPORT) | 7970 #endif // !defined(DISABLE_FTP_SUPPORT) |
7971 | 7971 |
7972 } // namespace net | 7972 } // namespace net |
OLD | NEW |