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.
5 #include "net/url_request/url_request_ftp_job.h"
7 #include "base/memory/ref_counted.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/run_loop.h"
10 #include "net/base/request_priority.h"
11 #include "net/ftp/ftp_auth_cache.h"
12 #include "net/http/http_transaction_unittest.h"
13 #include "net/proxy/mock_proxy_resolver.h"
14 #include "net/proxy/proxy_config_service.h"
15 #include "net/proxy/proxy_config_service_fixed.h"
16 #include "net/socket/socket_test_util.h"
17 #include "net/url_request/ftp_protocol_handler.h"
18 #include "net/url_request/url_request.h"
19 #include "net/url_request/url_request_context.h"
20 #include "net/url_request/url_request_job_factory_impl.h"
21 #include "net/url_request/url_request_status.h"
22 #include "net/url_request/url_request_test_util.h"
23 #include "testing/gtest/include/gtest/gtest.h"
28 class FtpTestURLRequestContext : public TestURLRequestContext {
30 FtpTestURLRequestContext(ClientSocketFactory* socket_factory,
31 ProxyService* proxy_service,
32 NetworkDelegate* network_delegate,
33 FtpTransactionFactory* ftp_transaction_factory)
34 : TestURLRequestContext(true),
35 ftp_protocol_handler_(new FtpProtocolHandler(ftp_transaction_factory)) {
36 set_client_socket_factory(socket_factory);
37 context_storage_.set_proxy_service(proxy_service);
38 set_network_delegate(network_delegate);
39 URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl;
40 job_factory->SetProtocolHandler("ftp", ftp_protocol_handler_);
41 context_storage_.set_job_factory(job_factory);
45 FtpAuthCache* GetFtpAuthCache() {
46 return ftp_protocol_handler_->ftp_auth_cache_.get();
49 void set_proxy_service(ProxyService* proxy_service) {
50 context_storage_.set_proxy_service(proxy_service);
54 FtpProtocolHandler* ftp_protocol_handler_;
59 class SimpleProxyConfigService : public ProxyConfigService {
61 SimpleProxyConfigService() {
62 // Any FTP requests that ever go through HTTP paths are proxied requests.
63 config_.proxy_rules().ParseFromString("ftp=localhost");
66 virtual void AddObserver(Observer* observer) OVERRIDE {
70 virtual void RemoveObserver(Observer* observer) OVERRIDE {
71 if (observer_ == observer) {
76 virtual ConfigAvailability GetLatestProxyConfig(
77 ProxyConfig* config) OVERRIDE {
82 void IncrementConfigId() {
83 config_.set_id(config_.id() + 1);
84 observer_->OnProxyConfigChanged(config_, ProxyConfigService::CONFIG_VALID);
92 // Inherit from URLRequestFtpJob to expose the priority and some
93 // other hidden functions.
94 class TestURLRequestFtpJob : public URLRequestFtpJob {
96 TestURLRequestFtpJob(URLRequest* request,
97 FtpTransactionFactory* ftp_factory,
98 FtpAuthCache* ftp_auth_cache)
99 : URLRequestFtpJob(request, NULL, ftp_factory, ftp_auth_cache) {}
101 using URLRequestFtpJob::SetPriority;
102 using URLRequestFtpJob::Start;
103 using URLRequestFtpJob::Kill;
104 using URLRequestFtpJob::priority;
107 virtual ~TestURLRequestFtpJob() {}
110 class MockFtpTransactionFactory : public FtpTransactionFactory {
112 virtual FtpTransaction* CreateTransaction() OVERRIDE {
116 virtual void Suspend(bool suspend) OVERRIDE {}
119 // Fixture for priority-related tests. Priority matters when there is
121 class URLRequestFtpJobPriorityTest : public testing::Test {
123 URLRequestFtpJobPriorityTest()
124 : proxy_service_(new SimpleProxyConfigService, NULL, NULL),
125 req_(GURL("ftp://ftp.example.com"),
129 context_.set_proxy_service(&proxy_service_);
130 context_.set_http_transaction_factory(&network_layer_);
133 ProxyService proxy_service_;
134 MockNetworkLayer network_layer_;
135 MockFtpTransactionFactory ftp_factory_;
136 FtpAuthCache ftp_auth_cache_;
137 TestURLRequestContext context_;
138 TestDelegate delegate_;
142 // Make sure that SetPriority actually sets the URLRequestFtpJob's
143 // priority, both before and after start.
144 TEST_F(URLRequestFtpJobPriorityTest, SetPriorityBasic) {
145 scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
146 &req_, &ftp_factory_, &ftp_auth_cache_));
147 EXPECT_EQ(DEFAULT_PRIORITY, job->priority());
149 job->SetPriority(LOWEST);
150 EXPECT_EQ(LOWEST, job->priority());
152 job->SetPriority(LOW);
153 EXPECT_EQ(LOW, job->priority());
156 EXPECT_EQ(LOW, job->priority());
158 job->SetPriority(MEDIUM);
159 EXPECT_EQ(MEDIUM, job->priority());
162 // Make sure that URLRequestFtpJob passes on its priority to its
163 // transaction on start.
164 TEST_F(URLRequestFtpJobPriorityTest, SetTransactionPriorityOnStart) {
165 scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
166 &req_, &ftp_factory_, &ftp_auth_cache_));
167 job->SetPriority(LOW);
169 EXPECT_FALSE(network_layer_.last_transaction());
173 ASSERT_TRUE(network_layer_.last_transaction());
174 EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
177 // Make sure that URLRequestFtpJob passes on its priority updates to
179 TEST_F(URLRequestFtpJobPriorityTest, SetTransactionPriority) {
180 scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
181 &req_, &ftp_factory_, &ftp_auth_cache_));
182 job->SetPriority(LOW);
184 ASSERT_TRUE(network_layer_.last_transaction());
185 EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
187 job->SetPriority(HIGHEST);
188 EXPECT_EQ(HIGHEST, network_layer_.last_transaction()->priority());
191 // Make sure that URLRequestFtpJob passes on its priority updates to
192 // newly-created transactions after the first one.
193 TEST_F(URLRequestFtpJobPriorityTest, SetSubsequentTransactionPriority) {
194 scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
195 &req_, &ftp_factory_, &ftp_auth_cache_));
198 job->SetPriority(LOW);
199 ASSERT_TRUE(network_layer_.last_transaction());
200 EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
203 network_layer_.ClearLastTransaction();
205 // Creates a second transaction.
207 ASSERT_TRUE(network_layer_.last_transaction());
208 EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
211 class URLRequestFtpJobTest : public testing::Test {
213 URLRequestFtpJobTest()
214 : request_context_(&socket_factory_,
216 new SimpleProxyConfigService, NULL, NULL),
218 &ftp_transaction_factory_) {
221 virtual ~URLRequestFtpJobTest() {
222 // Clean up any remaining tasks that mess up unrelated tests.
223 base::RunLoop run_loop;
224 run_loop.RunUntilIdle();
227 void AddSocket(MockRead* reads, size_t reads_size,
228 MockWrite* writes, size_t writes_size) {
229 DeterministicSocketData* socket_data = new DeterministicSocketData(
230 reads, reads_size, writes, writes_size);
231 socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
232 socket_data->StopAfter(reads_size + writes_size - 1);
233 socket_factory_.AddSocketDataProvider(socket_data);
235 socket_data_.push_back(socket_data);
238 FtpTestURLRequestContext* request_context() { return &request_context_; }
239 TestNetworkDelegate* network_delegate() { return &network_delegate_; }
240 DeterministicSocketData* socket_data(size_t index) {
241 return socket_data_[index];
245 ScopedVector<DeterministicSocketData> socket_data_;
246 DeterministicMockClientSocketFactory socket_factory_;
247 TestNetworkDelegate network_delegate_;
248 MockFtpTransactionFactory ftp_transaction_factory_;
250 FtpTestURLRequestContext request_context_;
253 TEST_F(URLRequestFtpJobTest, FtpProxyRequest) {
254 MockWrite writes[] = {
255 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
256 "Host: ftp.example.com\r\n"
257 "Proxy-Connection: keep-alive\r\n\r\n"),
260 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
261 MockRead(ASYNC, 2, "Content-Length: 9\r\n\r\n"),
262 MockRead(ASYNC, 3, "test.html"),
265 AddSocket(reads, arraysize(reads), writes, arraysize(writes));
267 TestDelegate request_delegate;
268 URLRequest url_request(GURL("ftp://ftp.example.com/"),
273 ASSERT_TRUE(url_request.is_pending());
274 socket_data(0)->RunFor(4);
276 EXPECT_TRUE(url_request.status().is_success());
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());
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(
288 new ProxyConfigServiceFixed(
289 ProxyConfig::CreateFromCustomPacURL(GURL("http://foo"))),
290 new MockAsyncProxyResolver, NULL));
292 TestDelegate request_delegate;
293 URLRequest url_request(GURL("ftp://ftp.example.com/"),
299 // Now |url_request| will be deleted before its completion,
300 // resulting in it being orphaned. It should not crash.
303 TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedProxyAuthNoCredentials) {
304 MockWrite writes[] = {
305 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
306 "Host: ftp.example.com\r\n"
307 "Proxy-Connection: keep-alive\r\n\r\n"),
311 MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
312 MockRead(ASYNC, 2, "Proxy-Authenticate: Basic "
313 "realm=\"MyRealm1\"\r\n"),
314 MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"),
315 MockRead(ASYNC, 4, "test.html"),
318 AddSocket(reads, arraysize(reads), writes, arraysize(writes));
320 TestDelegate request_delegate;
321 URLRequest url_request(GURL("ftp://ftp.example.com/"),
326 ASSERT_TRUE(url_request.is_pending());
327 socket_data(0)->RunFor(5);
329 EXPECT_TRUE(url_request.status().is_success());
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());
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"),
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"),
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"),
360 AddSocket(reads, arraysize(reads), writes, arraysize(writes));
362 TestDelegate request_delegate;
363 request_delegate.set_credentials(
364 AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass")));
365 URLRequest url_request(GURL("ftp://ftp.example.com/"),
370 ASSERT_TRUE(url_request.is_pending());
371 socket_data(0)->RunFor(9);
373 EXPECT_TRUE(url_request.status().is_success());
374 EXPECT_EQ(1, network_delegate()->completed_requests());
375 EXPECT_EQ(0, network_delegate()->error_count());
376 EXPECT_TRUE(request_delegate.auth_required_called());
377 EXPECT_EQ("test2.html", request_delegate.data_received());
380 TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedServerAuthNoCredentials) {
381 MockWrite writes[] = {
382 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
383 "Host: ftp.example.com\r\n"
384 "Proxy-Connection: keep-alive\r\n\r\n"),
388 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
389 MockRead(ASYNC, 2, "WWW-Authenticate: Basic "
390 "realm=\"MyRealm1\"\r\n"),
391 MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"),
392 MockRead(ASYNC, 4, "test.html"),
395 AddSocket(reads, arraysize(reads), writes, arraysize(writes));
397 TestDelegate request_delegate;
398 URLRequest url_request(GURL("ftp://ftp.example.com/"),
403 ASSERT_TRUE(url_request.is_pending());
404 socket_data(0)->RunFor(5);
406 EXPECT_TRUE(url_request.status().is_success());
407 EXPECT_EQ(1, network_delegate()->completed_requests());
408 EXPECT_EQ(0, network_delegate()->error_count());
409 EXPECT_TRUE(request_delegate.auth_required_called());
410 EXPECT_EQ("test.html", request_delegate.data_received());
413 TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedServerAuthWithCredentials) {
414 MockWrite writes[] = {
415 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
416 "Host: ftp.example.com\r\n"
417 "Proxy-Connection: keep-alive\r\n\r\n"),
418 MockWrite(ASYNC, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
419 "Host: ftp.example.com\r\n"
420 "Proxy-Connection: keep-alive\r\n"
421 "Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"),
425 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
426 MockRead(ASYNC, 2, "WWW-Authenticate: Basic "
427 "realm=\"MyRealm1\"\r\n"),
428 MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"),
429 MockRead(ASYNC, 4, "test.html"),
432 MockRead(ASYNC, 6, "HTTP/1.1 200 OK\r\n"),
433 MockRead(ASYNC, 7, "Content-Length: 10\r\n\r\n"),
434 MockRead(ASYNC, 8, "test2.html"),
437 AddSocket(reads, arraysize(reads), writes, arraysize(writes));
439 TestDelegate request_delegate;
440 request_delegate.set_credentials(
441 AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass")));
442 URLRequest url_request(GURL("ftp://ftp.example.com/"),
447 ASSERT_TRUE(url_request.is_pending());
448 socket_data(0)->RunFor(9);
450 EXPECT_TRUE(url_request.status().is_success());
451 EXPECT_EQ(1, network_delegate()->completed_requests());
452 EXPECT_EQ(0, network_delegate()->error_count());
453 EXPECT_TRUE(request_delegate.auth_required_called());
454 EXPECT_EQ("test2.html", request_delegate.data_received());
457 TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedProxyAndServerAuth) {
458 MockWrite writes[] = {
459 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
460 "Host: ftp.example.com\r\n"
461 "Proxy-Connection: keep-alive\r\n\r\n"),
462 MockWrite(ASYNC, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
463 "Host: ftp.example.com\r\n"
464 "Proxy-Connection: keep-alive\r\n"
465 "Proxy-Authorization: Basic "
466 "cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"),
467 MockWrite(ASYNC, 10, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
468 "Host: ftp.example.com\r\n"
469 "Proxy-Connection: keep-alive\r\n"
470 "Proxy-Authorization: Basic "
471 "cHJveHl1c2VyOnByb3h5cGFzcw==\r\n"
472 "Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"),
476 MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
477 MockRead(ASYNC, 2, "Proxy-Authenticate: Basic "
478 "realm=\"MyRealm1\"\r\n"),
479 MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"),
480 MockRead(ASYNC, 4, "test.html"),
483 MockRead(ASYNC, 6, "HTTP/1.1 401 Unauthorized\r\n"),
484 MockRead(ASYNC, 7, "WWW-Authenticate: Basic "
485 "realm=\"MyRealm1\"\r\n"),
486 MockRead(ASYNC, 8, "Content-Length: 9\r\n\r\n"),
487 MockRead(ASYNC, 9, "test.html"),
490 MockRead(ASYNC, 11, "HTTP/1.1 200 OK\r\n"),
491 MockRead(ASYNC, 12, "Content-Length: 10\r\n\r\n"),
492 MockRead(ASYNC, 13, "test2.html"),
495 AddSocket(reads, arraysize(reads), writes, arraysize(writes));
497 GURL url("ftp://ftp.example.com");
499 // Make sure cached FTP credentials are not used for proxy authentication.
500 request_context()->GetFtpAuthCache()->Add(
502 AuthCredentials(ASCIIToUTF16("userdonotuse"),
503 ASCIIToUTF16("passworddonotuse")));
505 TestDelegate request_delegate;
506 request_delegate.set_credentials(
507 AuthCredentials(ASCIIToUTF16("proxyuser"), ASCIIToUTF16("proxypass")));
508 URLRequest url_request(
509 url, DEFAULT_PRIORITY, &request_delegate, request_context());
511 ASSERT_TRUE(url_request.is_pending());
512 socket_data(0)->RunFor(5);
514 request_delegate.set_credentials(
515 AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass")));
516 socket_data(0)->RunFor(9);
518 EXPECT_TRUE(url_request.status().is_success());
519 EXPECT_EQ(1, network_delegate()->completed_requests());
520 EXPECT_EQ(0, network_delegate()->error_count());
521 EXPECT_TRUE(request_delegate.auth_required_called());
522 EXPECT_EQ("test2.html", request_delegate.data_received());
525 TEST_F(URLRequestFtpJobTest, FtpProxyRequestDoNotSaveCookies) {
526 MockWrite writes[] = {
527 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
528 "Host: ftp.example.com\r\n"
529 "Proxy-Connection: keep-alive\r\n\r\n"),
532 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
533 MockRead(ASYNC, 2, "Content-Length: 9\r\n"),
534 MockRead(ASYNC, 3, "Set-Cookie: name=value\r\n\r\n"),
535 MockRead(ASYNC, 4, "test.html"),
538 AddSocket(reads, arraysize(reads), writes, arraysize(writes));
540 TestDelegate request_delegate;
541 URLRequest url_request(GURL("ftp://ftp.example.com/"),
546 ASSERT_TRUE(url_request.is_pending());
548 socket_data(0)->RunFor(5);
550 EXPECT_TRUE(url_request.status().is_success());
551 EXPECT_EQ(1, network_delegate()->completed_requests());
552 EXPECT_EQ(0, network_delegate()->error_count());
554 // Make sure we do not accept cookies.
555 EXPECT_EQ(0, network_delegate()->set_cookie_count());
557 EXPECT_FALSE(request_delegate.auth_required_called());
558 EXPECT_EQ("test.html", request_delegate.data_received());
561 TEST_F(URLRequestFtpJobTest, FtpProxyRequestDoNotFollowRedirects) {
562 MockWrite writes[] = {
563 MockWrite(SYNCHRONOUS, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
564 "Host: ftp.example.com\r\n"
565 "Proxy-Connection: keep-alive\r\n\r\n"),
568 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 302 Found\r\n"),
569 MockRead(ASYNC, 2, "Location: http://other.example.com/\r\n\r\n"),
572 AddSocket(reads, arraysize(reads), writes, arraysize(writes));
574 TestDelegate request_delegate;
575 URLRequest url_request(GURL("ftp://ftp.example.com/"),
580 EXPECT_TRUE(url_request.is_pending());
582 base::MessageLoop::current()->RunUntilIdle();
584 EXPECT_TRUE(url_request.is_pending());
585 EXPECT_EQ(0, request_delegate.response_started_count());
586 EXPECT_EQ(0, network_delegate()->error_count());
587 ASSERT_TRUE(url_request.status().is_success());
589 socket_data(0)->RunFor(1);
591 EXPECT_EQ(1, network_delegate()->completed_requests());
592 EXPECT_EQ(1, network_delegate()->error_count());
593 EXPECT_FALSE(url_request.status().is_success());
594 EXPECT_EQ(ERR_UNSAFE_REDIRECT, url_request.status().error());
597 // We should re-use socket for requests using the same scheme, host, and port.
598 TEST_F(URLRequestFtpJobTest, FtpProxyRequestReuseSocket) {
599 MockWrite writes[] = {
600 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/first HTTP/1.1\r\n"
601 "Host: ftp.example.com\r\n"
602 "Proxy-Connection: keep-alive\r\n\r\n"),
603 MockWrite(ASYNC, 4, "GET ftp://ftp.example.com/second HTTP/1.1\r\n"
604 "Host: ftp.example.com\r\n"
605 "Proxy-Connection: keep-alive\r\n\r\n"),
608 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
609 MockRead(ASYNC, 2, "Content-Length: 10\r\n\r\n"),
610 MockRead(ASYNC, 3, "test1.html"),
611 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\n"),
612 MockRead(ASYNC, 6, "Content-Length: 10\r\n\r\n"),
613 MockRead(ASYNC, 7, "test2.html"),
616 AddSocket(reads, arraysize(reads), writes, arraysize(writes));
618 TestDelegate request_delegate1;
619 URLRequest url_request1(GURL("ftp://ftp.example.com/first"),
623 url_request1.Start();
624 ASSERT_TRUE(url_request1.is_pending());
625 socket_data(0)->RunFor(4);
627 EXPECT_TRUE(url_request1.status().is_success());
628 EXPECT_EQ(1, network_delegate()->completed_requests());
629 EXPECT_EQ(0, network_delegate()->error_count());
630 EXPECT_FALSE(request_delegate1.auth_required_called());
631 EXPECT_EQ("test1.html", request_delegate1.data_received());
633 TestDelegate request_delegate2;
634 URLRequest url_request2(GURL("ftp://ftp.example.com/second"),
638 url_request2.Start();
639 ASSERT_TRUE(url_request2.is_pending());
640 socket_data(0)->RunFor(4);
642 EXPECT_TRUE(url_request2.status().is_success());
643 EXPECT_EQ(2, network_delegate()->completed_requests());
644 EXPECT_EQ(0, network_delegate()->error_count());
645 EXPECT_FALSE(request_delegate2.auth_required_called());
646 EXPECT_EQ("test2.html", request_delegate2.data_received());
649 // We should not re-use socket when there are two requests to the same host,
650 // but one is FTP and the other is HTTP.
651 TEST_F(URLRequestFtpJobTest, FtpProxyRequestDoNotReuseSocket) {
652 MockWrite writes1[] = {
653 MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/first HTTP/1.1\r\n"
654 "Host: ftp.example.com\r\n"
655 "Proxy-Connection: keep-alive\r\n\r\n"),
657 MockWrite writes2[] = {
658 MockWrite(ASYNC, 0, "GET /second HTTP/1.1\r\n"
659 "Host: ftp.example.com\r\n"
660 "Connection: keep-alive\r\n"
662 "Accept-Encoding: gzip,deflate\r\n"
663 "Accept-Language: en-us,fr\r\n\r\n"),
665 MockRead reads1[] = {
666 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
667 MockRead(ASYNC, 2, "Content-Length: 10\r\n\r\n"),
668 MockRead(ASYNC, 3, "test1.html"),
670 MockRead reads2[] = {
671 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
672 MockRead(ASYNC, 2, "Content-Length: 10\r\n\r\n"),
673 MockRead(ASYNC, 3, "test2.html"),
676 AddSocket(reads1, arraysize(reads1), writes1, arraysize(writes1));
677 AddSocket(reads2, arraysize(reads2), writes2, arraysize(writes2));
679 TestDelegate request_delegate1;
680 URLRequest url_request1(GURL("ftp://ftp.example.com/first"),
684 url_request1.Start();
685 ASSERT_TRUE(url_request1.is_pending());
686 socket_data(0)->RunFor(4);
688 EXPECT_TRUE(url_request1.status().is_success());
689 EXPECT_EQ(1, network_delegate()->completed_requests());
690 EXPECT_EQ(0, network_delegate()->error_count());
691 EXPECT_FALSE(request_delegate1.auth_required_called());
692 EXPECT_EQ("test1.html", request_delegate1.data_received());
694 TestDelegate request_delegate2;
695 URLRequest url_request2(GURL("http://ftp.example.com/second"),
699 url_request2.Start();
700 ASSERT_TRUE(url_request2.is_pending());
701 socket_data(1)->RunFor(4);
703 EXPECT_TRUE(url_request2.status().is_success());
704 EXPECT_EQ(2, network_delegate()->completed_requests());
705 EXPECT_EQ(0, network_delegate()->error_count());
706 EXPECT_FALSE(request_delegate2.auth_required_called());
707 EXPECT_EQ("test2.html", request_delegate2.data_received());