Chromium Code Reviews| 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 "net/socket/ssl_client_socket.h" | 5 #include "net/socket/ssl_client_socket.h" |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
| 8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
| 9 #include "net/base/address_list.h" | 9 #include "net/base/address_list.h" |
| 10 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
| (...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1163 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | 1163 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
| 1164 #else | 1164 #else |
| 1165 // OpenSSL treats any errors as a simple EOF. | 1165 // OpenSSL treats any errors as a simple EOF. |
| 1166 EXPECT_EQ(0, rv); | 1166 EXPECT_EQ(0, rv); |
| 1167 #endif | 1167 #endif |
| 1168 | 1168 |
| 1169 // The Write callback should not have been called. | 1169 // The Write callback should not have been called. |
| 1170 EXPECT_FALSE(callback.have_result()); | 1170 EXPECT_FALSE(callback.have_result()); |
| 1171 } | 1171 } |
| 1172 | 1172 |
| 1173 // Tests that the SSLClientSocket does not crash if data is received on the | |
| 1174 // transport socket after a failing write. This can occur if we have a Write | |
| 1175 // error in a SPDY socket. | |
| 1176 // Regression test for http://crbug.com/335557 | |
| 1177 TEST_F(SSLClientSocketTest, Read_WithWriteError) { | |
| 1178 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
| 1179 SpawnedTestServer::kLocalhost, | |
| 1180 base::FilePath()); | |
| 1181 ASSERT_TRUE(test_server.Start()); | |
| 1182 | |
| 1183 AddressList addr; | |
| 1184 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
| 1185 | |
| 1186 TestCompletionCallback callback; | |
| 1187 scoped_ptr<StreamSocket> real_transport( | |
| 1188 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
| 1189 // Note: |error_socket|'s ownership is handed to |transport|, but a pointer | |
| 1190 // is retained in order to configure additional errors. | |
| 1191 scoped_ptr<SynchronousErrorStreamSocket> error_socket( | |
| 1192 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
| 1193 SynchronousErrorStreamSocket* raw_error_socket = error_socket.get(); | |
| 1194 scoped_ptr<FakeBlockingStreamSocket> transport( | |
| 1195 new FakeBlockingStreamSocket(error_socket.PassAs<StreamSocket>())); | |
| 1196 FakeBlockingStreamSocket* raw_transport = transport.get(); | |
| 1197 | |
| 1198 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
| 1199 EXPECT_EQ(OK, rv); | |
| 1200 | |
| 1201 // Disable TLS False Start to avoid handshake non-determinism. | |
| 1202 SSLConfig ssl_config; | |
| 1203 ssl_config.false_start_enabled = false; | |
| 1204 | |
| 1205 scoped_ptr<SSLClientSocket> sock( | |
| 1206 CreateSSLClientSocket(transport.PassAs<StreamSocket>(), | |
| 1207 test_server.host_port_pair(), | |
| 1208 ssl_config)); | |
| 1209 | |
| 1210 rv = callback.GetResult(sock->Connect(callback.callback())); | |
| 1211 EXPECT_EQ(OK, rv); | |
| 1212 EXPECT_TRUE(sock->IsConnected()); | |
| 1213 | |
| 1214 // Send a request so there is something to read from the socket. | |
| 1215 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | |
| 1216 static const int kRequestTextSize = | |
| 1217 static_cast<int>(arraysize(request_text) - 1); | |
| 1218 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize)); | |
| 1219 memcpy(request_buffer->data(), request_text, kRequestTextSize); | |
| 1220 | |
| 1221 rv = callback.GetResult( | |
| 1222 sock->Write(request_buffer.get(), kRequestTextSize, callback.callback())); | |
| 1223 EXPECT_EQ(kRequestTextSize, rv); | |
| 1224 | |
| 1225 // Start a hanging read. | |
| 1226 TestCompletionCallback read_callback; | |
| 1227 raw_transport->SetNextReadShouldBlock(); | |
| 1228 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | |
| 1229 rv = sock->Read(buf.get(), 4096, read_callback.callback()); | |
| 1230 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 1231 | |
| 1232 // Perform another write, but have it fail. This time use a very long request | |
| 1233 // to exceed internal buffers and flush out the socket error. | |
|
Ryan Sleevi
2014/02/05 19:07:40
Rather than "flush out the socket error" (which to
davidben
2014/02/05 20:34:41
Done.
| |
| 1234 std::string long_request_text = | |
| 1235 "GET / HTTP/1.1\r\nUser-Agent: long browser name "; | |
| 1236 long_request_text.append(20 * 1024, '*'); | |
| 1237 long_request_text.append("\r\n\r\n"); | |
| 1238 scoped_refptr<DrainableIOBuffer> long_request_buffer(new DrainableIOBuffer( | |
| 1239 new StringIOBuffer(long_request_text), long_request_text.size())); | |
| 1240 | |
| 1241 raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET); | |
| 1242 | |
| 1243 // Write as much data as possible until hitting an error. This is necessary | |
| 1244 // for NSS. PR_Write will only consume as much data as it can encode into | |
| 1245 // application data records before the internal memio buffer is full, which | |
| 1246 // should only fill if writing a large amount of data and the underlying | |
| 1247 // transport is blocked. Once this happens, NSS will return (total size of all | |
| 1248 // application data records it wrote) - 1, with the caller expected to resume | |
| 1249 // with the remaining unsent data. | |
| 1250 do { | |
| 1251 rv = callback.GetResult(sock->Write(long_request_buffer.get(), | |
| 1252 long_request_buffer->BytesRemaining(), | |
| 1253 callback.callback())); | |
| 1254 if (rv > 0) { | |
| 1255 long_request_buffer->DidConsume(rv); | |
| 1256 // Abort if the entire buffer is ever consumed. | |
| 1257 ASSERT_LT(0, long_request_buffer->BytesRemaining()); | |
| 1258 } | |
| 1259 } while (rv > 0); | |
| 1260 | |
| 1261 #if !defined(USE_OPENSSL) | |
| 1262 // NSS records the error exactly. | |
| 1263 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | |
| 1264 #else | |
| 1265 // OpenSSL treats the reset as a generic protocol error. | |
| 1266 EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv); | |
| 1267 #endif | |
| 1268 | |
| 1269 // Release the read. Some bytes should go through. | |
| 1270 raw_transport->UnblockRead(); | |
| 1271 rv = read_callback.WaitForResult(); | |
| 1272 | |
| 1273 // Per the fix for http://crbug.com/249848, write failures currently break | |
| 1274 // reads. Change this assertion if they're changed to not collide. | |
| 1275 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | |
| 1276 } | |
| 1277 | |
| 1173 TEST_F(SSLClientSocketTest, Read_SmallChunks) { | 1278 TEST_F(SSLClientSocketTest, Read_SmallChunks) { |
| 1174 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 1279 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
| 1175 SpawnedTestServer::kLocalhost, | 1280 SpawnedTestServer::kLocalhost, |
| 1176 base::FilePath()); | 1281 base::FilePath()); |
| 1177 ASSERT_TRUE(test_server.Start()); | 1282 ASSERT_TRUE(test_server.Start()); |
| 1178 | 1283 |
| 1179 AddressList addr; | 1284 AddressList addr; |
| 1180 ASSERT_TRUE(test_server.GetAddressList(&addr)); | 1285 ASSERT_TRUE(test_server.GetAddressList(&addr)); |
| 1181 | 1286 |
| 1182 TestCompletionCallback callback; | 1287 TestCompletionCallback callback; |
| (...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1946 log.GetEntries(&entries); | 2051 log.GetEntries(&entries); |
| 1947 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); | 2052 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); |
| 1948 | 2053 |
| 1949 EXPECT_FALSE(sock->signed_cert_timestamps_received_); | 2054 EXPECT_FALSE(sock->signed_cert_timestamps_received_); |
| 1950 | 2055 |
| 1951 sock->Disconnect(); | 2056 sock->Disconnect(); |
| 1952 EXPECT_FALSE(sock->IsConnected()); | 2057 EXPECT_FALSE(sock->IsConnected()); |
| 1953 } | 2058 } |
| 1954 | 2059 |
| 1955 } // namespace net | 2060 } // namespace net |
| OLD | NEW |