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_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"
28 using base::ASCIIToUTF16
;
33 class MockProxyResolverFactory
: public ProxyResolverFactory
{
35 MockProxyResolverFactory() : ProxyResolverFactory(false) {}
36 scoped_ptr
<ProxyResolver
> CreateProxyResolver() override
{
37 return make_scoped_ptr(new MockAsyncProxyResolver());
43 class FtpTestURLRequestContext
: public TestURLRequestContext
{
45 FtpTestURLRequestContext(ClientSocketFactory
* socket_factory
,
46 ProxyService
* proxy_service
,
47 NetworkDelegate
* network_delegate
,
48 FtpTransactionFactory
* ftp_transaction_factory
)
49 : TestURLRequestContext(true),
50 ftp_protocol_handler_(new FtpProtocolHandler(ftp_transaction_factory
)) {
51 set_client_socket_factory(socket_factory
);
52 context_storage_
.set_proxy_service(proxy_service
);
53 set_network_delegate(network_delegate
);
54 URLRequestJobFactoryImpl
* job_factory
= new URLRequestJobFactoryImpl
;
55 job_factory
->SetProtocolHandler("ftp", ftp_protocol_handler_
);
56 context_storage_
.set_job_factory(job_factory
);
60 FtpAuthCache
* GetFtpAuthCache() {
61 return ftp_protocol_handler_
->ftp_auth_cache_
.get();
64 void set_proxy_service(ProxyService
* proxy_service
) {
65 context_storage_
.set_proxy_service(proxy_service
);
69 FtpProtocolHandler
* ftp_protocol_handler_
;
74 class SimpleProxyConfigService
: public ProxyConfigService
{
76 SimpleProxyConfigService() {
77 // Any FTP requests that ever go through HTTP paths are proxied requests.
78 config_
.proxy_rules().ParseFromString("ftp=localhost");
81 void AddObserver(Observer
* observer
) override
{ observer_
= observer
; }
83 void RemoveObserver(Observer
* observer
) override
{
84 if (observer_
== observer
) {
89 ConfigAvailability
GetLatestProxyConfig(ProxyConfig
* config
) override
{
94 void IncrementConfigId() {
95 config_
.set_id(config_
.id() + 1);
96 observer_
->OnProxyConfigChanged(config_
, ProxyConfigService::CONFIG_VALID
);
104 // Inherit from URLRequestFtpJob to expose the priority and some
105 // other hidden functions.
106 class TestURLRequestFtpJob
: public URLRequestFtpJob
{
108 TestURLRequestFtpJob(URLRequest
* request
,
109 FtpTransactionFactory
* ftp_factory
,
110 FtpAuthCache
* ftp_auth_cache
)
111 : URLRequestFtpJob(request
, NULL
, ftp_factory
, ftp_auth_cache
) {}
113 using URLRequestFtpJob::SetPriority
;
114 using URLRequestFtpJob::Start
;
115 using URLRequestFtpJob::Kill
;
116 using URLRequestFtpJob::priority
;
119 ~TestURLRequestFtpJob() override
{}
122 class MockFtpTransactionFactory
: public FtpTransactionFactory
{
124 FtpTransaction
* CreateTransaction() override
{ return NULL
; }
126 void Suspend(bool suspend
) override
{}
129 // Fixture for priority-related tests. Priority matters when there is
131 class URLRequestFtpJobPriorityTest
: public testing::Test
{
133 URLRequestFtpJobPriorityTest()
134 : proxy_service_(new SimpleProxyConfigService
, NULL
, NULL
),
135 req_(context_
.CreateRequest(GURL("ftp://ftp.example.com"),
138 context_
.set_proxy_service(&proxy_service_
);
139 context_
.set_http_transaction_factory(&network_layer_
);
142 ProxyService proxy_service_
;
143 MockNetworkLayer network_layer_
;
144 MockFtpTransactionFactory ftp_factory_
;
145 FtpAuthCache ftp_auth_cache_
;
146 TestURLRequestContext context_
;
147 TestDelegate delegate_
;
148 scoped_ptr
<URLRequest
> req_
;
151 // Make sure that SetPriority actually sets the URLRequestFtpJob's
152 // priority, both before and after start.
153 TEST_F(URLRequestFtpJobPriorityTest
, SetPriorityBasic
) {
154 scoped_refptr
<TestURLRequestFtpJob
> job(new TestURLRequestFtpJob(
155 req_
.get(), &ftp_factory_
, &ftp_auth_cache_
));
156 EXPECT_EQ(DEFAULT_PRIORITY
, job
->priority());
158 job
->SetPriority(LOWEST
);
159 EXPECT_EQ(LOWEST
, job
->priority());
161 job
->SetPriority(LOW
);
162 EXPECT_EQ(LOW
, job
->priority());
165 EXPECT_EQ(LOW
, job
->priority());
167 job
->SetPriority(MEDIUM
);
168 EXPECT_EQ(MEDIUM
, job
->priority());
171 // Make sure that URLRequestFtpJob passes on its priority to its
172 // transaction on start.
173 TEST_F(URLRequestFtpJobPriorityTest
, SetTransactionPriorityOnStart
) {
174 scoped_refptr
<TestURLRequestFtpJob
> job(new TestURLRequestFtpJob(
175 req_
.get(), &ftp_factory_
, &ftp_auth_cache_
));
176 job
->SetPriority(LOW
);
178 EXPECT_FALSE(network_layer_
.last_transaction());
182 ASSERT_TRUE(network_layer_
.last_transaction());
183 EXPECT_EQ(LOW
, network_layer_
.last_transaction()->priority());
186 // Make sure that URLRequestFtpJob passes on its priority updates to
188 TEST_F(URLRequestFtpJobPriorityTest
, SetTransactionPriority
) {
189 scoped_refptr
<TestURLRequestFtpJob
> job(new TestURLRequestFtpJob(
190 req_
.get(), &ftp_factory_
, &ftp_auth_cache_
));
191 job
->SetPriority(LOW
);
193 ASSERT_TRUE(network_layer_
.last_transaction());
194 EXPECT_EQ(LOW
, network_layer_
.last_transaction()->priority());
196 job
->SetPriority(HIGHEST
);
197 EXPECT_EQ(HIGHEST
, network_layer_
.last_transaction()->priority());
200 // Make sure that URLRequestFtpJob passes on its priority updates to
201 // newly-created transactions after the first one.
202 TEST_F(URLRequestFtpJobPriorityTest
, SetSubsequentTransactionPriority
) {
203 scoped_refptr
<TestURLRequestFtpJob
> job(new TestURLRequestFtpJob(
204 req_
.get(), &ftp_factory_
, &ftp_auth_cache_
));
207 job
->SetPriority(LOW
);
208 ASSERT_TRUE(network_layer_
.last_transaction());
209 EXPECT_EQ(LOW
, network_layer_
.last_transaction()->priority());
212 network_layer_
.ClearLastTransaction();
214 // Creates a second transaction.
216 ASSERT_TRUE(network_layer_
.last_transaction());
217 EXPECT_EQ(LOW
, network_layer_
.last_transaction()->priority());
220 class URLRequestFtpJobTest
: public testing::Test
{
222 URLRequestFtpJobTest()
223 : request_context_(&socket_factory_
,
225 new SimpleProxyConfigService
, NULL
, NULL
),
227 &ftp_transaction_factory_
) {
230 ~URLRequestFtpJobTest() override
{
231 // Clean up any remaining tasks that mess up unrelated tests.
232 base::RunLoop run_loop
;
233 run_loop
.RunUntilIdle();
236 void AddSocket(MockRead
* reads
, size_t reads_size
,
237 MockWrite
* writes
, size_t writes_size
) {
238 DeterministicSocketData
* socket_data
= new DeterministicSocketData(
239 reads
, reads_size
, writes
, writes_size
);
240 socket_data
->set_connect_data(MockConnect(SYNCHRONOUS
, OK
));
241 socket_data
->StopAfter(reads_size
+ writes_size
- 1);
242 socket_factory_
.AddSocketDataProvider(socket_data
);
244 socket_data_
.push_back(socket_data
);
247 FtpTestURLRequestContext
* request_context() { return &request_context_
; }
248 TestNetworkDelegate
* network_delegate() { return &network_delegate_
; }
249 DeterministicSocketData
* socket_data(size_t index
) {
250 return socket_data_
[index
];
254 ScopedVector
<DeterministicSocketData
> socket_data_
;
255 DeterministicMockClientSocketFactory socket_factory_
;
256 TestNetworkDelegate network_delegate_
;
257 MockFtpTransactionFactory ftp_transaction_factory_
;
259 FtpTestURLRequestContext request_context_
;
262 TEST_F(URLRequestFtpJobTest
, FtpProxyRequest
) {
263 MockWrite writes
[] = {
264 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
265 "Host: ftp.example.com\r\n"
266 "Proxy-Connection: keep-alive\r\n\r\n"),
269 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
270 MockRead(ASYNC
, 2, "Content-Length: 9\r\n\r\n"),
271 MockRead(ASYNC
, 3, "test.html"),
274 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
276 TestDelegate request_delegate
;
277 scoped_ptr
<URLRequest
> url_request(request_context()->CreateRequest(
278 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY
, &request_delegate
));
279 url_request
->Start();
280 ASSERT_TRUE(url_request
->is_pending());
281 socket_data(0)->RunFor(4);
283 EXPECT_TRUE(url_request
->status().is_success());
284 EXPECT_TRUE(url_request
->proxy_server().Equals(
285 net::HostPortPair::FromString("localhost:80")));
286 EXPECT_EQ(1, network_delegate()->completed_requests());
287 EXPECT_EQ(0, network_delegate()->error_count());
288 EXPECT_FALSE(request_delegate
.auth_required_called());
289 EXPECT_EQ("test.html", request_delegate
.data_received());
292 // Regression test for http://crbug.com/237526 .
293 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestOrphanJob
) {
294 // Use a PAC URL so that URLRequestFtpJob's |pac_request_| field is non-NULL.
295 request_context()->set_proxy_service(new ProxyService(
296 new ProxyConfigServiceFixed(
297 ProxyConfig::CreateFromCustomPacURL(GURL("http://foo"))),
298 make_scoped_ptr(new MockProxyResolverFactory
), NULL
));
300 TestDelegate request_delegate
;
301 scoped_ptr
<URLRequest
> url_request(request_context()->CreateRequest(
302 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY
, &request_delegate
));
303 url_request
->Start();
305 // Now |url_request| will be deleted before its completion,
306 // resulting in it being orphaned. It should not crash.
309 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestNeedProxyAuthNoCredentials
) {
310 MockWrite writes
[] = {
311 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
312 "Host: ftp.example.com\r\n"
313 "Proxy-Connection: keep-alive\r\n\r\n"),
317 MockRead(ASYNC
, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
318 MockRead(ASYNC
, 2, "Proxy-Authenticate: Basic "
319 "realm=\"MyRealm1\"\r\n"),
320 MockRead(ASYNC
, 3, "Content-Length: 9\r\n\r\n"),
321 MockRead(ASYNC
, 4, "test.html"),
324 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
326 TestDelegate request_delegate
;
327 scoped_ptr
<URLRequest
> url_request(request_context()->CreateRequest(
328 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY
, &request_delegate
));
329 url_request
->Start();
330 ASSERT_TRUE(url_request
->is_pending());
331 socket_data(0)->RunFor(5);
333 EXPECT_TRUE(url_request
->status().is_success());
334 EXPECT_TRUE(url_request
->proxy_server().Equals(
335 net::HostPortPair::FromString("localhost:80")));
336 EXPECT_EQ(1, network_delegate()->completed_requests());
337 EXPECT_EQ(0, network_delegate()->error_count());
338 EXPECT_TRUE(request_delegate
.auth_required_called());
339 EXPECT_EQ("test.html", request_delegate
.data_received());
342 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestNeedProxyAuthWithCredentials
) {
343 MockWrite writes
[] = {
344 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
345 "Host: ftp.example.com\r\n"
346 "Proxy-Connection: keep-alive\r\n\r\n"),
347 MockWrite(ASYNC
, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
348 "Host: ftp.example.com\r\n"
349 "Proxy-Connection: keep-alive\r\n"
350 "Proxy-Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"),
354 MockRead(ASYNC
, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
355 MockRead(ASYNC
, 2, "Proxy-Authenticate: Basic "
356 "realm=\"MyRealm1\"\r\n"),
357 MockRead(ASYNC
, 3, "Content-Length: 9\r\n\r\n"),
358 MockRead(ASYNC
, 4, "test.html"),
361 MockRead(ASYNC
, 6, "HTTP/1.1 200 OK\r\n"),
362 MockRead(ASYNC
, 7, "Content-Length: 10\r\n\r\n"),
363 MockRead(ASYNC
, 8, "test2.html"),
366 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
368 TestDelegate request_delegate
;
369 request_delegate
.set_credentials(
370 AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass")));
371 scoped_ptr
<URLRequest
> url_request(request_context()->CreateRequest(
372 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY
, &request_delegate
));
373 url_request
->Start();
374 ASSERT_TRUE(url_request
->is_pending());
375 socket_data(0)->RunFor(9);
377 EXPECT_TRUE(url_request
->status().is_success());
378 EXPECT_EQ(1, network_delegate()->completed_requests());
379 EXPECT_EQ(0, network_delegate()->error_count());
380 EXPECT_TRUE(request_delegate
.auth_required_called());
381 EXPECT_EQ("test2.html", request_delegate
.data_received());
384 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestNeedServerAuthNoCredentials
) {
385 MockWrite writes
[] = {
386 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
387 "Host: ftp.example.com\r\n"
388 "Proxy-Connection: keep-alive\r\n\r\n"),
392 MockRead(ASYNC
, 1, "HTTP/1.1 401 Unauthorized\r\n"),
393 MockRead(ASYNC
, 2, "WWW-Authenticate: Basic "
394 "realm=\"MyRealm1\"\r\n"),
395 MockRead(ASYNC
, 3, "Content-Length: 9\r\n\r\n"),
396 MockRead(ASYNC
, 4, "test.html"),
399 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
401 TestDelegate request_delegate
;
402 scoped_ptr
<URLRequest
> url_request(request_context()->CreateRequest(
403 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY
, &request_delegate
));
404 url_request
->Start();
405 ASSERT_TRUE(url_request
->is_pending());
406 socket_data(0)->RunFor(5);
408 EXPECT_TRUE(url_request
->status().is_success());
409 EXPECT_EQ(1, network_delegate()->completed_requests());
410 EXPECT_EQ(0, network_delegate()->error_count());
411 EXPECT_TRUE(request_delegate
.auth_required_called());
412 EXPECT_EQ("test.html", request_delegate
.data_received());
415 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestNeedServerAuthWithCredentials
) {
416 MockWrite writes
[] = {
417 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
418 "Host: ftp.example.com\r\n"
419 "Proxy-Connection: keep-alive\r\n\r\n"),
420 MockWrite(ASYNC
, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
421 "Host: ftp.example.com\r\n"
422 "Proxy-Connection: keep-alive\r\n"
423 "Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"),
427 MockRead(ASYNC
, 1, "HTTP/1.1 401 Unauthorized\r\n"),
428 MockRead(ASYNC
, 2, "WWW-Authenticate: Basic "
429 "realm=\"MyRealm1\"\r\n"),
430 MockRead(ASYNC
, 3, "Content-Length: 9\r\n\r\n"),
431 MockRead(ASYNC
, 4, "test.html"),
434 MockRead(ASYNC
, 6, "HTTP/1.1 200 OK\r\n"),
435 MockRead(ASYNC
, 7, "Content-Length: 10\r\n\r\n"),
436 MockRead(ASYNC
, 8, "test2.html"),
439 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
441 TestDelegate request_delegate
;
442 request_delegate
.set_credentials(
443 AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass")));
444 scoped_ptr
<URLRequest
> url_request(request_context()->CreateRequest(
445 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY
, &request_delegate
));
446 url_request
->Start();
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 scoped_ptr
<URLRequest
> url_request(request_context()->CreateRequest(
509 url
, DEFAULT_PRIORITY
, &request_delegate
));
510 url_request
->Start();
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 scoped_ptr
<URLRequest
> url_request(request_context()->CreateRequest(
542 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY
, &request_delegate
));
543 url_request
->Start();
544 ASSERT_TRUE(url_request
->is_pending());
546 socket_data(0)->RunFor(5);
548 EXPECT_TRUE(url_request
->status().is_success());
549 EXPECT_EQ(1, network_delegate()->completed_requests());
550 EXPECT_EQ(0, network_delegate()->error_count());
552 // Make sure we do not accept cookies.
553 EXPECT_EQ(0, network_delegate()->set_cookie_count());
555 EXPECT_FALSE(request_delegate
.auth_required_called());
556 EXPECT_EQ("test.html", request_delegate
.data_received());
559 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestDoNotFollowRedirects
) {
560 MockWrite writes
[] = {
561 MockWrite(SYNCHRONOUS
, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
562 "Host: ftp.example.com\r\n"
563 "Proxy-Connection: keep-alive\r\n\r\n"),
566 MockRead(SYNCHRONOUS
, 1, "HTTP/1.1 302 Found\r\n"),
567 MockRead(ASYNC
, 2, "Location: http://other.example.com/\r\n\r\n"),
570 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
572 TestDelegate request_delegate
;
573 scoped_ptr
<URLRequest
> url_request(request_context()->CreateRequest(
574 GURL("ftp://ftp.example.com/"), DEFAULT_PRIORITY
, &request_delegate
));
575 url_request
->Start();
576 EXPECT_TRUE(url_request
->is_pending());
578 base::MessageLoop::current()->RunUntilIdle();
580 EXPECT_TRUE(url_request
->is_pending());
581 EXPECT_EQ(0, request_delegate
.response_started_count());
582 EXPECT_EQ(0, network_delegate()->error_count());
583 ASSERT_TRUE(url_request
->status().is_success());
585 socket_data(0)->RunFor(1);
587 EXPECT_EQ(1, network_delegate()->completed_requests());
588 EXPECT_EQ(1, network_delegate()->error_count());
589 EXPECT_FALSE(url_request
->status().is_success());
590 EXPECT_EQ(ERR_UNSAFE_REDIRECT
, url_request
->status().error());
593 // We should re-use socket for requests using the same scheme, host, and port.
594 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestReuseSocket
) {
595 MockWrite writes
[] = {
596 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/first HTTP/1.1\r\n"
597 "Host: ftp.example.com\r\n"
598 "Proxy-Connection: keep-alive\r\n\r\n"),
599 MockWrite(ASYNC
, 4, "GET ftp://ftp.example.com/second HTTP/1.1\r\n"
600 "Host: ftp.example.com\r\n"
601 "Proxy-Connection: keep-alive\r\n\r\n"),
604 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
605 MockRead(ASYNC
, 2, "Content-Length: 10\r\n\r\n"),
606 MockRead(ASYNC
, 3, "test1.html"),
607 MockRead(ASYNC
, 5, "HTTP/1.1 200 OK\r\n"),
608 MockRead(ASYNC
, 6, "Content-Length: 10\r\n\r\n"),
609 MockRead(ASYNC
, 7, "test2.html"),
612 AddSocket(reads
, arraysize(reads
), writes
, arraysize(writes
));
614 TestDelegate request_delegate1
;
616 scoped_ptr
<URLRequest
> url_request1(
617 request_context()->CreateRequest(GURL("ftp://ftp.example.com/first"),
618 DEFAULT_PRIORITY
, &request_delegate1
));
619 url_request1
->Start();
620 ASSERT_TRUE(url_request1
->is_pending());
621 socket_data(0)->RunFor(4);
623 EXPECT_TRUE(url_request1
->status().is_success());
624 EXPECT_TRUE(url_request1
->proxy_server().Equals(
625 net::HostPortPair::FromString("localhost:80")));
626 EXPECT_EQ(1, network_delegate()->completed_requests());
627 EXPECT_EQ(0, network_delegate()->error_count());
628 EXPECT_FALSE(request_delegate1
.auth_required_called());
629 EXPECT_EQ("test1.html", request_delegate1
.data_received());
631 TestDelegate request_delegate2
;
632 scoped_ptr
<URLRequest
> url_request2(
633 request_context()->CreateRequest(GURL("ftp://ftp.example.com/second"),
634 DEFAULT_PRIORITY
, &request_delegate2
));
635 url_request2
->Start();
636 ASSERT_TRUE(url_request2
->is_pending());
637 socket_data(0)->RunFor(4);
639 EXPECT_TRUE(url_request2
->status().is_success());
640 EXPECT_EQ(2, network_delegate()->completed_requests());
641 EXPECT_EQ(0, network_delegate()->error_count());
642 EXPECT_FALSE(request_delegate2
.auth_required_called());
643 EXPECT_EQ("test2.html", request_delegate2
.data_received());
646 // We should not re-use socket when there are two requests to the same host,
647 // but one is FTP and the other is HTTP.
648 TEST_F(URLRequestFtpJobTest
, FtpProxyRequestDoNotReuseSocket
) {
649 MockWrite writes1
[] = {
650 MockWrite(ASYNC
, 0, "GET ftp://ftp.example.com/first HTTP/1.1\r\n"
651 "Host: ftp.example.com\r\n"
652 "Proxy-Connection: keep-alive\r\n\r\n"),
654 MockWrite writes2
[] = {
655 MockWrite(ASYNC
, 0, "GET /second HTTP/1.1\r\n"
656 "Host: ftp.example.com\r\n"
657 "Connection: keep-alive\r\n"
659 "Accept-Encoding: gzip, deflate\r\n"
660 "Accept-Language: en-us,fr\r\n\r\n"),
662 MockRead reads1
[] = {
663 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
664 MockRead(ASYNC
, 2, "Content-Length: 10\r\n\r\n"),
665 MockRead(ASYNC
, 3, "test1.html"),
667 MockRead reads2
[] = {
668 MockRead(ASYNC
, 1, "HTTP/1.1 200 OK\r\n"),
669 MockRead(ASYNC
, 2, "Content-Length: 10\r\n\r\n"),
670 MockRead(ASYNC
, 3, "test2.html"),
673 AddSocket(reads1
, arraysize(reads1
), writes1
, arraysize(writes1
));
674 AddSocket(reads2
, arraysize(reads2
), writes2
, arraysize(writes2
));
676 TestDelegate request_delegate1
;
677 scoped_ptr
<URLRequest
> url_request1(
678 request_context()->CreateRequest(GURL("ftp://ftp.example.com/first"),
679 DEFAULT_PRIORITY
, &request_delegate1
));
680 url_request1
->Start();
681 ASSERT_TRUE(url_request1
->is_pending());
682 socket_data(0)->RunFor(4);
684 EXPECT_TRUE(url_request1
->status().is_success());
685 EXPECT_EQ(1, network_delegate()->completed_requests());
686 EXPECT_EQ(0, network_delegate()->error_count());
687 EXPECT_FALSE(request_delegate1
.auth_required_called());
688 EXPECT_EQ("test1.html", request_delegate1
.data_received());
690 TestDelegate request_delegate2
;
691 scoped_ptr
<URLRequest
> url_request2(
692 request_context()->CreateRequest(GURL("http://ftp.example.com/second"),
693 DEFAULT_PRIORITY
, &request_delegate2
));
694 url_request2
->Start();
695 ASSERT_TRUE(url_request2
->is_pending());
696 socket_data(1)->RunFor(4);
698 EXPECT_TRUE(url_request2
->status().is_success());
699 EXPECT_EQ(2, network_delegate()->completed_requests());
700 EXPECT_EQ(0, network_delegate()->error_count());
701 EXPECT_FALSE(request_delegate2
.auth_required_called());
702 EXPECT_EQ("test2.html", request_delegate2
.data_received());