Probably broke Win7 Tests (dbg)(6). http://build.chromium.org/p/chromium.win/builders...
[chromium-blink-merge.git] / net / url_request / url_request_ftp_job_unittest.cc
blob8797a3584fb44196fa4b4183dff795f3e6fa0e0b
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"
25 #include "url/gurl.h"
27 using base::ASCIIToUTF16;
29 namespace net {
31 class FtpTestURLRequestContext : public TestURLRequestContext {
32 public:
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);
45 Init();
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);
56 private:
57 FtpProtocolHandler* ftp_protocol_handler_;
60 namespace {
62 class SimpleProxyConfigService : public ProxyConfigService {
63 public:
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 {
70 observer_ = observer;
73 virtual void RemoveObserver(Observer* observer) OVERRIDE {
74 if (observer_ == observer) {
75 observer_ = NULL;
79 virtual ConfigAvailability GetLatestProxyConfig(
80 ProxyConfig* config) OVERRIDE {
81 *config = config_;
82 return CONFIG_VALID;
85 void IncrementConfigId() {
86 config_.set_id(config_.id() + 1);
87 observer_->OnProxyConfigChanged(config_, ProxyConfigService::CONFIG_VALID);
90 private:
91 ProxyConfig config_;
92 Observer* observer_;
95 // Inherit from URLRequestFtpJob to expose the priority and some
96 // other hidden functions.
97 class TestURLRequestFtpJob : public URLRequestFtpJob {
98 public:
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;
109 protected:
110 virtual ~TestURLRequestFtpJob() {}
113 class MockFtpTransactionFactory : public FtpTransactionFactory {
114 public:
115 virtual FtpTransaction* CreateTransaction() OVERRIDE {
116 return NULL;
119 virtual void Suspend(bool suspend) OVERRIDE {}
122 // Fixture for priority-related tests. Priority matters when there is
123 // an HTTP proxy.
124 class URLRequestFtpJobPriorityTest : public testing::Test {
125 protected:
126 URLRequestFtpJobPriorityTest()
127 : proxy_service_(new SimpleProxyConfigService, NULL, NULL),
128 req_(GURL("ftp://ftp.example.com"),
129 DEFAULT_PRIORITY,
130 &delegate_,
131 &context_) {
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_;
142 TestURLRequest req_;
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());
158 job->Start();
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());
174 job->Start();
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
181 // its transaction.
182 TEST_F(URLRequestFtpJobPriorityTest, SetTransactionPriority) {
183 scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
184 &req_, &ftp_factory_, &ftp_auth_cache_));
185 job->SetPriority(LOW);
186 job->Start();
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_));
199 job->Start();
201 job->SetPriority(LOW);
202 ASSERT_TRUE(network_layer_.last_transaction());
203 EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
205 job->Kill();
206 network_layer_.ClearLastTransaction();
208 // Creates a second transaction.
209 job->Start();
210 ASSERT_TRUE(network_layer_.last_transaction());
211 EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
214 class URLRequestFtpJobTest : public testing::Test {
215 public:
216 URLRequestFtpJobTest()
217 : request_context_(&socket_factory_,
218 new ProxyService(
219 new SimpleProxyConfigService, NULL, NULL),
220 &network_delegate_,
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];
247 private:
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"),
262 MockRead reads[] = {
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/"),
272 DEFAULT_PRIORITY,
273 &request_delegate,
274 request_context());
275 url_request.Start();
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(
292 new ProxyService(
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/"),
299 DEFAULT_PRIORITY,
300 &request_delegate,
301 request_context());
302 url_request.Start();
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"),
314 MockRead reads[] = {
315 // No credentials.
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/"),
327 DEFAULT_PRIORITY,
328 &request_delegate,
329 request_context());
330 url_request.Start();
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"),
353 MockRead reads[] = {
354 // No credentials.
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"),
361 // Second response.
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/"),
373 DEFAULT_PRIORITY,
374 &request_delegate,
375 request_context());
376 url_request.Start();
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"),
393 MockRead reads[] = {
394 // No credentials.
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/"),
406 DEFAULT_PRIORITY,
407 &request_delegate,
408 request_context());
409 url_request.Start();
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"),
430 MockRead reads[] = {
431 // No credentials.
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"),
438 // Second response.
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/"),
450 DEFAULT_PRIORITY,
451 &request_delegate,
452 request_context());
453 url_request.Start();
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"),
481 MockRead reads[] = {
482 // No credentials.
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"),
489 // Second response.
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"),
496 // Third response.
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(
508 url.GetOrigin(),
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());
517 url_request.Start();
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"),
538 MockRead reads[] = {
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/"),
549 DEFAULT_PRIORITY,
550 &request_delegate,
551 request_context());
552 url_request.Start();
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"),
574 MockRead reads[] = {
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/"),
583 DEFAULT_PRIORITY,
584 &request_delegate,
585 request_context());
586 url_request.Start();
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"),
614 MockRead reads[] = {
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"),
627 DEFAULT_PRIORITY,
628 &request_delegate1,
629 request_context());
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"),
644 DEFAULT_PRIORITY,
645 &request_delegate2,
646 request_context());
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"
670 "User-Agent:\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"),
690 DEFAULT_PRIORITY,
691 &request_delegate1,
692 request_context());
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"),
705 DEFAULT_PRIORITY,
706 &request_delegate2,
707 request_context());
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());
719 } // namespace
721 } // namespace net