OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/url_request/url_request_ftp_job.h" | |
6 | |
7 #include "base/memory/ref_counted.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/memory/scoped_vector.h" | |
10 #include "base/run_loop.h" | |
11 #include "net/base/host_port_pair.h" | |
12 #include "net/base/request_priority.h" | |
13 #include "net/ftp/ftp_auth_cache.h" | |
14 #include "net/http/http_transaction_test_util.h" | |
15 #include "net/proxy/mock_proxy_resolver.h" | |
16 #include "net/proxy/proxy_config_service.h" | |
17 #include "net/proxy/proxy_config_service_fixed.h" | |
18 #include "net/socket/socket_test_util.h" | |
19 #include "net/url_request/ftp_protocol_handler.h" | |
20 #include "net/url_request/url_request.h" | |
21 #include "net/url_request/url_request_context.h" | |
22 #include "net/url_request/url_request_job_factory_impl.h" | |
23 #include "net/url_request/url_request_status.h" | |
24 #include "net/url_request/url_request_test_util.h" | |
25 #include "testing/gtest/include/gtest/gtest.h" | |
26 #include "url/gurl.h" | |
27 | |
28 using base::ASCIIToUTF16; | |
29 | |
30 namespace net { | |
31 | |
32 class FtpTestURLRequestContext : public TestURLRequestContext { | |
33 public: | |
34 FtpTestURLRequestContext(ClientSocketFactory* socket_factory, | |
35 ProxyService* proxy_service, | |
36 NetworkDelegate* network_delegate, | |
37 FtpTransactionFactory* ftp_transaction_factory) | |
38 : TestURLRequestContext(true), | |
39 ftp_protocol_handler_(new FtpProtocolHandler(ftp_transaction_factory)) { | |
40 set_client_socket_factory(socket_factory); | |
41 context_storage_.set_proxy_service(proxy_service); | |
42 set_network_delegate(network_delegate); | |
43 URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl; | |
44 job_factory->SetProtocolHandler("ftp", ftp_protocol_handler_); | |
45 context_storage_.set_job_factory(job_factory); | |
46 Init(); | |
47 } | |
48 | |
49 FtpAuthCache* GetFtpAuthCache() { | |
50 return ftp_protocol_handler_->ftp_auth_cache_.get(); | |
51 } | |
52 | |
53 void set_proxy_service(ProxyService* proxy_service) { | |
54 context_storage_.set_proxy_service(proxy_service); | |
55 } | |
56 | |
57 private: | |
58 FtpProtocolHandler* ftp_protocol_handler_; | |
59 }; | |
60 | |
61 namespace { | |
62 | |
63 class SimpleProxyConfigService : public ProxyConfigService { | |
64 public: | |
65 SimpleProxyConfigService() { | |
66 // Any FTP requests that ever go through HTTP paths are proxied requests. | |
67 config_.proxy_rules().ParseFromString("ftp=localhost"); | |
68 } | |
69 | |
70 void AddObserver(Observer* observer) override { observer_ = observer; } | |
71 | |
72 void RemoveObserver(Observer* observer) override { | |
73 if (observer_ == observer) { | |
74 observer_ = NULL; | |
75 } | |
76 } | |
77 | |
78 ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) override { | |
79 *config = config_; | |
80 return CONFIG_VALID; | |
81 } | |
82 | |
83 void IncrementConfigId() { | |
84 config_.set_id(config_.id() + 1); | |
85 observer_->OnProxyConfigChanged(config_, ProxyConfigService::CONFIG_VALID); | |
86 } | |
87 | |
88 private: | |
89 ProxyConfig config_; | |
90 Observer* observer_; | |
91 }; | |
92 | |
93 // Inherit from URLRequestFtpJob to expose the priority and some | |
94 // other hidden functions. | |
95 class TestURLRequestFtpJob : public URLRequestFtpJob { | |
96 public: | |
97 TestURLRequestFtpJob(URLRequest* request, | |
98 FtpTransactionFactory* ftp_factory, | |
99 FtpAuthCache* ftp_auth_cache) | |
100 : URLRequestFtpJob(request, NULL, ftp_factory, ftp_auth_cache) {} | |
101 | |
102 using URLRequestFtpJob::SetPriority; | |
103 using URLRequestFtpJob::Start; | |
104 using URLRequestFtpJob::Kill; | |
105 using URLRequestFtpJob::priority; | |
106 | |
107 protected: | |
108 ~TestURLRequestFtpJob() override {} | |
109 }; | |
110 | |
111 class MockFtpTransactionFactory : public FtpTransactionFactory { | |
112 public: | |
113 FtpTransaction* CreateTransaction() override { return NULL; } | |
114 | |
115 void Suspend(bool suspend) override {} | |
116 }; | |
117 | |
118 // Fixture for priority-related tests. Priority matters when there is | |
119 // an HTTP proxy. | |
120 class URLRequestFtpJobPriorityTest : public testing::Test { | |
121 protected: | |
122 URLRequestFtpJobPriorityTest() | |
123 : proxy_service_(new SimpleProxyConfigService, NULL, NULL), | |
124 req_(context_.CreateRequest(GURL("ftp://ftp.example.com"), | |
125 DEFAULT_PRIORITY, | |
126 &delegate_, | |
127 NULL)) { | |
128 context_.set_proxy_service(&proxy_service_); | |
129 context_.set_http_transaction_factory(&network_layer_); | |
130 } | |
131 | |
132 ProxyService proxy_service_; | |
133 MockNetworkLayer network_layer_; | |
134 MockFtpTransactionFactory ftp_factory_; | |
135 FtpAuthCache ftp_auth_cache_; | |
136 TestURLRequestContext context_; | |
137 TestDelegate delegate_; | |
138 scoped_ptr<URLRequest> req_; | |
139 }; | |
140 | |
141 // Make sure that SetPriority actually sets the URLRequestFtpJob's | |
142 // priority, both before and after start. | |
143 TEST_F(URLRequestFtpJobPriorityTest, SetPriorityBasic) { | |
144 scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob( | |
145 req_.get(), &ftp_factory_, &ftp_auth_cache_)); | |
146 EXPECT_EQ(DEFAULT_PRIORITY, job->priority()); | |
147 | |
148 job->SetPriority(LOWEST); | |
149 EXPECT_EQ(LOWEST, job->priority()); | |
150 | |
151 job->SetPriority(LOW); | |
152 EXPECT_EQ(LOW, job->priority()); | |
153 | |
154 job->Start(); | |
155 EXPECT_EQ(LOW, job->priority()); | |
156 | |
157 job->SetPriority(MEDIUM); | |
158 EXPECT_EQ(MEDIUM, job->priority()); | |
159 } | |
160 | |
161 // Make sure that URLRequestFtpJob passes on its priority to its | |
162 // transaction on start. | |
163 TEST_F(URLRequestFtpJobPriorityTest, SetTransactionPriorityOnStart) { | |
164 scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob( | |
165 req_.get(), &ftp_factory_, &ftp_auth_cache_)); | |
166 job->SetPriority(LOW); | |
167 | |
168 EXPECT_FALSE(network_layer_.last_transaction()); | |
169 | |
170 job->Start(); | |
171 | |
172 ASSERT_TRUE(network_layer_.last_transaction()); | |
173 EXPECT_EQ(LOW, network_layer_.last_transaction()->priority()); | |
174 } | |
175 | |
176 // Make sure that URLRequestFtpJob passes on its priority updates to | |
177 // its transaction. | |
178 TEST_F(URLRequestFtpJobPriorityTest, SetTransactionPriority) { | |
179 scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob( | |
180 req_.get(), &ftp_factory_, &ftp_auth_cache_)); | |
181 job->SetPriority(LOW); | |
182 job->Start(); | |
183 ASSERT_TRUE(network_layer_.last_transaction()); | |
184 EXPECT_EQ(LOW, network_layer_.last_transaction()->priority()); | |
185 | |
186 job->SetPriority(HIGHEST); | |
187 EXPECT_EQ(HIGHEST, network_layer_.last_transaction()->priority()); | |
188 } | |
189 | |
190 // Make sure that URLRequestFtpJob passes on its priority updates to | |
191 // newly-created transactions after the first one. | |
192 TEST_F(URLRequestFtpJobPriorityTest, SetSubsequentTransactionPriority) { | |
193 scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob( | |
194 req_.get(), &ftp_factory_, &ftp_auth_cache_)); | |
195 job->Start(); | |
196 | |
197 job->SetPriority(LOW); | |
198 ASSERT_TRUE(network_layer_.last_transaction()); | |
199 EXPECT_EQ(LOW, network_layer_.last_transaction()->priority()); | |
200 | |
201 job->Kill(); | |
202 network_layer_.ClearLastTransaction(); | |
203 | |
204 // Creates a second transaction. | |
205 job->Start(); | |
206 ASSERT_TRUE(network_layer_.last_transaction()); | |
207 EXPECT_EQ(LOW, network_layer_.last_transaction()->priority()); | |
208 } | |
209 | |
210 class URLRequestFtpJobTest : public testing::Test { | |
211 public: | |
212 URLRequestFtpJobTest() | |
213 : request_context_(&socket_factory_, | |
214 new ProxyService( | |
215 new SimpleProxyConfigService, NULL, NULL), | |
216 &network_delegate_, | |
217 &ftp_transaction_factory_) { | |
218 } | |
219 | |
220 ~URLRequestFtpJobTest() override { | |
221 // Clean up any remaining tasks that mess up unrelated tests. | |
222 base::RunLoop run_loop; | |
223 run_loop.RunUntilIdle(); | |
224 } | |
225 | |
226 void AddSocket(MockRead* reads, size_t reads_size, | |
227 MockWrite* writes, size_t writes_size) { | |
228 DeterministicSocketData* socket_data = new DeterministicSocketData( | |
229 reads, reads_size, writes, writes_size); | |
230 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK)); | |
231 socket_data->StopAfter(reads_size + writes_size - 1); | |
232 socket_factory_.AddSocketDataProvider(socket_data); | |
233 | |
234 socket_data_.push_back(socket_data); | |
235 } | |
236 | |
237 FtpTestURLRequestContext* request_context() { return &request_context_; } | |
238 TestNetworkDelegate* network_delegate() { return &network_delegate_; } | |
239 DeterministicSocketData* socket_data(size_t index) { | |
240 return socket_data_[index]; | |
241 } | |
242 | |
243 private: | |
244 ScopedVector<DeterministicSocketData> socket_data_; | |
245 DeterministicMockClientSocketFactory socket_factory_; | |
246 TestNetworkDelegate network_delegate_; | |
247 MockFtpTransactionFactory ftp_transaction_factory_; | |
248 | |
249 FtpTestURLRequestContext request_context_; | |
250 }; | |
251 | |
252 TEST_F(URLRequestFtpJobTest, FtpProxyRequest) { | |
253 MockWrite writes[] = { | |
254 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
255 "Host: ftp.example.com\r\n" | |
256 "Proxy-Connection: keep-alive\r\n\r\n"), | |
257 }; | |
258 MockRead reads[] = { | |
259 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"), | |
260 MockRead(ASYNC, 2, "Content-Length: 9\r\n\r\n"), | |
261 MockRead(ASYNC, 3, "test.html"), | |
262 }; | |
263 | |
264 AddSocket(reads, arraysize(reads), writes, arraysize(writes)); | |
265 | |
266 TestDelegate request_delegate; | |
267 scoped_ptr<URLRequest> url_request(request_context()->CreateRequest( | |
268 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY, | |
269 &request_delegate, NULL)); | |
270 url_request->Start(); | |
271 ASSERT_TRUE(url_request->is_pending()); | |
272 socket_data(0)->RunFor(4); | |
273 | |
274 EXPECT_TRUE(url_request->status().is_success()); | |
275 EXPECT_TRUE(url_request->proxy_server().Equals( | |
276 net::HostPortPair::FromString("localhost:80"))); | |
277 EXPECT_EQ(1, network_delegate()->completed_requests()); | |
278 EXPECT_EQ(0, network_delegate()->error_count()); | |
279 EXPECT_FALSE(request_delegate.auth_required_called()); | |
280 EXPECT_EQ("test.html", request_delegate.data_received()); | |
281 } | |
282 | |
283 // Regression test for http://crbug.com/237526 . | |
284 TEST_F(URLRequestFtpJobTest, FtpProxyRequestOrphanJob) { | |
285 // Use a PAC URL so that URLRequestFtpJob's |pac_request_| field is non-NULL. | |
286 request_context()->set_proxy_service( | |
287 new ProxyService( | |
288 new ProxyConfigServiceFixed( | |
289 ProxyConfig::CreateFromCustomPacURL(GURL("http://foo"))), | |
290 new MockAsyncProxyResolver, NULL)); | |
291 | |
292 TestDelegate request_delegate; | |
293 scoped_ptr<URLRequest> url_request(request_context()->CreateRequest( | |
294 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY, &request_delegate, | |
295 NULL)); | |
296 url_request->Start(); | |
297 | |
298 // Now |url_request| will be deleted before its completion, | |
299 // resulting in it being orphaned. It should not crash. | |
300 } | |
301 | |
302 TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedProxyAuthNoCredentials) { | |
303 MockWrite writes[] = { | |
304 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
305 "Host: ftp.example.com\r\n" | |
306 "Proxy-Connection: keep-alive\r\n\r\n"), | |
307 }; | |
308 MockRead reads[] = { | |
309 // No credentials. | |
310 MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"), | |
311 MockRead(ASYNC, 2, "Proxy-Authenticate: Basic " | |
312 "realm=\"MyRealm1\"\r\n"), | |
313 MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"), | |
314 MockRead(ASYNC, 4, "test.html"), | |
315 }; | |
316 | |
317 AddSocket(reads, arraysize(reads), writes, arraysize(writes)); | |
318 | |
319 TestDelegate request_delegate; | |
320 scoped_ptr<URLRequest> url_request(request_context()->CreateRequest( | |
321 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY, &request_delegate, | |
322 NULL)); | |
323 url_request->Start(); | |
324 ASSERT_TRUE(url_request->is_pending()); | |
325 socket_data(0)->RunFor(5); | |
326 | |
327 EXPECT_TRUE(url_request->status().is_success()); | |
328 EXPECT_TRUE(url_request->proxy_server().Equals( | |
329 net::HostPortPair::FromString("localhost:80"))); | |
330 EXPECT_EQ(1, network_delegate()->completed_requests()); | |
331 EXPECT_EQ(0, network_delegate()->error_count()); | |
332 EXPECT_TRUE(request_delegate.auth_required_called()); | |
333 EXPECT_EQ("test.html", request_delegate.data_received()); | |
334 } | |
335 | |
336 TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedProxyAuthWithCredentials) { | |
337 MockWrite writes[] = { | |
338 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
339 "Host: ftp.example.com\r\n" | |
340 "Proxy-Connection: keep-alive\r\n\r\n"), | |
341 MockWrite(ASYNC, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
342 "Host: ftp.example.com\r\n" | |
343 "Proxy-Connection: keep-alive\r\n" | |
344 "Proxy-Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"), | |
345 }; | |
346 MockRead reads[] = { | |
347 // No credentials. | |
348 MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"), | |
349 MockRead(ASYNC, 2, "Proxy-Authenticate: Basic " | |
350 "realm=\"MyRealm1\"\r\n"), | |
351 MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"), | |
352 MockRead(ASYNC, 4, "test.html"), | |
353 | |
354 // Second response. | |
355 MockRead(ASYNC, 6, "HTTP/1.1 200 OK\r\n"), | |
356 MockRead(ASYNC, 7, "Content-Length: 10\r\n\r\n"), | |
357 MockRead(ASYNC, 8, "test2.html"), | |
358 }; | |
359 | |
360 AddSocket(reads, arraysize(reads), writes, arraysize(writes)); | |
361 | |
362 TestDelegate request_delegate; | |
363 request_delegate.set_credentials( | |
364 AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass"))); | |
365 scoped_ptr<URLRequest> url_request(request_context()->CreateRequest( | |
366 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY, &request_delegate, | |
367 NULL)); | |
368 url_request->Start(); | |
369 ASSERT_TRUE(url_request->is_pending()); | |
370 socket_data(0)->RunFor(9); | |
371 | |
372 EXPECT_TRUE(url_request->status().is_success()); | |
373 EXPECT_EQ(1, network_delegate()->completed_requests()); | |
374 EXPECT_EQ(0, network_delegate()->error_count()); | |
375 EXPECT_TRUE(request_delegate.auth_required_called()); | |
376 EXPECT_EQ("test2.html", request_delegate.data_received()); | |
377 } | |
378 | |
379 TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedServerAuthNoCredentials) { | |
380 MockWrite writes[] = { | |
381 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
382 "Host: ftp.example.com\r\n" | |
383 "Proxy-Connection: keep-alive\r\n\r\n"), | |
384 }; | |
385 MockRead reads[] = { | |
386 // No credentials. | |
387 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"), | |
388 MockRead(ASYNC, 2, "WWW-Authenticate: Basic " | |
389 "realm=\"MyRealm1\"\r\n"), | |
390 MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"), | |
391 MockRead(ASYNC, 4, "test.html"), | |
392 }; | |
393 | |
394 AddSocket(reads, arraysize(reads), writes, arraysize(writes)); | |
395 | |
396 TestDelegate request_delegate; | |
397 scoped_ptr<URLRequest> url_request(request_context()->CreateRequest( | |
398 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY, &request_delegate, | |
399 NULL)); | |
400 url_request->Start(); | |
401 ASSERT_TRUE(url_request->is_pending()); | |
402 socket_data(0)->RunFor(5); | |
403 | |
404 EXPECT_TRUE(url_request->status().is_success()); | |
405 EXPECT_EQ(1, network_delegate()->completed_requests()); | |
406 EXPECT_EQ(0, network_delegate()->error_count()); | |
407 EXPECT_TRUE(request_delegate.auth_required_called()); | |
408 EXPECT_EQ("test.html", request_delegate.data_received()); | |
409 } | |
410 | |
411 TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedServerAuthWithCredentials) { | |
412 MockWrite writes[] = { | |
413 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
414 "Host: ftp.example.com\r\n" | |
415 "Proxy-Connection: keep-alive\r\n\r\n"), | |
416 MockWrite(ASYNC, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
417 "Host: ftp.example.com\r\n" | |
418 "Proxy-Connection: keep-alive\r\n" | |
419 "Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"), | |
420 }; | |
421 MockRead reads[] = { | |
422 // No credentials. | |
423 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"), | |
424 MockRead(ASYNC, 2, "WWW-Authenticate: Basic " | |
425 "realm=\"MyRealm1\"\r\n"), | |
426 MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"), | |
427 MockRead(ASYNC, 4, "test.html"), | |
428 | |
429 // Second response. | |
430 MockRead(ASYNC, 6, "HTTP/1.1 200 OK\r\n"), | |
431 MockRead(ASYNC, 7, "Content-Length: 10\r\n\r\n"), | |
432 MockRead(ASYNC, 8, "test2.html"), | |
433 }; | |
434 | |
435 AddSocket(reads, arraysize(reads), writes, arraysize(writes)); | |
436 | |
437 TestDelegate request_delegate; | |
438 request_delegate.set_credentials( | |
439 AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass"))); | |
440 scoped_ptr<URLRequest> url_request(request_context()->CreateRequest( | |
441 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY, &request_delegate, | |
442 NULL)); | |
443 url_request->Start(); | |
444 ASSERT_TRUE(url_request->is_pending()); | |
445 socket_data(0)->RunFor(9); | |
446 | |
447 EXPECT_TRUE(url_request->status().is_success()); | |
448 EXPECT_EQ(1, network_delegate()->completed_requests()); | |
449 EXPECT_EQ(0, network_delegate()->error_count()); | |
450 EXPECT_TRUE(request_delegate.auth_required_called()); | |
451 EXPECT_EQ("test2.html", request_delegate.data_received()); | |
452 } | |
453 | |
454 TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedProxyAndServerAuth) { | |
455 MockWrite writes[] = { | |
456 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
457 "Host: ftp.example.com\r\n" | |
458 "Proxy-Connection: keep-alive\r\n\r\n"), | |
459 MockWrite(ASYNC, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
460 "Host: ftp.example.com\r\n" | |
461 "Proxy-Connection: keep-alive\r\n" | |
462 "Proxy-Authorization: Basic " | |
463 "cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"), | |
464 MockWrite(ASYNC, 10, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
465 "Host: ftp.example.com\r\n" | |
466 "Proxy-Connection: keep-alive\r\n" | |
467 "Proxy-Authorization: Basic " | |
468 "cHJveHl1c2VyOnByb3h5cGFzcw==\r\n" | |
469 "Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"), | |
470 }; | |
471 MockRead reads[] = { | |
472 // No credentials. | |
473 MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"), | |
474 MockRead(ASYNC, 2, "Proxy-Authenticate: Basic " | |
475 "realm=\"MyRealm1\"\r\n"), | |
476 MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"), | |
477 MockRead(ASYNC, 4, "test.html"), | |
478 | |
479 // Second response. | |
480 MockRead(ASYNC, 6, "HTTP/1.1 401 Unauthorized\r\n"), | |
481 MockRead(ASYNC, 7, "WWW-Authenticate: Basic " | |
482 "realm=\"MyRealm1\"\r\n"), | |
483 MockRead(ASYNC, 8, "Content-Length: 9\r\n\r\n"), | |
484 MockRead(ASYNC, 9, "test.html"), | |
485 | |
486 // Third response. | |
487 MockRead(ASYNC, 11, "HTTP/1.1 200 OK\r\n"), | |
488 MockRead(ASYNC, 12, "Content-Length: 10\r\n\r\n"), | |
489 MockRead(ASYNC, 13, "test2.html"), | |
490 }; | |
491 | |
492 AddSocket(reads, arraysize(reads), writes, arraysize(writes)); | |
493 | |
494 GURL url("ftp://ftp.example.com"); | |
495 | |
496 // Make sure cached FTP credentials are not used for proxy authentication. | |
497 request_context()->GetFtpAuthCache()->Add( | |
498 url.GetOrigin(), | |
499 AuthCredentials(ASCIIToUTF16("userdonotuse"), | |
500 ASCIIToUTF16("passworddonotuse"))); | |
501 | |
502 TestDelegate request_delegate; | |
503 request_delegate.set_credentials( | |
504 AuthCredentials(ASCIIToUTF16("proxyuser"), ASCIIToUTF16("proxypass"))); | |
505 scoped_ptr<URLRequest> url_request(request_context()->CreateRequest( | |
506 url, DEFAULT_PRIORITY, &request_delegate, NULL)); | |
507 url_request->Start(); | |
508 ASSERT_TRUE(url_request->is_pending()); | |
509 socket_data(0)->RunFor(5); | |
510 | |
511 request_delegate.set_credentials( | |
512 AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass"))); | |
513 socket_data(0)->RunFor(9); | |
514 | |
515 EXPECT_TRUE(url_request->status().is_success()); | |
516 EXPECT_EQ(1, network_delegate()->completed_requests()); | |
517 EXPECT_EQ(0, network_delegate()->error_count()); | |
518 EXPECT_TRUE(request_delegate.auth_required_called()); | |
519 EXPECT_EQ("test2.html", request_delegate.data_received()); | |
520 } | |
521 | |
522 TEST_F(URLRequestFtpJobTest, FtpProxyRequestDoNotSaveCookies) { | |
523 MockWrite writes[] = { | |
524 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
525 "Host: ftp.example.com\r\n" | |
526 "Proxy-Connection: keep-alive\r\n\r\n"), | |
527 }; | |
528 MockRead reads[] = { | |
529 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"), | |
530 MockRead(ASYNC, 2, "Content-Length: 9\r\n"), | |
531 MockRead(ASYNC, 3, "Set-Cookie: name=value\r\n\r\n"), | |
532 MockRead(ASYNC, 4, "test.html"), | |
533 }; | |
534 | |
535 AddSocket(reads, arraysize(reads), writes, arraysize(writes)); | |
536 | |
537 TestDelegate request_delegate; | |
538 scoped_ptr<URLRequest> url_request(request_context()->CreateRequest( | |
539 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY, &request_delegate, | |
540 NULL)); | |
541 url_request->Start(); | |
542 ASSERT_TRUE(url_request->is_pending()); | |
543 | |
544 socket_data(0)->RunFor(5); | |
545 | |
546 EXPECT_TRUE(url_request->status().is_success()); | |
547 EXPECT_EQ(1, network_delegate()->completed_requests()); | |
548 EXPECT_EQ(0, network_delegate()->error_count()); | |
549 | |
550 // Make sure we do not accept cookies. | |
551 EXPECT_EQ(0, network_delegate()->set_cookie_count()); | |
552 | |
553 EXPECT_FALSE(request_delegate.auth_required_called()); | |
554 EXPECT_EQ("test.html", request_delegate.data_received()); | |
555 } | |
556 | |
557 TEST_F(URLRequestFtpJobTest, FtpProxyRequestDoNotFollowRedirects) { | |
558 MockWrite writes[] = { | |
559 MockWrite(SYNCHRONOUS, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n" | |
560 "Host: ftp.example.com\r\n" | |
561 "Proxy-Connection: keep-alive\r\n\r\n"), | |
562 }; | |
563 MockRead reads[] = { | |
564 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 302 Found\r\n"), | |
565 MockRead(ASYNC, 2, "Location: http://other.example.com/\r\n\r\n"), | |
566 }; | |
567 | |
568 AddSocket(reads, arraysize(reads), writes, arraysize(writes)); | |
569 | |
570 TestDelegate request_delegate; | |
571 scoped_ptr<URLRequest> url_request(request_context()->CreateRequest( | |
572 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY, &request_delegate, | |
573 NULL)); | |
574 url_request->Start(); | |
575 EXPECT_TRUE(url_request->is_pending()); | |
576 | |
577 base::MessageLoop::current()->RunUntilIdle(); | |
578 | |
579 EXPECT_TRUE(url_request->is_pending()); | |
580 EXPECT_EQ(0, request_delegate.response_started_count()); | |
581 EXPECT_EQ(0, network_delegate()->error_count()); | |
582 ASSERT_TRUE(url_request->status().is_success()); | |
583 | |
584 socket_data(0)->RunFor(1); | |
585 | |
586 EXPECT_EQ(1, network_delegate()->completed_requests()); | |
587 EXPECT_EQ(1, network_delegate()->error_count()); | |
588 EXPECT_FALSE(url_request->status().is_success()); | |
589 EXPECT_EQ(ERR_UNSAFE_REDIRECT, url_request->status().error()); | |
590 } | |
591 | |
592 // We should re-use socket for requests using the same scheme, host, and port. | |
593 TEST_F(URLRequestFtpJobTest, FtpProxyRequestReuseSocket) { | |
594 MockWrite writes[] = { | |
595 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/first HTTP/1.1\r\n" | |
596 "Host: ftp.example.com\r\n" | |
597 "Proxy-Connection: keep-alive\r\n\r\n"), | |
598 MockWrite(ASYNC, 4, "GET ftp://ftp.example.com/second HTTP/1.1\r\n" | |
599 "Host: ftp.example.com\r\n" | |
600 "Proxy-Connection: keep-alive\r\n\r\n"), | |
601 }; | |
602 MockRead reads[] = { | |
603 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"), | |
604 MockRead(ASYNC, 2, "Content-Length: 10\r\n\r\n"), | |
605 MockRead(ASYNC, 3, "test1.html"), | |
606 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\n"), | |
607 MockRead(ASYNC, 6, "Content-Length: 10\r\n\r\n"), | |
608 MockRead(ASYNC, 7, "test2.html"), | |
609 }; | |
610 | |
611 AddSocket(reads, arraysize(reads), writes, arraysize(writes)); | |
612 | |
613 TestDelegate request_delegate1; | |
614 | |
615 scoped_ptr<URLRequest> url_request1(request_context()->CreateRequest( | |
616 GURL("ftp://ftp.example.com/first"), DEFAULT_PRIORITY, &request_delegate1, | |
617 NULL)); | |
618 url_request1->Start(); | |
619 ASSERT_TRUE(url_request1->is_pending()); | |
620 socket_data(0)->RunFor(4); | |
621 | |
622 EXPECT_TRUE(url_request1->status().is_success()); | |
623 EXPECT_TRUE(url_request1->proxy_server().Equals( | |
624 net::HostPortPair::FromString("localhost:80"))); | |
625 EXPECT_EQ(1, network_delegate()->completed_requests()); | |
626 EXPECT_EQ(0, network_delegate()->error_count()); | |
627 EXPECT_FALSE(request_delegate1.auth_required_called()); | |
628 EXPECT_EQ("test1.html", request_delegate1.data_received()); | |
629 | |
630 TestDelegate request_delegate2; | |
631 scoped_ptr<URLRequest> url_request2(request_context()->CreateRequest( | |
632 GURL("ftp://ftp.example.com/second"), DEFAULT_PRIORITY, | |
633 &request_delegate2, NULL)); | |
634 url_request2->Start(); | |
635 ASSERT_TRUE(url_request2->is_pending()); | |
636 socket_data(0)->RunFor(4); | |
637 | |
638 EXPECT_TRUE(url_request2->status().is_success()); | |
639 EXPECT_EQ(2, network_delegate()->completed_requests()); | |
640 EXPECT_EQ(0, network_delegate()->error_count()); | |
641 EXPECT_FALSE(request_delegate2.auth_required_called()); | |
642 EXPECT_EQ("test2.html", request_delegate2.data_received()); | |
643 } | |
644 | |
645 // We should not re-use socket when there are two requests to the same host, | |
646 // but one is FTP and the other is HTTP. | |
647 TEST_F(URLRequestFtpJobTest, FtpProxyRequestDoNotReuseSocket) { | |
648 MockWrite writes1[] = { | |
649 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/first HTTP/1.1\r\n" | |
650 "Host: ftp.example.com\r\n" | |
651 "Proxy-Connection: keep-alive\r\n\r\n"), | |
652 }; | |
653 MockWrite writes2[] = { | |
654 MockWrite(ASYNC, 0, "GET /second HTTP/1.1\r\n" | |
655 "Host: ftp.example.com\r\n" | |
656 "Connection: keep-alive\r\n" | |
657 "User-Agent:\r\n" | |
658 "Accept-Encoding: gzip, deflate\r\n" | |
659 "Accept-Language: en-us,fr\r\n\r\n"), | |
660 }; | |
661 MockRead reads1[] = { | |
662 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"), | |
663 MockRead(ASYNC, 2, "Content-Length: 10\r\n\r\n"), | |
664 MockRead(ASYNC, 3, "test1.html"), | |
665 }; | |
666 MockRead reads2[] = { | |
667 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"), | |
668 MockRead(ASYNC, 2, "Content-Length: 10\r\n\r\n"), | |
669 MockRead(ASYNC, 3, "test2.html"), | |
670 }; | |
671 | |
672 AddSocket(reads1, arraysize(reads1), writes1, arraysize(writes1)); | |
673 AddSocket(reads2, arraysize(reads2), writes2, arraysize(writes2)); | |
674 | |
675 TestDelegate request_delegate1; | |
676 scoped_ptr<URLRequest> url_request1(request_context()->CreateRequest( | |
677 GURL("ftp://ftp.example.com/first"), DEFAULT_PRIORITY, | |
678 &request_delegate1, NULL)); | |
679 url_request1->Start(); | |
680 ASSERT_TRUE(url_request1->is_pending()); | |
681 socket_data(0)->RunFor(4); | |
682 | |
683 EXPECT_TRUE(url_request1->status().is_success()); | |
684 EXPECT_EQ(1, network_delegate()->completed_requests()); | |
685 EXPECT_EQ(0, network_delegate()->error_count()); | |
686 EXPECT_FALSE(request_delegate1.auth_required_called()); | |
687 EXPECT_EQ("test1.html", request_delegate1.data_received()); | |
688 | |
689 TestDelegate request_delegate2; | |
690 scoped_ptr<URLRequest> url_request2(request_context()->CreateRequest( | |
691 GURL("http://ftp.example.com/second"), DEFAULT_PRIORITY, | |
692 &request_delegate2, NULL)); | |
693 url_request2->Start(); | |
694 ASSERT_TRUE(url_request2->is_pending()); | |
695 socket_data(1)->RunFor(4); | |
696 | |
697 EXPECT_TRUE(url_request2->status().is_success()); | |
698 EXPECT_EQ(2, network_delegate()->completed_requests()); | |
699 EXPECT_EQ(0, network_delegate()->error_count()); | |
700 EXPECT_FALSE(request_delegate2.auth_required_called()); | |
701 EXPECT_EQ("test2.html", request_delegate2.data_received()); | |
702 } | |
703 | |
704 } // namespace | |
705 | |
706 } // namespace net | |
OLD | NEW |