Chromium Code Reviews| Index: net/http/http_network_transaction_unittest.cc | 
| diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc | 
| index efdd8f50ab141f2aa1fc681655345edcdc497498..fafca6a2dc21a6938e5e30373712a5dc676513ab 100644 | 
| --- a/net/http/http_network_transaction_unittest.cc | 
| +++ b/net/http/http_network_transaction_unittest.cc | 
| @@ -8372,4 +8372,81 @@ TEST_F(HttpNetworkTransactionTest, Direct_ClientAuthCertCache_FalseStart) { | 
| &client_cert)); | 
| } | 
| + | 
| +// Ensure that a client certificate is removed from the SSL client auth | 
| +// cache when: | 
| +// 1) An HTTPS proxy is involved. | 
| +// 3) SSL is being used through the HTTPS proxy. | 
| 
 
Ryan Hamilton
2011/01/07 17:25:50
Can you add a similar test in which the request UR
 
Ryan Sleevi
2011/01/09 08:47:33
Done. In practice it shouldn't matter, but you're
 
 | 
| +// 3) The HTTPS proxy requests a client certificate. | 
| +// 4) The client supplies an invalid/unacceptable certificate for the | 
| +// proxy. | 
| +TEST_F(HttpNetworkTransactionTest, Proxy_ClientAuthCertCache) { | 
| + SessionDependencies session_deps( | 
| + ProxyService::CreateFixed("https://proxy:70")); | 
| + CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | 
| + session_deps.net_log = log.bound().net_log(); | 
| + | 
| + // See Direct_ClientAuthCertCache_NoFalseStart for the explanation of | 
| + // [ssl_]data[1-3]. Rather than represending the endpoint | 
| + // (www.example.com:443), they represent failures with the HTTPS proxy | 
| + // (proxy:70). | 
| + SSLSocketDataProvider ssl_data1(true /* async */, | 
| + net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED); | 
| + SSLSocketDataProvider ssl_data2(true /* async */, | 
| + net::ERR_SSL_PROTOCOL_ERROR); | 
| + SSLSocketDataProvider ssl_data3(true /* async */, | 
| + net::ERR_SSL_PROTOCOL_ERROR); | 
| + scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo()); | 
| + cert_request->host_and_port = "proxy:70"; | 
| + ssl_data1.cert_request_info = cert_request.get(); | 
| + ssl_data2.cert_request_info = cert_request.get(); | 
| + ssl_data3.cert_request_info = cert_request.get(); | 
| + | 
| + // Not particularly interested in the individual reads/writes, as the | 
| + // SSL client auth cache is what is under inspection. | 
| + net::StaticSocketDataProvider data1(NULL, 0, NULL, 0); | 
| + net::StaticSocketDataProvider data2(NULL, 0, NULL, 0); | 
| + net::StaticSocketDataProvider data3(NULL, 0, NULL, 0); | 
| + | 
| + session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1); | 
| + session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2); | 
| + session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3); | 
| + session_deps.socket_factory.AddSocketDataProvider(&data1); | 
| + session_deps.socket_factory.AddSocketDataProvider(&data2); | 
| + session_deps.socket_factory.AddSocketDataProvider(&data3); | 
| + | 
| + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); | 
| + scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session)); | 
| + | 
| + net::HttpRequestInfo request_info; | 
| + request_info.url = GURL("https://www.example.com/"); | 
| + request_info.method = "GET"; | 
| + request_info.load_flags = net::LOAD_NORMAL; | 
| + | 
| + TestCompletionCallback callback; | 
| + int rv = trans->Start(&request_info, &callback, net::BoundNetLog()); | 
| + ASSERT_EQ(net::ERR_IO_PENDING, rv); | 
| + rv = callback.WaitForResult(); | 
| + ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); | 
| + | 
| + // Supply a dummy certificate. The SSLClientAuthCertCache tests ensure | 
| + // this test should behave the same as if this test used a real cert. | 
| + rv = trans->RestartWithCertificate(NULL, &callback); | 
| + ASSERT_EQ(net::ERR_IO_PENDING, rv); | 
| + | 
| + // Ensure the certificate was added to the client auth cache before | 
| + // allowing the connection to continue restarting. | 
| + scoped_refptr<X509Certificate> client_cert; | 
| + ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70", | 
| + &client_cert)); | 
| + ASSERT_EQ(NULL, client_cert.get()); | 
| + rv = callback.WaitForResult(); | 
| + | 
| + // Now that the new handshake has failed, ensure that the client | 
| + // certificate was removed from the client auth cache. | 
| + ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv); | 
| + ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70", | 
| + &client_cert)); | 
| +} | 
| + | 
| } // namespace net |