Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <math.h> // ceil | 5 #include <math.h> // ceil |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "net/base/client_socket_factory.h" | 8 #include "net/base/client_socket_factory.h" |
| 9 #include "net/base/completion_callback.h" | |
| 10 #include "net/base/ssl_client_socket.h" | |
| 11 #include "net/base/ssl_info.h" | |
| 9 #include "net/base/test_completion_callback.h" | 12 #include "net/base/test_completion_callback.h" |
| 10 #include "net/base/upload_data.h" | 13 #include "net/base/upload_data.h" |
| 11 #include "net/http/http_auth_handler_ntlm.h" | 14 #include "net/http/http_auth_handler_ntlm.h" |
| 12 #include "net/http/http_network_session.h" | 15 #include "net/http/http_network_session.h" |
| 13 #include "net/http/http_network_transaction.h" | 16 #include "net/http/http_network_transaction.h" |
| 14 #include "net/http/http_transaction_unittest.h" | 17 #include "net/http/http_transaction_unittest.h" |
| 15 #include "net/proxy/proxy_config_service_fixed.h" | 18 #include "net/proxy/proxy_config_service_fixed.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "testing/platform_test.h" | 20 #include "testing/platform_test.h" |
| 18 | 21 |
| 19 //----------------------------------------------------------------------------- | 22 //----------------------------------------------------------------------------- |
| 20 | 23 |
| 21 namespace net { | 24 namespace net { |
| 22 | 25 |
| 23 // TODO(eroman): Now that this is inside the net namespace, remove the redundant | 26 // TODO(eroman): Now that this is inside the net namespace, remove the redundant |
| 24 // net:: qualifiers. | 27 // net:: qualifiers. |
| 25 | 28 |
| 26 struct MockConnect { | 29 struct MockConnect { |
| 27 // Asynchronous connection success. | 30 // Asynchronous connection success. |
| 28 MockConnect() : async(true), result(net::OK) { } | 31 MockConnect() : async(true), result(OK) { } |
| 32 MockConnect(bool a, int r) : async(a), result(r) { } | |
|
wtc
2009/03/30 18:18:57
You may have intentionally named the constructor's
| |
| 29 | 33 |
| 30 bool async; | 34 bool async; |
| 31 int result; | 35 int result; |
| 32 }; | 36 }; |
| 33 | 37 |
| 34 struct MockRead { | 38 struct MockRead { |
| 35 // Read failure (no data). | 39 // Read failure (no data). |
| 36 MockRead(bool async, int result) : async(async) , result(result), data(NULL), | 40 MockRead(bool async, int result) : async(async) , result(result), data(NULL), |
| 37 data_len(0) { } | 41 data_len(0) { } |
| 38 | 42 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 55 }; | 59 }; |
| 56 | 60 |
| 57 // MockWrite uses the same member fields as MockRead, but with different | 61 // MockWrite uses the same member fields as MockRead, but with different |
| 58 // meanings. The expected input to MockTCPClientSocket::Write() is given | 62 // meanings. The expected input to MockTCPClientSocket::Write() is given |
| 59 // by {data, data_len}, and the return value of Write() is controlled by | 63 // by {data, data_len}, and the return value of Write() is controlled by |
| 60 // {async, result}. | 64 // {async, result}. |
| 61 typedef MockRead MockWrite; | 65 typedef MockRead MockWrite; |
| 62 | 66 |
| 63 struct MockSocket { | 67 struct MockSocket { |
| 64 MockSocket() : reads(NULL), writes(NULL) { } | 68 MockSocket() : reads(NULL), writes(NULL) { } |
| 69 MockSocket(MockRead* r, MockWrite* w) : reads(r), writes(w) { } | |
|
wtc
2009/03/30 18:18:57
Not sure if we need this constructor, but it's ok.
| |
| 65 | 70 |
| 66 MockConnect connect; | 71 MockConnect connect; |
| 67 MockRead* reads; | 72 MockRead* reads; |
| 68 MockWrite* writes; | 73 MockWrite* writes; |
| 69 }; | 74 }; |
| 70 | 75 |
| 71 // Holds an array of MockSocket elements. As MockTCPClientSocket objects get | 76 // Holds an array of MockSocket elements. As MockTCPClientSocket objects get |
| 72 // instantiated, they take their data from the i'th element of this array. | 77 // instantiated, they take their data from the i'th element of this array. |
| 73 // | 78 // |
| 74 // Tests should assign the first N entries of mock_sockets to point to valid | 79 // Tests should assign the first N entries of mock_sockets to point to valid |
| 75 // MockSocket objects. The first unused entry should be NULL'd. | 80 // MockSocket objects. The first unused entry should be NULL'd. |
| 76 // | 81 // |
| 77 MockSocket* mock_sockets[10]; | 82 MockSocket* mock_sockets[10]; |
| 78 | 83 |
| 84 // MockSSLSockets only need to keep track of the return code from calls to | |
| 85 // Connect(). | |
| 86 struct MockSSLSocket { | |
| 87 MockSSLSocket(bool async, int result) : connect(async, result) { } | |
| 88 | |
| 89 MockConnect connect; | |
| 90 }; | |
| 91 MockSSLSocket* mock_ssl_sockets[10]; | |
| 92 | |
| 79 // Index of the next mock_sockets element to use. | 93 // Index of the next mock_sockets element to use. |
| 80 int mock_sockets_index; | 94 int mock_sockets_index; |
| 95 int mock_ssl_sockets_index; | |
| 81 | 96 |
| 82 class MockTCPClientSocket : public net::ClientSocket { | 97 class MockClientSocket : public SSLClientSocket { |
| 83 public: | 98 public: |
| 84 explicit MockTCPClientSocket(const net::AddressList& addresses) | 99 explicit MockClientSocket() |
| 85 : data_(mock_sockets[mock_sockets_index++]), | 100 : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), |
| 86 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), | |
| 87 callback_(NULL), | 101 callback_(NULL), |
| 88 read_index_(0), | |
| 89 read_offset_(0), | |
| 90 write_index_(0), | |
| 91 connected_(false) { | 102 connected_(false) { |
| 92 DCHECK(data_) << "overran mock_sockets array"; | |
| 93 } | 103 } |
| 104 | |
| 94 // ClientSocket methods: | 105 // ClientSocket methods: |
| 95 virtual int Connect(net::CompletionCallback* callback) { | 106 virtual int Connect(CompletionCallback* callback) = 0; |
| 96 DCHECK(!callback_); | 107 |
| 97 if (connected_) | 108 // SSLClientSocket methods: |
| 98 return net::OK; | 109 virtual void GetSSLInfo(SSLInfo* ssl_info) { |
| 99 connected_ = true; | 110 NOTREACHED(); |
| 100 if (data_->connect.async) { | |
| 101 RunCallbackAsync(callback, data_->connect.result); | |
| 102 return net::ERR_IO_PENDING; | |
| 103 } | |
| 104 return data_->connect.result; | |
| 105 } | 111 } |
| 106 virtual int ReconnectIgnoringLastError(net::CompletionCallback* callback) { | 112 |
| 107 NOTREACHED(); | |
| 108 return net::ERR_FAILED; | |
| 109 } | |
| 110 virtual void Disconnect() { | 113 virtual void Disconnect() { |
| 111 connected_ = false; | 114 connected_ = false; |
| 112 callback_ = NULL; | 115 callback_ = NULL; |
| 113 } | 116 } |
| 114 virtual bool IsConnected() const { | 117 virtual bool IsConnected() const { |
| 115 return connected_; | 118 return connected_; |
| 116 } | 119 } |
| 117 virtual bool IsConnectedAndIdle() const { | 120 virtual bool IsConnectedAndIdle() const { |
| 118 return connected_; | 121 return connected_; |
| 119 } | 122 } |
| 120 // Socket methods: | 123 // Socket methods: |
| 121 virtual int Read(char* buf, int buf_len, net::CompletionCallback* callback) { | 124 virtual int Read(char* buf, int buf_len, |
| 125 CompletionCallback* callback) = 0; | |
| 126 virtual int Write(const char* buf, int buf_len, | |
| 127 CompletionCallback* callback) = 0; | |
| 128 | |
| 129 #if defined(OS_LINUX) | |
| 130 virtual int GetPeerName(struct sockaddr *name, socklen_t *namelen) { | |
| 131 memset(reinterpret_cast<char *>(name), 0, *namelen); | |
| 132 return OK; | |
| 133 } | |
| 134 #endif | |
| 135 | |
| 136 | |
| 137 protected: | |
| 138 void RunCallbackAsync(CompletionCallback* callback, int result) { | |
| 139 callback_ = callback; | |
| 140 MessageLoop::current()->PostTask(FROM_HERE, | |
| 141 method_factory_.NewRunnableMethod( | |
| 142 &MockClientSocket::RunCallback, result)); | |
| 143 } | |
| 144 | |
| 145 void RunCallback(int result) { | |
| 146 CompletionCallback* c = callback_; | |
| 147 callback_ = NULL; | |
| 148 if (c) | |
| 149 c->Run(result); | |
| 150 } | |
| 151 | |
| 152 ScopedRunnableMethodFactory<MockClientSocket> method_factory_; | |
| 153 CompletionCallback* callback_; | |
| 154 bool connected_; | |
| 155 }; | |
| 156 | |
| 157 class MockTCPClientSocket : public MockClientSocket { | |
| 158 public: | |
| 159 explicit MockTCPClientSocket(const AddressList& addresses) | |
| 160 : data_(mock_sockets[mock_sockets_index++]), | |
| 161 read_index_(0), | |
| 162 read_offset_(0), | |
| 163 write_index_(0) { | |
| 164 DCHECK(data_) << "overran mock_sockets array"; | |
| 165 } | |
| 166 | |
| 167 // ClientSocket methods: | |
| 168 virtual int Connect(CompletionCallback* callback) { | |
| 169 DCHECK(!callback_); | |
| 170 if (connected_) | |
| 171 return OK; | |
| 172 connected_ = true; | |
| 173 if (data_->connect.async) { | |
| 174 RunCallbackAsync(callback, data_->connect.result); | |
| 175 return ERR_IO_PENDING; | |
| 176 } | |
| 177 return data_->connect.result; | |
| 178 } | |
| 179 | |
| 180 // Socket methods: | |
| 181 virtual int Read(char* buf, int buf_len, CompletionCallback* callback) { | |
| 122 DCHECK(!callback_); | 182 DCHECK(!callback_); |
| 123 MockRead& r = data_->reads[read_index_]; | 183 MockRead& r = data_->reads[read_index_]; |
| 124 int result = r.result; | 184 int result = r.result; |
| 125 if (r.data) { | 185 if (r.data) { |
| 126 if (r.data_len - read_offset_ > 0) { | 186 if (r.data_len - read_offset_ > 0) { |
| 127 result = std::min(buf_len, r.data_len - read_offset_); | 187 result = std::min(buf_len, r.data_len - read_offset_); |
| 128 memcpy(buf, r.data + read_offset_, result); | 188 memcpy(buf, r.data + read_offset_, result); |
| 129 read_offset_ += result; | 189 read_offset_ += result; |
| 130 if (read_offset_ == r.data_len) { | 190 if (read_offset_ == r.data_len) { |
| 131 read_index_++; | 191 read_index_++; |
| 132 read_offset_ = 0; | 192 read_offset_ = 0; |
| 133 } | 193 } |
| 134 } else { | 194 } else { |
| 135 result = 0; // EOF | 195 result = 0; // EOF |
| 136 } | 196 } |
| 137 } | 197 } |
| 138 if (r.async) { | 198 if (r.async) { |
| 139 RunCallbackAsync(callback, result); | 199 RunCallbackAsync(callback, result); |
| 140 return net::ERR_IO_PENDING; | 200 return ERR_IO_PENDING; |
| 141 } | 201 } |
| 142 return result; | 202 return result; |
| 143 } | 203 } |
| 204 | |
| 144 virtual int Write(const char* buf, int buf_len, | 205 virtual int Write(const char* buf, int buf_len, |
| 145 net::CompletionCallback* callback) { | 206 CompletionCallback* callback) { |
| 146 DCHECK(buf); | 207 DCHECK(buf); |
| 147 DCHECK(buf_len > 0); | 208 DCHECK(buf_len > 0); |
| 148 DCHECK(!callback_); | 209 DCHECK(!callback_); |
| 149 // Not using mock writes; succeed synchronously. | 210 // Not using mock writes; succeed synchronously. |
| 150 if (!data_->writes) | 211 if (!data_->writes) |
| 151 return buf_len; | 212 return buf_len; |
| 152 | 213 |
| 153 // Check that what we are writing matches the expectation. | 214 // Check that what we are writing matches the expectation. |
| 154 // Then give the mocked return value. | 215 // Then give the mocked return value. |
| 155 MockWrite& w = data_->writes[write_index_++]; | 216 MockWrite& w = data_->writes[write_index_++]; |
| 156 int result = w.result; | 217 int result = w.result; |
| 157 if (w.data) { | 218 if (w.data) { |
| 158 std::string expected_data(w.data, w.data_len); | 219 std::string expected_data(w.data, w.data_len); |
| 159 std::string actual_data(buf, buf_len); | 220 std::string actual_data(buf, buf_len); |
| 160 EXPECT_EQ(expected_data, actual_data); | 221 EXPECT_EQ(expected_data, actual_data); |
| 161 if (expected_data != actual_data) | 222 if (expected_data != actual_data) |
| 162 return net::ERR_UNEXPECTED; | 223 return ERR_UNEXPECTED; |
| 163 if (result == net::OK) | 224 if (result == OK) |
| 164 result = w.data_len; | 225 result = w.data_len; |
| 165 } | 226 } |
| 166 if (w.async) { | 227 if (w.async) { |
| 167 RunCallbackAsync(callback, result); | 228 RunCallbackAsync(callback, result); |
| 168 return net::ERR_IO_PENDING; | 229 return ERR_IO_PENDING; |
| 169 } | 230 } |
| 170 return result; | 231 return result; |
| 171 } | 232 } |
| 233 | |
| 172 private: | 234 private: |
| 173 void RunCallbackAsync(net::CompletionCallback* callback, int result) { | |
| 174 callback_ = callback; | |
| 175 MessageLoop::current()->PostTask(FROM_HERE, | |
| 176 method_factory_.NewRunnableMethod( | |
| 177 &MockTCPClientSocket::RunCallback, result)); | |
| 178 } | |
| 179 void RunCallback(int result) { | |
| 180 net::CompletionCallback* c = callback_; | |
| 181 callback_ = NULL; | |
| 182 if (c) | |
| 183 c->Run(result); | |
| 184 } | |
| 185 MockSocket* data_; | 235 MockSocket* data_; |
| 186 ScopedRunnableMethodFactory<MockTCPClientSocket> method_factory_; | |
| 187 net::CompletionCallback* callback_; | |
| 188 int read_index_; | 236 int read_index_; |
| 189 int read_offset_; | 237 int read_offset_; |
| 190 int write_index_; | 238 int write_index_; |
| 191 bool connected_; | |
| 192 }; | 239 }; |
| 193 | 240 |
| 194 class MockClientSocketFactory : public net::ClientSocketFactory { | 241 class MockSSLClientSocket : public MockClientSocket { |
| 195 public: | 242 public: |
| 196 virtual net::ClientSocket* CreateTCPClientSocket( | 243 explicit MockSSLClientSocket( |
| 197 const net::AddressList& addresses) { | 244 ClientSocket* transport_socket, |
| 245 const std::string& hostname, | |
| 246 const SSLConfig& ssl_config) | |
| 247 : transport_(transport_socket), | |
| 248 data_(mock_ssl_sockets[mock_ssl_sockets_index++]) { | |
| 249 DCHECK(data_) << "overran mock_ssl_sockets array"; | |
| 250 } | |
| 251 | |
| 252 ~MockSSLClientSocket() { | |
| 253 Disconnect(); | |
| 254 } | |
| 255 | |
| 256 virtual void GetSSLInfo(SSLInfo* ssl_info) { | |
| 257 ssl_info->Reset(); | |
| 258 } | |
| 259 | |
| 260 friend class ConnectCallback; | |
| 261 class ConnectCallback : | |
| 262 public CompletionCallbackImpl<ConnectCallback> { | |
| 263 public: | |
| 264 ConnectCallback(MockSSLClientSocket *ssl_client_socket, | |
| 265 CompletionCallback* user_callback, | |
| 266 int rv) | |
| 267 : ALLOW_THIS_IN_INITIALIZER_LIST( | |
| 268 CompletionCallbackImpl<ConnectCallback>( | |
| 269 this, &ConnectCallback::Wrapper)), | |
| 270 ssl_client_socket_(ssl_client_socket), | |
| 271 user_callback_(user_callback), | |
| 272 rv_(rv) { | |
| 273 } | |
| 274 | |
| 275 private: | |
| 276 void Wrapper(int rv) { | |
| 277 if (rv_ == OK) | |
| 278 ssl_client_socket_->connected_ = true; | |
| 279 user_callback_->Run(rv_); | |
| 280 delete this; | |
| 281 } | |
| 282 | |
| 283 MockSSLClientSocket* ssl_client_socket_; | |
| 284 CompletionCallback* user_callback_; | |
| 285 int rv_; | |
| 286 }; | |
| 287 | |
| 288 virtual int Connect(CompletionCallback* callback) { | |
| 289 DCHECK(!callback_); | |
| 290 ConnectCallback* connect_callback = new ConnectCallback( | |
| 291 this, callback, data_->connect.result); | |
| 292 int rv = transport_->Connect(connect_callback); | |
| 293 if (rv == OK) { | |
| 294 delete connect_callback; | |
| 295 if (data_->connect.async) { | |
| 296 RunCallbackAsync(callback, data_->connect.result); | |
| 297 return ERR_IO_PENDING; | |
| 298 } | |
| 299 if (data_->connect.result == OK) | |
| 300 connected_ = true; | |
| 301 return data_->connect.result; | |
| 302 } | |
| 303 return rv; | |
| 304 } | |
| 305 | |
| 306 virtual void Disconnect() { | |
| 307 MockClientSocket::Disconnect(); | |
| 308 if (transport_ != NULL) | |
| 309 transport_->Disconnect(); | |
| 310 } | |
| 311 | |
| 312 // Socket methods: | |
| 313 virtual int Read(char* buf, int buf_len, CompletionCallback* callback) { | |
| 314 DCHECK(!callback_); | |
| 315 return transport_->Read(buf, buf_len, callback); | |
| 316 } | |
| 317 | |
| 318 virtual int Write(const char* buf, int buf_len, | |
| 319 CompletionCallback* callback) { | |
| 320 DCHECK(!callback_); | |
| 321 return transport_->Write(buf, buf_len, callback); | |
| 322 } | |
| 323 | |
| 324 private: | |
| 325 scoped_ptr<ClientSocket> transport_; | |
| 326 MockSSLSocket* data_; | |
| 327 }; | |
| 328 | |
| 329 class MockClientSocketFactory : public ClientSocketFactory { | |
| 330 public: | |
| 331 virtual ClientSocket* CreateTCPClientSocket( | |
| 332 const AddressList& addresses) { | |
| 198 return new MockTCPClientSocket(addresses); | 333 return new MockTCPClientSocket(addresses); |
| 199 } | 334 } |
| 200 virtual net::SSLClientSocket* CreateSSLClientSocket( | 335 virtual SSLClientSocket* CreateSSLClientSocket( |
| 201 net::ClientSocket* transport_socket, | 336 ClientSocket* transport_socket, |
| 202 const std::string& hostname, | 337 const std::string& hostname, |
| 203 const net::SSLConfig& ssl_config) { | 338 const SSLConfig& ssl_config) { |
| 204 return NULL; | 339 return new MockSSLClientSocket(transport_socket, hostname, ssl_config); |
| 205 } | 340 } |
| 206 }; | 341 }; |
| 207 | 342 |
| 208 MockClientSocketFactory mock_socket_factory; | 343 MockClientSocketFactory mock_socket_factory; |
| 209 | 344 |
| 210 // Create a proxy service which fails on all requests (falls back to direct). | 345 // Create a proxy service which fails on all requests (falls back to direct). |
| 211 net::ProxyService* CreateNullProxyService() { | 346 net::ProxyService* CreateNullProxyService() { |
| 212 return net::ProxyService::CreateNull(); | 347 return net::ProxyService::CreateNull(); |
| 213 } | 348 } |
| 214 | 349 |
| 215 net::ProxyService* CreateFixedProxyService(const std::string& proxy) { | 350 net::ProxyService* CreateFixedProxyService(const std::string& proxy) { |
| 216 net::ProxyInfo proxy_info; | 351 net::ProxyInfo proxy_info; |
| 217 proxy_info.UseNamedProxy(proxy); | 352 proxy_info.UseNamedProxy(proxy); |
| 218 return net::ProxyService::Create(&proxy_info); | 353 return net::ProxyService::Create(&proxy_info); |
| 219 } | 354 } |
| 220 | 355 |
| 221 | 356 |
| 222 net::HttpNetworkSession* CreateSession(net::ProxyService* proxy_service) { | 357 net::HttpNetworkSession* CreateSession(net::ProxyService* proxy_service) { |
| 223 return new net::HttpNetworkSession(proxy_service); | 358 return new net::HttpNetworkSession(proxy_service); |
| 224 } | 359 } |
| 225 | 360 |
| 226 class HttpNetworkTransactionTest : public PlatformTest { | 361 class HttpNetworkTransactionTest : public PlatformTest { |
| 227 public: | 362 public: |
| 228 virtual void SetUp() { | 363 virtual void SetUp() { |
| 229 PlatformTest::SetUp(); | 364 PlatformTest::SetUp(); |
| 230 mock_sockets[0] = NULL; | 365 mock_sockets[0] = NULL; |
| 231 mock_sockets_index = 0; | 366 mock_sockets_index = 0; |
| 367 mock_ssl_sockets_index = 0; | |
| 232 } | 368 } |
| 233 | 369 |
| 234 virtual void TearDown() { | 370 virtual void TearDown() { |
| 235 // Empty the current queue. | 371 // Empty the current queue. |
| 236 MessageLoop::current()->RunAllPending(); | 372 MessageLoop::current()->RunAllPending(); |
| 237 PlatformTest::TearDown(); | 373 PlatformTest::TearDown(); |
| 238 } | 374 } |
| 239 | 375 |
| 240 protected: | 376 protected: |
| 241 void KeepAliveConnectionResendRequestTest(const MockRead& read_failure); | 377 void KeepAliveConnectionResendRequestTest(const MockRead& read_failure); |
| (...skipping 2462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2704 EXPECT_EQ(0U, trans->request_headers_bytes_sent_); | 2840 EXPECT_EQ(0U, trans->request_headers_bytes_sent_); |
| 2705 EXPECT_EQ(NULL, trans->response_.auth_challenge.get()); | 2841 EXPECT_EQ(NULL, trans->response_.auth_challenge.get()); |
| 2706 EXPECT_EQ(NULL, trans->response_.headers.get()); | 2842 EXPECT_EQ(NULL, trans->response_.headers.get()); |
| 2707 EXPECT_EQ(false, trans->response_.was_cached); | 2843 EXPECT_EQ(false, trans->response_.was_cached); |
| 2708 EXPECT_EQ(base::kInvalidPlatformFileValue, | 2844 EXPECT_EQ(base::kInvalidPlatformFileValue, |
| 2709 trans->response_.response_data_file); | 2845 trans->response_.response_data_file); |
| 2710 EXPECT_EQ(0, trans->response_.ssl_info.cert_status); | 2846 EXPECT_EQ(0, trans->response_.ssl_info.cert_status); |
| 2711 EXPECT_FALSE(trans->response_.vary_data.is_valid()); | 2847 EXPECT_FALSE(trans->response_.vary_data.is_valid()); |
| 2712 } | 2848 } |
| 2713 | 2849 |
| 2850 // Test HTTPS connections to a site with a bad certificate | |
| 2851 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) { | |
| 2852 scoped_ptr<ProxyService> proxy_service(CreateNullProxyService()); | |
| 2853 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( | |
| 2854 CreateSession(proxy_service.get()), &mock_socket_factory)); | |
| 2855 | |
| 2856 HttpRequestInfo request; | |
| 2857 request.method = "GET"; | |
| 2858 request.url = GURL("https://www.google.com/"); | |
| 2859 request.load_flags = 0; | |
| 2860 | |
| 2861 MockWrite data_writes[] = { | |
| 2862 MockWrite("GET / HTTP/1.1\r\n" | |
| 2863 "Host: www.google.com\r\n" | |
| 2864 "Connection: keep-alive\r\n\r\n"), | |
| 2865 }; | |
| 2866 | |
| 2867 MockRead data_reads[] = { | |
| 2868 MockRead("HTTP/1.0 200 OK\r\n"), | |
| 2869 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | |
| 2870 MockRead("Content-Length: 100\r\n\r\n"), | |
| 2871 MockRead(false, OK), | |
| 2872 }; | |
| 2873 | |
| 2874 MockSocket ssl_bad_certificate; | |
| 2875 MockSocket data(data_reads, data_writes); | |
| 2876 MockSSLSocket ssl_bad(true, ERR_CERT_AUTHORITY_INVALID); | |
| 2877 MockSSLSocket ssl(true, OK); | |
| 2878 | |
| 2879 mock_sockets[0] = &ssl_bad_certificate; | |
| 2880 mock_sockets[1] = &data; | |
| 2881 mock_sockets[2] = NULL; | |
| 2882 | |
| 2883 mock_ssl_sockets[0] = &ssl_bad; | |
| 2884 mock_ssl_sockets[1] = &ssl; | |
| 2885 mock_ssl_sockets[2] = NULL; | |
| 2886 | |
| 2887 TestCompletionCallback callback; | |
| 2888 | |
| 2889 int rv = trans->Start(&request, &callback); | |
| 2890 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 2891 | |
| 2892 rv = callback.WaitForResult(); | |
| 2893 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); | |
| 2894 | |
| 2895 rv = trans->RestartIgnoringLastError(&callback); | |
| 2896 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 2897 | |
| 2898 rv = callback.WaitForResult(); | |
| 2899 EXPECT_EQ(OK, rv); | |
| 2900 | |
| 2901 const HttpResponseInfo* response = trans->GetResponseInfo(); | |
| 2902 | |
| 2903 EXPECT_FALSE(response == NULL); | |
| 2904 EXPECT_EQ(100, response->headers->GetContentLength()); | |
| 2905 } | |
| 2906 | |
| 2907 // Test HTTPS connections to a site with a bad certificate, going through a | |
| 2908 // proxy | |
| 2909 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) { | |
| 2910 scoped_ptr<ProxyService> proxy_service( | |
| 2911 CreateFixedProxyService("myproxy:70")); | |
| 2912 | |
| 2913 HttpRequestInfo request; | |
| 2914 request.method = "GET"; | |
| 2915 request.url = GURL("https://www.google.com/"); | |
| 2916 request.load_flags = 0; | |
| 2917 | |
| 2918 MockWrite proxy_writes[] = { | |
| 2919 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" | |
| 2920 "Host: www.google.com\r\n\r\n"), | |
| 2921 }; | |
| 2922 | |
| 2923 MockRead proxy_reads[] = { | |
| 2924 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), | |
| 2925 MockRead(false, net::OK) | |
| 2926 }; | |
| 2927 | |
| 2928 MockWrite data_writes[] = { | |
| 2929 MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n" | |
| 2930 "Host: www.google.com\r\n\r\n"), | |
| 2931 MockWrite("GET / HTTP/1.1\r\n" | |
| 2932 "Host: www.google.com\r\n" | |
| 2933 "Connection: keep-alive\r\n\r\n"), | |
| 2934 }; | |
| 2935 | |
| 2936 MockRead data_reads[] = { | |
| 2937 MockRead("HTTP/1.0 200 Connected\r\n\r\n"), | |
| 2938 MockRead("HTTP/1.0 200 OK\r\n"), | |
| 2939 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"), | |
| 2940 MockRead("Content-Length: 100\r\n\r\n"), | |
| 2941 MockRead(false, OK), | |
| 2942 }; | |
| 2943 | |
| 2944 MockSocket ssl_bad_certificate(proxy_reads, proxy_writes); | |
| 2945 MockSocket data(data_reads, data_writes); | |
| 2946 MockSSLSocket ssl_bad(true, ERR_CERT_AUTHORITY_INVALID); | |
| 2947 MockSSLSocket ssl(true, OK); | |
| 2948 | |
| 2949 mock_sockets[0] = &ssl_bad_certificate; | |
|
wtc
2009/03/30 18:18:57
It's a little confusing for a socket to be named "
| |
| 2950 mock_sockets[1] = &data; | |
| 2951 mock_sockets[2] = NULL; | |
| 2952 | |
| 2953 mock_ssl_sockets[0] = &ssl_bad; | |
| 2954 mock_ssl_sockets[1] = &ssl; | |
| 2955 mock_ssl_sockets[2] = NULL; | |
| 2956 | |
| 2957 TestCompletionCallback callback; | |
| 2958 | |
| 2959 for (int i = 0; i < 2; i++) { | |
| 2960 mock_sockets_index = 0; | |
| 2961 mock_ssl_sockets_index = 0; | |
| 2962 | |
| 2963 scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( | |
| 2964 CreateSession(proxy_service.get()), &mock_socket_factory)); | |
| 2965 | |
| 2966 int rv = trans->Start(&request, &callback); | |
| 2967 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 2968 | |
| 2969 rv = callback.WaitForResult(); | |
| 2970 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv); | |
| 2971 | |
| 2972 rv = trans->RestartIgnoringLastError(&callback); | |
| 2973 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 2974 | |
| 2975 rv = callback.WaitForResult(); | |
| 2976 EXPECT_EQ(OK, rv); | |
| 2977 | |
| 2978 const HttpResponseInfo* response = trans->GetResponseInfo(); | |
| 2979 | |
| 2980 EXPECT_FALSE(response == NULL); | |
| 2981 EXPECT_EQ(100, response->headers->GetContentLength()); | |
| 2982 } | |
| 2983 } | |
| 2984 | |
| 2714 } // namespace net | 2985 } // namespace net |
| OLD | NEW |