summaryrefslogtreecommitdiffstats
path: root/net/http/http_network_transaction_unittest.cc
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-20 22:05:21 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-20 22:05:21 +0000
commitaeaca1f02debae9a75c57b03d67b2c3a2e62ca38 (patch)
treeb175e8844bb3b5b692eb7fdcd8de0c1d9170e504 /net/http/http_network_transaction_unittest.cc
parent9c6d006761c3313f7fe81ff304d10a6c02400622 (diff)
downloadchromium_src-aeaca1f02debae9a75c57b03d67b2c3a2e62ca38.zip
chromium_src-aeaca1f02debae9a75c57b03d67b2c3a2e62ca38.tar.gz
chromium_src-aeaca1f02debae9a75c57b03d67b2c3a2e62ca38.tar.bz2
SSL fixes for sites with buggy DEFLATE support.
1) Keep a global set of known buggy hosts in memory. Previously we would fallback to SSLv3 with each connection. While I quite like the idea of making these buggy sites slow, it doesn't really help users and it feels silly. 2) Catch SSL decompression alerts while reading the initial data from the server and fallback so SSLv3. Since we added False Start, servers which believe that they support DEFLATE compression but fail at it are not detected as a handshake error. Rather they cause an error when reading the first byte of application level data. BUG=41591 TEST=Navigate to https://ws.sso.post.ch/ without an SSL error http://codereview.chromium.org/1585041 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45088 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http/http_network_transaction_unittest.cc')
-rw-r--r--net/http/http_network_transaction_unittest.cc108
1 files changed, 108 insertions, 0 deletions
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 41408bd..28dfa8d 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) {
}
}
+class TLSDecompressionFailureSocketDataProvider : public SocketDataProvider {
+ public:
+ TLSDecompressionFailureSocketDataProvider(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;
+ TLSDecompressionFailureSocketDataProvider socket_data_provider1(
+ false /* fail all reads */);
+ TLSDecompressionFailureSocketDataProvider 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;
+ TLSDecompressionFailureSocketDataProvider socket_data_provider1(
+ true /* fail all reads */);
+ TLSDecompressionFailureSocketDataProvider 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