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 41408bdd5def6ce8b932d7ff1da76bf207d1c913..450439be5919c91ef5ead41e848939eebee0fc35 100644 |
--- a/net/http/http_network_transaction_unittest.cc |
+++ b/net/http/http_network_transaction_unittest.cc |
@@ -4886,4 +4886,112 @@ TEST_F(HttpNetworkTransactionTest, ResolveCanonicalName) { |
} |
} |
+struct TLSCompressionFailureSocketDataProvider : public SocketDataProvider { |
wtc
2010/04/20 21:31:07
Why is this class defined as a 'struct'?
Nit: thi
|
+ public: |
+ TLSCompressionFailureSocketDataProvider(bool fail_all) |
+ : fail_all_(fail_all) { |
+ } |
+ |
+ virtual MockRead GetNextRead() { |
+ if (fail_all_) |
+ return MockRead(false /* async */, ERR_SSL_DECOMPRESSION_FAILURE_ALERT); |
+ |
+ return MockRead(false /* async */, |
+ "HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nok.\r\n"); |
+ } |
+ |
+ virtual MockWriteResult OnWrite(const std::string& data) { |
+ return MockWriteResult(false /* async */, data.size()); |
+ } |
+ |
+ void Reset() { |
+ } |
+ |
+ private: |
+ const bool fail_all_; |
+}; |
+ |
+// Test that we restart a connection when we see a decompression failure from |
+// the peer during the handshake. (In the real world we'll restart with SSLv3 |
+// and we won't offer DEFLATE in that case.) |
+TEST_F(HttpNetworkTransactionTest, RestartAfterTLSDecompressionFailure) { |
+ HttpRequestInfo request; |
+ request.method = "GET"; |
+ request.url = GURL("https://tlsdecompressionfailure.example.com/"); |
+ request.load_flags = 0; |
+ |
+ SessionDependencies session_deps; |
+ TLSCompressionFailureSocketDataProvider socket_data_provider1( |
+ false /* fail all reads */); |
+ TLSCompressionFailureSocketDataProvider socket_data_provider2(false); |
+ SSLSocketDataProvider ssl_socket_data_provider1( |
+ false, ERR_SSL_DECOMPRESSION_FAILURE_ALERT); |
+ SSLSocketDataProvider ssl_socket_data_provider2(false, OK); |
+ session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider1); |
+ session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider2); |
+ session_deps.socket_factory.AddSSLSocketDataProvider( |
+ &ssl_socket_data_provider1); |
+ session_deps.socket_factory.AddSSLSocketDataProvider( |
+ &ssl_socket_data_provider2); |
+ |
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
+ scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); |
+ TestCompletionCallback callback; |
+ |
+ int rv = trans->Start(&request, &callback, NULL); |
+ EXPECT_EQ(ERR_IO_PENDING, rv); |
+ EXPECT_EQ(OK, callback.WaitForResult()); |
+ |
+ const HttpResponseInfo* response = trans->GetResponseInfo(); |
+ ASSERT_TRUE(response != NULL); |
+ ASSERT_TRUE(response->headers != NULL); |
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
+ |
+ std::string response_data; |
+ ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); |
+ EXPECT_EQ("ok.", response_data); |
+} |
+ |
+// Test that we restart a connection if we get a decompression failure from the |
+// peer while reading the first bytes from the connection. This occurs when the |
+// peer cannot handle DEFLATE but we're using False Start, so we don't notice |
+// in the handshake. |
+TEST_F(HttpNetworkTransactionTest, |
+ RestartAfterTLSDecompressionFailureWithFalseStart) { |
+ HttpRequestInfo request; |
+ request.method = "GET"; |
+ request.url = GURL("https://tlsdecompressionfailure2.example.com/"); |
+ request.load_flags = 0; |
+ |
+ SessionDependencies session_deps; |
+ TLSCompressionFailureSocketDataProvider socket_data_provider1( |
+ true /* fail all reads */); |
+ TLSCompressionFailureSocketDataProvider socket_data_provider2(false); |
+ SSLSocketDataProvider ssl_socket_data_provider1(false, OK); |
+ SSLSocketDataProvider ssl_socket_data_provider2(false, OK); |
+ session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider1); |
+ session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider2); |
+ session_deps.socket_factory.AddSSLSocketDataProvider( |
+ &ssl_socket_data_provider1); |
+ session_deps.socket_factory.AddSSLSocketDataProvider( |
+ &ssl_socket_data_provider2); |
+ |
+ scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
+ scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); |
+ TestCompletionCallback callback; |
+ |
+ int rv = trans->Start(&request, &callback, NULL); |
+ EXPECT_EQ(ERR_IO_PENDING, rv); |
+ EXPECT_EQ(OK, callback.WaitForResult()); |
+ |
+ const HttpResponseInfo* response = trans->GetResponseInfo(); |
+ ASSERT_TRUE(response != NULL); |
+ ASSERT_TRUE(response->headers != NULL); |
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); |
+ |
+ std::string response_data; |
+ ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); |
+ EXPECT_EQ("ok.", response_data); |
+} |
+ |
} // namespace net |