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 |