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/host_port_pair.h"
11 #include "net/base/request_priority.h"
12 #include "net/ftp/ftp_auth_cache.h"
13 #include "net/http/http_transaction_test_util.h"
14 #include "net/proxy/mock_proxy_resolver.h"
15 #include "net/proxy/proxy_config_service.h"
16 #include "net/proxy/proxy_config_service_fixed.h"
17 #include "net/socket/socket_test_util.h"
18 #include "net/url_request/ftp_protocol_handler.h"
19 #include "net/url_request/url_request.h"
20 #include "net/url_request/url_request_context.h"
21 #include "net/url_request/url_request_job_factory_impl.h"
22 #include "net/url_request/url_request_status.h"
23 #include "net/url_request/url_request_test_util.h"
24 #include "testing/gtest/include/gtest/gtest.h"
27 using base::ASCIIToUTF16
;
31 class FtpTestURLRequestContext
: public TestURLRequestContext
{
33 FtpTestURLRequestContext(ClientSocketFactory
* socket_factory
,
34 ProxyService
* proxy_service
,
35 NetworkDelegate
* network_delegate
,
36 FtpTransactionFactory
* ftp_transaction_factory
)
37 : TestURLRequestContext(true),
38 ftp_protocol_handler_(new FtpProtocolHandler(ftp_transaction_factory
)) {
39 set_client_socket_factory(socket_factory
);
40 context_storage_
.set_proxy_service(proxy_service
);
41 set_network_delegate(network_delegate
);
42 URLRequestJobFactoryImpl
* job_factory
= new URLRequestJobFactoryImpl
;
43 job_factory
->SetProtocolHandler("ftp", ftp_protocol_handler_
);
44 context_storage_
.set_job_factory(job_factory
);
48 FtpAuthCache
* GetFtpAuthCache() {
49 return ftp_protocol_handler_
->ftp_auth_cache_
.get();
52 void set_proxy_service(ProxyService
* proxy_service
) {
53 context_storage_
.set_proxy_service(proxy_service
);
57 FtpProtocolHandler
* ftp_protocol_handler_
;
62 class SimpleProxyConfigService
: public ProxyConfigService
{
64 SimpleProxyConfigService() {
65 // Any FTP requests that ever go through HTTP paths are proxied requests.
66 config_
.proxy_rules().ParseFromString("ftp=localhost");
69 virtual void AddObserver(Observer
* observer
) OVERRIDE
{
73 virtual void RemoveObserver(Observer
* observer
) OVERRIDE
{
74 if (observer_
== observer
) {
79 virtual ConfigAvailability
GetLatestProxyConfig(
80 ProxyConfig
* config
) OVERRIDE
{
85 void IncrementConfigId() {
86 config_
.set_id(config_
.id() + 1);
87 observer_
->OnProxyConfigChanged(config_
, ProxyConfigService::CONFIG_VALID
);
95 // Inherit from URLRequestFtpJob to expose the priority and some
96 // other hidden functions.
97 class TestURLRequestFtpJob
: public URLRequestFtpJob
{
99 TestURLRequestFtpJob(URLRequest
* request
,
100 FtpTransactionFactory
* ftp_factory
,
101 FtpAuthCache
* ftp_auth_cache
)
102 : URLRequestFtpJob(request
, NULL
, ftp_factory
, ftp_auth_cache
) {}
104 using URLRequestFtpJob::SetPriority
;
105 using URLRequestFtpJob::Start
;
106 using URLRequestFtpJob::Kill
;
107 using URLRequestFtpJob::priority
;
110 virtual ~TestURLRequestFtpJob() {}
113 class MockFtpTransactionFactory
: public FtpTransactionFactory
{
115 virtual FtpTransaction
* CreateTransaction() OVERRIDE
{
119 virtual void Suspend(bool suspend
) OVERRIDE
{}
122 // Fixture for priority-related tests. Priority matters when there is
124 class URLRequestFtpJobPriorityTest
: public testing::Test
{
126 URLRequestFtpJobPriorityTest()
127 : proxy_service_(new SimpleProxyConfigService
, NULL
, NULL
),
128 req_(GURL("ftp://ftp.example.com"),
132 context_
.set_proxy_service(&proxy_service_
);
133 context_
.set_http_transaction_factory(&network_layer_
);
136 ProxyService proxy_service_
;
137 MockNetworkLayer network_layer_
;
138 MockFtpTransactionFactory ftp_factory_
;
139 FtpAuthCache ftp_auth_cache_
;
140 TestURLRequestContext context_
;
141 TestDelegate delegate_
;
145 // Make sure that SetPriority actually sets the URLRequestFtpJob's
146 // priority, both before and after start.
147 TEST_F(URLRequestFtpJobPriorityTest
, SetPriorityBasic
) {
148 scoped_refptr
<TestURLRequestFtpJob
> job(new TestURLRequestFtpJob(
149 &req_
, &ftp_factory_
, &ftp_auth_cache_
));
150 EXPECT_EQ(DEFAULT_PRIORITY
, job
->priority());
152 job
->SetPriority(LOWEST
);
153 EXPECT_EQ(LOWEST
, job
->priority());
155 job
->SetPriority(LOW
);
156 EXPECT_EQ(LOW
, job
->priority());
159 EXPECT_EQ(LOW
, job
->priority());
161 job
->SetPriority(MEDIUM
);
162 EXPECT_EQ(MEDIUM
, job
->priority());
165 // Make sure that URLRequestFtpJob passes on its priority to its
166 // transaction on start.
167 TEST_F(URLRequestFtpJobPriorityTest
, SetTransactionPriorityOnStart
) {
168 scoped_refptr
<TestURLRequestFtpJob
> job(new TestURLRequestFtpJob(
169 &req_
, &ftp_factory_
, &ftp_auth_cache_
));
170 job
->SetPriority(LOW
);
172 EXPECT_FALSE(network_layer_
.last_transaction());
176 ASSERT_TRUE(network_layer_
.last_transaction());
177 EXPECT_EQ(LOW
, network_layer_
.last_transaction()->priority());
180 // Make sure that URLRequestFtpJob passes on its priority updates to
182 TEST_F(URLRequestFtpJobPriorityTest
, SetTransactionPriority
) {
183 scoped_refptr
<TestURLRequestFtpJob
> job(new TestURLRequestFtpJob(
184 &req_
, &ftp_factory_
, &ftp_auth_cache_
));
185 job
->SetPriority(LOW
);
187 ASSERT_TRUE(network_layer_
.last_transaction());
188 EXPECT_EQ(LOW
, network_layer_
.last_transaction()->priority());
190 job
->SetPriority(HIGHEST
);
191 EXPECT_EQ(HIGHEST
, network_layer_
.last_transaction()->priority());
194 // Make sure that URLRequestFtpJob passes on its priority updates to
195 // newly-created transactions after the first one.
196 TEST_F(URLRequestFtpJobPriorityTest
, SetSubsequentTransactionPriority
) {
197 scoped_refptr
<TestURLRequestFtpJob
> job(new TestURLRequestFtpJob(
198 &req_
, &ftp_factory_
, &ftp_auth_cache_
));
201 job
->SetPriority(LOW
);
202 ASSERT_TRUE(network_layer_
.last_transaction());
203 EXPECT_EQ(LOW
, network_layer_
.last_transaction()->priority());
206 network_layer_
.ClearLastTransaction();
208 // Creates a second transaction.
210 ASSERT_TRUE(network_layer_
.last_transaction());
211 EXPECT_EQ(LOW
, network_layer_
.last_transaction()->priority());
214 class URLRequestFtpJobTest
: public testing::Test
{
216 URLRequestFtpJobTest()
217 : request_context_(&socket_factory_
,
219 new SimpleProxyConfigService
, NULL
, NULL
),
221 &ftp_transaction_factory_
) {
224 virtual ~URLRequestFtpJobTest() {
225 // Clean up any remaining tasks that mess up unrelated tests.
226 base::RunLoop run_loop
;
227 run_loop
.RunUntilIdle();
230 void AddSocket(MockRead
* reads
, size_t reads_size
,
231 MockWrite
* writes
, size_t writes_size
) {
232 DeterministicSocketData
* socket_data
= new DeterministicSocketData(
233 reads
, reads_size
, writes
, writes_size
);
234 socket_data
->set_connect_data(MockConnect(SYNCHRONOUS
, OK
));
235 socket_data
->StopAfter(reads_size
+ writes_size
- 1);
236 socket_factory_
.AddSocketDataProvider(socket_data
);
238 socket_data_
.push_back(socket_data
);
241 FtpTestURLRequestContext
* request_context() { return &request_context_
; }
242 TestNetworkDelegate
* network_delegate() { return &network_delegate_
; }
243 DeterministicSocketData
* socket_data(size_t index
) {
244 return socket_data_
[index
];
248 ScopedVector
<DeterministicSocketData
> socket_data_
;
249 DeterministicMockClientSocketFactory socket_factory_
;
250 TestNetworkDelegate network_delegate_
;
251 MockFtpTransactionFactory ftp_transaction_factory_
;
253 FtpTestURLRequestContext request_context_
;
256 TEST_F(URLRequestFtpJobTest
, FtpProxyRequest
) {
257 MockWrite writes
[] = {
258 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
259 "Host: ftp.example.com\r\n"
260 "Proxy-Connection: keep-alive\r\n\r\n"),
263 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
264 MockRead(ASYNC
, 2, "Content-Length: 9\r\n\r\n"),
265 MockRead(ASYNC
, 3, "test.html"),
268 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
270 TestDelegate request_delegate
;
271 URLRequest
url_request(GURL("ftp://ftp.example.com/"),
276 ASSERT_TRUE(url_request
.is_pending());
277 socket_data(0)->RunFor(4);
279 EXPECT_TRUE(url_request
.status().is_success());
280 EXPECT_TRUE(url_request
.proxy_server().Equals(
281 net::HostPortPair::FromString("localhost:80")));
282 EXPECT_EQ(1, network_delegate()->completed_requests());
283 EXPECT_EQ(0, network_delegate()->error_count());
284 EXPECT_FALSE(request_delegate
.auth_required_called());
285 EXPECT_EQ("test.html", request_delegate
.data_received());
288 // Regression test for http://crbug.com/237526 .
289 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestOrphanJob
) {
290 // Use a PAC URL so that URLRequestFtpJob's |pac_request_| field is non-NULL.
291 request_context()->set_proxy_service(
293 new ProxyConfigServiceFixed(
294 ProxyConfig::CreateFromCustomPacURL(GURL("http://foo"))),
295 new MockAsyncProxyResolver
, NULL
));
297 TestDelegate request_delegate
;
298 URLRequest
url_request(GURL("ftp://ftp.example.com/"),
304 // Now |url_request| will be deleted before its completion,
305 // resulting in it being orphaned. It should not crash.
308 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestNeedProxyAuthNoCredentials
) {
309 MockWrite writes
[] = {
310 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
311 "Host: ftp.example.com\r\n"
312 "Proxy-Connection: keep-alive\r\n\r\n"),
316 MockRead(ASYNC
, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
317 MockRead(ASYNC
, 2, "Proxy-Authenticate: Basic "
318 "realm=\"MyRealm1\"\r\n"),
319 MockRead(ASYNC
, 3, "Content-Length: 9\r\n\r\n"),
320 MockRead(ASYNC
, 4, "test.html"),
323 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
325 TestDelegate request_delegate
;
326 URLRequest
url_request(GURL("ftp://ftp.example.com/"),
331 ASSERT_TRUE(url_request
.is_pending());
332 socket_data(0)->RunFor(5);
334 EXPECT_TRUE(url_request
.status().is_success());
335 EXPECT_TRUE(url_request
.proxy_server().Equals(
336 net::HostPortPair::FromString("localhost:80")));
337 EXPECT_EQ(1, network_delegate()->completed_requests());
338 EXPECT_EQ(0, network_delegate()->error_count());
339 EXPECT_TRUE(request_delegate
.auth_required_called());
340 EXPECT_EQ("test.html", request_delegate
.data_received());
343 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestNeedProxyAuthWithCredentials
) {
344 MockWrite writes
[] = {
345 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
346 "Host: ftp.example.com\r\n"
347 "Proxy-Connection: keep-alive\r\n\r\n"),
348 MockWrite(ASYNC
, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
349 "Host: ftp.example.com\r\n"
350 "Proxy-Connection: keep-alive\r\n"
351 "Proxy-Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"),
355 MockRead(ASYNC
, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
356 MockRead(ASYNC
, 2, "Proxy-Authenticate: Basic "
357 "realm=\"MyRealm1\"\r\n"),
358 MockRead(ASYNC
, 3, "Content-Length: 9\r\n\r\n"),
359 MockRead(ASYNC
, 4, "test.html"),
362 MockRead(ASYNC
, 6, "HTTP/1.1 200 OK\r\n"),
363 MockRead(ASYNC
, 7, "Content-Length: 10\r\n\r\n"),
364 MockRead(ASYNC
, 8, "test2.html"),
367 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
369 TestDelegate request_delegate
;
370 request_delegate
.set_credentials(
371 AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass")));
372 URLRequest
url_request(GURL("ftp://ftp.example.com/"),
377 ASSERT_TRUE(url_request
.is_pending());
378 socket_data(0)->RunFor(9);
380 EXPECT_TRUE(url_request
.status().is_success());
381 EXPECT_EQ(1, network_delegate()->completed_requests());
382 EXPECT_EQ(0, network_delegate()->error_count());
383 EXPECT_TRUE(request_delegate
.auth_required_called());
384 EXPECT_EQ("test2.html", request_delegate
.data_received());
387 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestNeedServerAuthNoCredentials
) {
388 MockWrite writes
[] = {
389 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
390 "Host: ftp.example.com\r\n"
391 "Proxy-Connection: keep-alive\r\n\r\n"),
395 MockRead(ASYNC
, 1, "HTTP/1.1 401 Unauthorized\r\n"),
396 MockRead(ASYNC
, 2, "WWW-Authenticate: Basic "
397 "realm=\"MyRealm1\"\r\n"),
398 MockRead(ASYNC
, 3, "Content-Length: 9\r\n\r\n"),
399 MockRead(ASYNC
, 4, "test.html"),
402 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
404 TestDelegate request_delegate
;
405 URLRequest
url_request(GURL("ftp://ftp.example.com/"),
410 ASSERT_TRUE(url_request
.is_pending());
411 socket_data(0)->RunFor(5);
413 EXPECT_TRUE(url_request
.status().is_success());
414 EXPECT_EQ(1, network_delegate()->completed_requests());
415 EXPECT_EQ(0, network_delegate()->error_count());
416 EXPECT_TRUE(request_delegate
.auth_required_called());
417 EXPECT_EQ("test.html", request_delegate
.data_received());
420 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestNeedServerAuthWithCredentials
) {
421 MockWrite writes
[] = {
422 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
423 "Host: ftp.example.com\r\n"
424 "Proxy-Connection: keep-alive\r\n\r\n"),
425 MockWrite(ASYNC
, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
426 "Host: ftp.example.com\r\n"
427 "Proxy-Connection: keep-alive\r\n"
428 "Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"),
432 MockRead(ASYNC
, 1, "HTTP/1.1 401 Unauthorized\r\n"),
433 MockRead(ASYNC
, 2, "WWW-Authenticate: Basic "
434 "realm=\"MyRealm1\"\r\n"),
435 MockRead(ASYNC
, 3, "Content-Length: 9\r\n\r\n"),
436 MockRead(ASYNC
, 4, "test.html"),
439 MockRead(ASYNC
, 6, "HTTP/1.1 200 OK\r\n"),
440 MockRead(ASYNC
, 7, "Content-Length: 10\r\n\r\n"),
441 MockRead(ASYNC
, 8, "test2.html"),
444 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
446 TestDelegate request_delegate
;
447 request_delegate
.set_credentials(
448 AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass")));
449 URLRequest
url_request(GURL("ftp://ftp.example.com/"),
454 ASSERT_TRUE(url_request
.is_pending());
455 socket_data(0)->RunFor(9);
457 EXPECT_TRUE(url_request
.status().is_success());
458 EXPECT_EQ(1, network_delegate()->completed_requests());
459 EXPECT_EQ(0, network_delegate()->error_count());
460 EXPECT_TRUE(request_delegate
.auth_required_called());
461 EXPECT_EQ("test2.html", request_delegate
.data_received());
464 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestNeedProxyAndServerAuth
) {
465 MockWrite writes
[] = {
466 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
467 "Host: ftp.example.com\r\n"
468 "Proxy-Connection: keep-alive\r\n\r\n"),
469 MockWrite(ASYNC
, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
470 "Host: ftp.example.com\r\n"
471 "Proxy-Connection: keep-alive\r\n"
472 "Proxy-Authorization: Basic "
473 "cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"),
474 MockWrite(ASYNC
, 10, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
475 "Host: ftp.example.com\r\n"
476 "Proxy-Connection: keep-alive\r\n"
477 "Proxy-Authorization: Basic "
478 "cHJveHl1c2VyOnByb3h5cGFzcw==\r\n"
479 "Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"),
483 MockRead(ASYNC
, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
484 MockRead(ASYNC
, 2, "Proxy-Authenticate: Basic "
485 "realm=\"MyRealm1\"\r\n"),
486 MockRead(ASYNC
, 3, "Content-Length: 9\r\n\r\n"),
487 MockRead(ASYNC
, 4, "test.html"),
490 MockRead(ASYNC
, 6, "HTTP/1.1 401 Unauthorized\r\n"),
491 MockRead(ASYNC
, 7, "WWW-Authenticate: Basic "
492 "realm=\"MyRealm1\"\r\n"),
493 MockRead(ASYNC
, 8, "Content-Length: 9\r\n\r\n"),
494 MockRead(ASYNC
, 9, "test.html"),
497 MockRead(ASYNC
, 11, "HTTP/1.1 200 OK\r\n"),
498 MockRead(ASYNC
, 12, "Content-Length: 10\r\n\r\n"),
499 MockRead(ASYNC
, 13, "test2.html"),
502 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
504 GURL
url("ftp://ftp.example.com");
506 // Make sure cached FTP credentials are not used for proxy authentication.
507 request_context()->GetFtpAuthCache()->Add(
509 AuthCredentials(ASCIIToUTF16("userdonotuse"),
510 ASCIIToUTF16("passworddonotuse")));
512 TestDelegate request_delegate
;
513 request_delegate
.set_credentials(
514 AuthCredentials(ASCIIToUTF16("proxyuser"), ASCIIToUTF16("proxypass")));
515 URLRequest
url_request(
516 url
, DEFAULT_PRIORITY
, &request_delegate
, request_context());
518 ASSERT_TRUE(url_request
.is_pending());
519 socket_data(0)->RunFor(5);
521 request_delegate
.set_credentials(
522 AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass")));
523 socket_data(0)->RunFor(9);
525 EXPECT_TRUE(url_request
.status().is_success());
526 EXPECT_EQ(1, network_delegate()->completed_requests());
527 EXPECT_EQ(0, network_delegate()->error_count());
528 EXPECT_TRUE(request_delegate
.auth_required_called());
529 EXPECT_EQ("test2.html", request_delegate
.data_received());
532 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestDoNotSaveCookies
) {
533 MockWrite writes
[] = {
534 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
535 "Host: ftp.example.com\r\n"
536 "Proxy-Connection: keep-alive\r\n\r\n"),
539 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
540 MockRead(ASYNC
, 2, "Content-Length: 9\r\n"),
541 MockRead(ASYNC
, 3, "Set-Cookie: name=value\r\n\r\n"),
542 MockRead(ASYNC
, 4, "test.html"),
545 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
547 TestDelegate request_delegate
;
548 URLRequest
url_request(GURL("ftp://ftp.example.com/"),
553 ASSERT_TRUE(url_request
.is_pending());
555 socket_data(0)->RunFor(5);
557 EXPECT_TRUE(url_request
.status().is_success());
558 EXPECT_EQ(1, network_delegate()->completed_requests());
559 EXPECT_EQ(0, network_delegate()->error_count());
561 // Make sure we do not accept cookies.
562 EXPECT_EQ(0, network_delegate()->set_cookie_count());
564 EXPECT_FALSE(request_delegate
.auth_required_called());
565 EXPECT_EQ("test.html", request_delegate
.data_received());
568 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestDoNotFollowRedirects
) {
569 MockWrite writes
[] = {
570 MockWrite(SYNCHRONOUS
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
571 "Host: ftp.example.com\r\n"
572 "Proxy-Connection: keep-alive\r\n\r\n"),
575 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 302 Found\r\n"),
576 MockRead(ASYNC
, 2, "Location: http://other.example.com/\r\n\r\n"),
579 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
581 TestDelegate request_delegate
;
582 URLRequest
url_request(GURL("ftp://ftp.example.com/"),
587 EXPECT_TRUE(url_request
.is_pending());
589 base::MessageLoop::current()->RunUntilIdle();
591 EXPECT_TRUE(url_request
.is_pending());
592 EXPECT_EQ(0, request_delegate
.response_started_count());
593 EXPECT_EQ(0, network_delegate()->error_count());
594 ASSERT_TRUE(url_request
.status().is_success());
596 socket_data(0)->RunFor(1);
598 EXPECT_EQ(1, network_delegate()->completed_requests());
599 EXPECT_EQ(1, network_delegate()->error_count());
600 EXPECT_FALSE(url_request
.status().is_success());
601 EXPECT_EQ(ERR_UNSAFE_REDIRECT
, url_request
.status().error());
604 // We should re-use socket for requests using the same scheme, host, and port.
605 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestReuseSocket
) {
606 MockWrite writes
[] = {
607 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/first HTTP/1.1\r\n"
608 "Host: ftp.example.com\r\n"
609 "Proxy-Connection: keep-alive\r\n\r\n"),
610 MockWrite(ASYNC
, 4, "GET ftp://ftp.example.com/second HTTP/1.1\r\n"
611 "Host: ftp.example.com\r\n"
612 "Proxy-Connection: keep-alive\r\n\r\n"),
615 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
616 MockRead(ASYNC
, 2, "Content-Length: 10\r\n\r\n"),
617 MockRead(ASYNC
, 3, "test1.html"),
618 MockRead(ASYNC
, 5, "HTTP/1.1 200 OK\r\n"),
619 MockRead(ASYNC
, 6, "Content-Length: 10\r\n\r\n"),
620 MockRead(ASYNC
, 7, "test2.html"),
623 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
625 TestDelegate request_delegate1
;
626 URLRequest
url_request1(GURL("ftp://ftp.example.com/first"),
630 url_request1
.Start();
631 ASSERT_TRUE(url_request1
.is_pending());
632 socket_data(0)->RunFor(4);
634 EXPECT_TRUE(url_request1
.status().is_success());
635 EXPECT_TRUE(url_request1
.proxy_server().Equals(
636 net::HostPortPair::FromString("localhost:80")));
637 EXPECT_EQ(1, network_delegate()->completed_requests());
638 EXPECT_EQ(0, network_delegate()->error_count());
639 EXPECT_FALSE(request_delegate1
.auth_required_called());
640 EXPECT_EQ("test1.html", request_delegate1
.data_received());
642 TestDelegate request_delegate2
;
643 URLRequest
url_request2(GURL("ftp://ftp.example.com/second"),
647 url_request2
.Start();
648 ASSERT_TRUE(url_request2
.is_pending());
649 socket_data(0)->RunFor(4);
651 EXPECT_TRUE(url_request2
.status().is_success());
652 EXPECT_EQ(2, network_delegate()->completed_requests());
653 EXPECT_EQ(0, network_delegate()->error_count());
654 EXPECT_FALSE(request_delegate2
.auth_required_called());
655 EXPECT_EQ("test2.html", request_delegate2
.data_received());
658 // We should not re-use socket when there are two requests to the same host,
659 // but one is FTP and the other is HTTP.
660 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestDoNotReuseSocket
) {
661 MockWrite writes1
[] = {
662 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/first HTTP/1.1\r\n"
663 "Host: ftp.example.com\r\n"
664 "Proxy-Connection: keep-alive\r\n\r\n"),
666 MockWrite writes2
[] = {
667 MockWrite(ASYNC
, 0, "GET /second HTTP/1.1\r\n"
668 "Host: ftp.example.com\r\n"
669 "Connection: keep-alive\r\n"
671 "Accept-Encoding: gzip,deflate\r\n"
672 "Accept-Language: en-us,fr\r\n\r\n"),
674 MockRead reads1
[] = {
675 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
676 MockRead(ASYNC
, 2, "Content-Length: 10\r\n\r\n"),
677 MockRead(ASYNC
, 3, "test1.html"),
679 MockRead reads2
[] = {
680 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
681 MockRead(ASYNC
, 2, "Content-Length: 10\r\n\r\n"),
682 MockRead(ASYNC
, 3, "test2.html"),
685 AddSocket(reads1
, arraysize(reads1
), writes1
, arraysize(writes1
));
686 AddSocket(reads2
, arraysize(reads2
), writes2
, arraysize(writes2
));
688 TestDelegate request_delegate1
;
689 URLRequest
url_request1(GURL("ftp://ftp.example.com/first"),
693 url_request1
.Start();
694 ASSERT_TRUE(url_request1
.is_pending());
695 socket_data(0)->RunFor(4);
697 EXPECT_TRUE(url_request1
.status().is_success());
698 EXPECT_EQ(1, network_delegate()->completed_requests());
699 EXPECT_EQ(0, network_delegate()->error_count());
700 EXPECT_FALSE(request_delegate1
.auth_required_called());
701 EXPECT_EQ("test1.html", request_delegate1
.data_received());
703 TestDelegate request_delegate2
;
704 URLRequest
url_request2(GURL("http://ftp.example.com/second"),
708 url_request2
.Start();
709 ASSERT_TRUE(url_request2
.is_pending());
710 socket_data(1)->RunFor(4);
712 EXPECT_TRUE(url_request2
.status().is_success());
713 EXPECT_EQ(2, network_delegate()->completed_requests());
714 EXPECT_EQ(0, network_delegate()->error_count());
715 EXPECT_FALSE(request_delegate2
.auth_required_called());
716 EXPECT_EQ("test2.html", request_delegate2
.data_received());