15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_ftp_job.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_vector.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/run_loop.h"
10b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/ftp/ftp_auth_cache.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_transaction_unittest.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/proxy/mock_proxy_resolver.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/proxy/proxy_config_service.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/proxy/proxy_config_service_fixed.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/socket/socket_test_util.h"
16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/url_request/ftp_protocol_handler.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
19b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/url_request/url_request_job_factory_impl.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_test_util.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class FtpTestURLRequestContext : public TestURLRequestContext {
28b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) public:
29b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FtpTestURLRequestContext(ClientSocketFactory* socket_factory,
30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                           ProxyService* proxy_service,
31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                           NetworkDelegate* network_delegate,
32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                           FtpTransactionFactory* ftp_transaction_factory)
33b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      : TestURLRequestContext(true),
34b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        ftp_protocol_handler_(new FtpProtocolHandler(ftp_transaction_factory)) {
35b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    set_client_socket_factory(socket_factory);
36b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    context_storage_.set_proxy_service(proxy_service);
37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    set_network_delegate(network_delegate);
38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl;
39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    job_factory->SetProtocolHandler("ftp", ftp_protocol_handler_);
40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    context_storage_.set_job_factory(job_factory);
41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    Init();
42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FtpAuthCache* GetFtpAuthCache() {
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return ftp_protocol_handler_->ftp_auth_cache_.get();
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
48b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void set_proxy_service(ProxyService* proxy_service) {
49b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    context_storage_.set_proxy_service(proxy_service);
50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
52b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) private:
53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FtpProtocolHandler* ftp_protocol_handler_;
54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)};
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SimpleProxyConfigService : public ProxyConfigService {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SimpleProxyConfigService() {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Any FTP requests that ever go through HTTP paths are proxied requests.
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    config_.proxy_rules().ParseFromString("ftp=localhost");
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddObserver(Observer* observer) OVERRIDE {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer_ = observer;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void RemoveObserver(Observer* observer) OVERRIDE {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (observer_ == observer) {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      observer_ = NULL;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ConfigAvailability GetLatestProxyConfig(
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyConfig* config) OVERRIDE {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *config = config_;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return CONFIG_VALID;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void IncrementConfigId() {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    config_.set_id(config_.id() + 1);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observer_->OnProxyConfigChanged(config_, ProxyConfigService::CONFIG_VALID);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProxyConfig config_;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Observer* observer_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Inherit from URLRequestFtpJob to expose the priority and some
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// other hidden functions.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestURLRequestFtpJob : public URLRequestFtpJob {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TestURLRequestFtpJob(URLRequest* request,
96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                       FtpTransactionFactory* ftp_factory,
97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                       FtpAuthCache* ftp_auth_cache)
98b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      : URLRequestFtpJob(request, NULL, ftp_factory, ftp_auth_cache) {}
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  using URLRequestFtpJob::SetPriority;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  using URLRequestFtpJob::Start;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  using URLRequestFtpJob::Kill;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  using URLRequestFtpJob::priority;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TestURLRequestFtpJob() {}
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
109b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class MockFtpTransactionFactory : public FtpTransactionFactory {
110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) public:
111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual FtpTransaction* CreateTransaction() OVERRIDE {
112b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return NULL;
113b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
115b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void Suspend(bool suspend) OVERRIDE {}
116b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)};
117b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Fixture for priority-related tests. Priority matters when there is
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// an HTTP proxy.
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLRequestFtpJobPriorityTest : public testing::Test {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRequestFtpJobPriorityTest()
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : proxy_service_(new SimpleProxyConfigService, NULL, NULL),
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        req_(GURL("ftp://ftp.example.com"), &delegate_, &context_, NULL) {
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context_.set_proxy_service(&proxy_service_);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context_.set_http_transaction_factory(&network_layer_);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProxyService proxy_service_;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockNetworkLayer network_layer_;
131b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  MockFtpTransactionFactory ftp_factory_;
132b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FtpAuthCache ftp_auth_cache_;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestURLRequestContext context_;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestDelegate delegate_;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestURLRequest req_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Make sure that SetPriority actually sets the URLRequestFtpJob's
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// priority, both before and after start.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(URLRequestFtpJobPriorityTest, SetPriorityBasic) {
141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      &req_, &ftp_factory_, &ftp_auth_cache_));
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(DEFAULT_PRIORITY, job->priority());
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->SetPriority(LOWEST);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOWEST, job->priority());
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->SetPriority(LOW);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOW, job->priority());
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->Start();
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOW, job->priority());
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->SetPriority(MEDIUM);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(MEDIUM, job->priority());
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Make sure that URLRequestFtpJob passes on its priority to its
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// transaction on start.
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(URLRequestFtpJobPriorityTest, SetTransactionPriorityOnStart) {
161b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
162b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      &req_, &ftp_factory_, &ftp_auth_cache_));
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->SetPriority(LOW);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(network_layer_.last_transaction());
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->Start();
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(network_layer_.last_transaction());
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Make sure that URLRequestFtpJob passes on its priority updates to
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// its transaction.
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(URLRequestFtpJobPriorityTest, SetTransactionPriority) {
176b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
177b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      &req_, &ftp_factory_, &ftp_auth_cache_));
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->SetPriority(LOW);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->Start();
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(network_layer_.last_transaction());
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->SetPriority(HIGHEST);
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(HIGHEST, network_layer_.last_transaction()->priority());
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Make sure that URLRequestFtpJob passes on its priority updates to
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// newly-created transactions after the first one.
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(URLRequestFtpJobPriorityTest, SetSubsequentTransactionPriority) {
190b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<TestURLRequestFtpJob> job(new TestURLRequestFtpJob(
191b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      &req_, &ftp_factory_, &ftp_auth_cache_));
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->Start();
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->SetPriority(LOW);
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(network_layer_.last_transaction());
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->Kill();
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  network_layer_.ClearLastTransaction();
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Creates a second transaction.
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  job->Start();
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(network_layer_.last_transaction());
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(LOW, network_layer_.last_transaction()->priority());
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class URLRequestFtpJobTest : public testing::Test {
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRequestFtpJobTest()
210b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      : request_context_(&socket_factory_,
211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                         new ProxyService(
212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                             new SimpleProxyConfigService, NULL, NULL),
213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                         &network_delegate_,
214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                         &ftp_transaction_factory_) {
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~URLRequestFtpJobTest() {
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Clean up any remaining tasks that mess up unrelated tests.
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::RunLoop run_loop;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    run_loop.RunUntilIdle();
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddSocket(MockRead* reads, size_t reads_size,
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 MockWrite* writes, size_t writes_size) {
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DeterministicSocketData* socket_data = new DeterministicSocketData(
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        reads, reads_size, writes, writes_size);
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    socket_data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    socket_data->StopAfter(reads_size + writes_size - 1);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    socket_factory_.AddSocketDataProvider(socket_data);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    socket_data_.push_back(socket_data);
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
234b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  FtpTestURLRequestContext* request_context() { return &request_context_; }
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestNetworkDelegate* network_delegate() { return &network_delegate_; }
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData* socket_data(size_t index) {
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return socket_data_[index];
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<DeterministicSocketData> socket_data_;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicMockClientSocketFactory socket_factory_;
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestNetworkDelegate network_delegate_;
244b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  MockFtpTransactionFactory ftp_transaction_factory_;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FtpTestURLRequestContext request_context_;
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(URLRequestFtpJobTest, FtpProxyRequest) {
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite writes[] = {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: ftp.example.com\r\n"
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead reads[] = {
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 2, "Content-Length: 9\r\n\r\n"),
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 3, "test.html"),
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddSocket(reads, arraysize(reads), writes, arraysize(writes));
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestDelegate request_delegate;
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRequest url_request(GURL("ftp://ftp.example.com/"),
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         &request_delegate,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         request_context(),
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         network_delegate());
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_request.Start();
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(url_request.is_pending());
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  socket_data(0)->RunFor(4);
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(url_request.status().is_success());
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, network_delegate()->completed_requests());
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(request_delegate.auth_required_called());
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("test.html", request_delegate.data_received());
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Regression test for http://crbug.com/237526 .
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(URLRequestFtpJobTest, FtpProxyRequestOrphanJob) {
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Use a PAC URL so that URLRequestFtpJob's |pac_request_| field is non-NULL.
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request_context()->set_proxy_service(
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new ProxyService(
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          new ProxyConfigServiceFixed(
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              ProxyConfig::CreateFromCustomPacURL(GURL("http://foo"))),
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          new MockAsyncProxyResolver, NULL));
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestDelegate request_delegate;
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  URLRequest url_request(GURL("ftp://ftp.example.com/"),
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         &request_delegate,
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         request_context(),
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         network_delegate());
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_request.Start();
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Now |url_request| will be deleted before its completion,
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // resulting in it being orphaned. It should not crash.
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedProxyAuthNoCredentials) {
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite writes[] = {
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: ftp.example.com\r\n"
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead reads[] = {
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No credentials.
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 2, "Proxy-Authenticate: Basic "
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             "realm=\"MyRealm1\"\r\n"),
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"),
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 4, "test.html"),
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddSocket(reads, arraysize(reads), writes, arraysize(writes));
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestDelegate request_delegate;
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRequest url_request(GURL("ftp://ftp.example.com/"),
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         &request_delegate,
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         request_context(),
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         network_delegate());
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_request.Start();
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(url_request.is_pending());
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  socket_data(0)->RunFor(5);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(url_request.status().is_success());
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, network_delegate()->completed_requests());
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(request_delegate.auth_required_called());
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("test.html", request_delegate.data_received());
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedProxyAuthWithCredentials) {
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWrite writes[] = {
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Host: ftp.example.com\r\n"
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockWrite(ASYNC, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Host: ftp.example.com\r\n"
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Proxy-Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"),
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads[] = {
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // No credentials.
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 2, "Proxy-Authenticate: Basic "
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             "realm=\"MyRealm1\"\r\n"),
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"),
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 4, "test.html"),
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Second response.
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 6, "HTTP/1.1 200 OK\r\n"),
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 7, "Content-Length: 10\r\n\r\n"),
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 8, "test2.html"),
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddSocket(reads, arraysize(reads), writes, arraysize(writes));
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestDelegate request_delegate;
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request_delegate.set_credentials(
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass")));
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  URLRequest url_request(GURL("ftp://ftp.example.com/"),
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         &request_delegate,
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         request_context(),
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         network_delegate());
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_request.Start();
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(url_request.is_pending());
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  socket_data(0)->RunFor(9);
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(url_request.status().is_success());
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, network_delegate()->completed_requests());
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(request_delegate.auth_required_called());
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("test2.html", request_delegate.data_received());
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedServerAuthNoCredentials) {
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWrite writes[] = {
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Host: ftp.example.com\r\n"
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads[] = {
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // No credentials.
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 2, "WWW-Authenticate: Basic "
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             "realm=\"MyRealm1\"\r\n"),
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"),
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 4, "test.html"),
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddSocket(reads, arraysize(reads), writes, arraysize(writes));
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestDelegate request_delegate;
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  URLRequest url_request(GURL("ftp://ftp.example.com/"),
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         &request_delegate,
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         request_context(),
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         network_delegate());
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_request.Start();
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(url_request.is_pending());
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  socket_data(0)->RunFor(5);
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(url_request.status().is_success());
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, network_delegate()->completed_requests());
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(request_delegate.auth_required_called());
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("test.html", request_delegate.data_received());
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedServerAuthWithCredentials) {
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWrite writes[] = {
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Host: ftp.example.com\r\n"
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockWrite(ASYNC, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Host: ftp.example.com\r\n"
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"),
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads[] = {
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // No credentials.
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 2, "WWW-Authenticate: Basic "
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             "realm=\"MyRealm1\"\r\n"),
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"),
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 4, "test.html"),
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Second response.
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 6, "HTTP/1.1 200 OK\r\n"),
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 7, "Content-Length: 10\r\n\r\n"),
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 8, "test2.html"),
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddSocket(reads, arraysize(reads), writes, arraysize(writes));
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestDelegate request_delegate;
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request_delegate.set_credentials(
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass")));
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  URLRequest url_request(GURL("ftp://ftp.example.com/"),
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         &request_delegate,
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         request_context(),
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         network_delegate());
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_request.Start();
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(url_request.is_pending());
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  socket_data(0)->RunFor(9);
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(url_request.status().is_success());
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, network_delegate()->completed_requests());
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(request_delegate.auth_required_called());
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("test2.html", request_delegate.data_received());
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(URLRequestFtpJobTest, FtpProxyRequestNeedProxyAndServerAuth) {
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWrite writes[] = {
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Host: ftp.example.com\r\n"
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockWrite(ASYNC, 5, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Host: ftp.example.com\r\n"
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Proxy-Authorization: Basic "
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "cHJveHl1c2VyOnByb3h5cGFzcw==\r\n\r\n"),
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockWrite(ASYNC, 10, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Host: ftp.example.com\r\n"
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Proxy-Authorization: Basic "
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "cHJveHl1c2VyOnByb3h5cGFzcw==\r\n"
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              "Authorization: Basic bXl1c2VyOm15cGFzcw==\r\n\r\n"),
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads[] = {
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // No credentials.
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 2, "Proxy-Authenticate: Basic "
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             "realm=\"MyRealm1\"\r\n"),
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 3, "Content-Length: 9\r\n\r\n"),
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 4, "test.html"),
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Second response.
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 6, "HTTP/1.1 401 Unauthorized\r\n"),
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 7, "WWW-Authenticate: Basic "
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             "realm=\"MyRealm1\"\r\n"),
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 8, "Content-Length: 9\r\n\r\n"),
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 9, "test.html"),
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Third response.
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 11, "HTTP/1.1 200 OK\r\n"),
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 12, "Content-Length: 10\r\n\r\n"),
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, 13, "test2.html"),
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddSocket(reads, arraysize(reads), writes, arraysize(writes));
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL url("ftp://ftp.example.com");
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure cached FTP credentials are not used for proxy authentication.
496b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  request_context()->GetFtpAuthCache()->Add(
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      url.GetOrigin(),
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AuthCredentials(ASCIIToUTF16("userdonotuse"),
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      ASCIIToUTF16("passworddonotuse")));
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestDelegate request_delegate;
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request_delegate.set_credentials(
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AuthCredentials(ASCIIToUTF16("proxyuser"), ASCIIToUTF16("proxypass")));
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  URLRequest url_request(url,
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         &request_delegate,
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         request_context(),
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         network_delegate());
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  url_request.Start();
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(url_request.is_pending());
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  socket_data(0)->RunFor(5);
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request_delegate.set_credentials(
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AuthCredentials(ASCIIToUTF16("myuser"), ASCIIToUTF16("mypass")));
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  socket_data(0)->RunFor(9);
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(url_request.status().is_success());
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, network_delegate()->completed_requests());
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(request_delegate.auth_required_called());
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("test2.html", request_delegate.data_received());
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(URLRequestFtpJobTest, FtpProxyRequestDoNotSaveCookies) {
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite writes[] = {
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: ftp.example.com\r\n"
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead reads[] = {
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 2, "Content-Length: 9\r\n"),
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 3, "Set-Cookie: name=value\r\n\r\n"),
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 4, "test.html"),
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddSocket(reads, arraysize(reads), writes, arraysize(writes));
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestDelegate request_delegate;
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRequest url_request(GURL("ftp://ftp.example.com/"),
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         &request_delegate,
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         request_context(),
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         network_delegate());
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_request.Start();
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(url_request.is_pending());
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  socket_data(0)->RunFor(5);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(url_request.status().is_success());
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, network_delegate()->completed_requests());
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure we do not accept cookies.
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->set_cookie_count());
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(request_delegate.auth_required_called());
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("test.html", request_delegate.data_received());
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(URLRequestFtpJobTest, FtpProxyRequestDoNotFollowRedirects) {
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite writes[] = {
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(SYNCHRONOUS, 0, "GET ftp://ftp.example.com/ HTTP/1.1\r\n"
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: ftp.example.com\r\n"
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead reads[] = {
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, 1, "HTTP/1.1 302 Found\r\n"),
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 2, "Location: http://other.example.com/\r\n\r\n"),
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddSocket(reads, arraysize(reads), writes, arraysize(writes));
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestDelegate request_delegate;
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRequest url_request(GURL("ftp://ftp.example.com/"),
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         &request_delegate,
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         request_context(),
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         network_delegate());
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_request.Start();
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(url_request.is_pending());
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
58090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(url_request.is_pending());
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, request_delegate.response_started_count());
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(url_request.status().is_success());
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  socket_data(0)->RunFor(1);
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, network_delegate()->completed_requests());
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, network_delegate()->error_count());
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(url_request.status().is_success());
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_UNSAFE_REDIRECT, url_request.status().error());
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// We should re-use socket for requests using the same scheme, host, and port.
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(URLRequestFtpJobTest, FtpProxyRequestReuseSocket) {
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite writes[] = {
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/first HTTP/1.1\r\n"
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: ftp.example.com\r\n"
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, 4, "GET ftp://ftp.example.com/second HTTP/1.1\r\n"
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: ftp.example.com\r\n"
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead reads[] = {
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 2, "Content-Length: 10\r\n\r\n"),
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 3, "test1.html"),
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\n"),
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 6, "Content-Length: 10\r\n\r\n"),
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 7, "test2.html"),
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddSocket(reads, arraysize(reads), writes, arraysize(writes));
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestDelegate request_delegate1;
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRequest url_request1(GURL("ftp://ftp.example.com/first"),
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          &request_delegate1,
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          request_context(),
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          network_delegate());
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_request1.Start();
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(url_request1.is_pending());
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  socket_data(0)->RunFor(4);
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(url_request1.status().is_success());
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, network_delegate()->completed_requests());
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(request_delegate1.auth_required_called());
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("test1.html", request_delegate1.data_received());
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestDelegate request_delegate2;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRequest url_request2(GURL("ftp://ftp.example.com/second"),
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          &request_delegate2,
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          request_context(),
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          network_delegate());
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_request2.Start();
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(url_request2.is_pending());
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  socket_data(0)->RunFor(4);
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(url_request2.status().is_success());
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, network_delegate()->completed_requests());
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(request_delegate2.auth_required_called());
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("test2.html", request_delegate2.data_received());
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// We should not re-use socket when there are two requests to the same host,
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// but one is FTP and the other is HTTP.
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(URLRequestFtpJobTest, FtpProxyRequestDoNotReuseSocket) {
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite writes1[] = {
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, 0, "GET ftp://ftp.example.com/first HTTP/1.1\r\n"
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: ftp.example.com\r\n"
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite writes2[] = {
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, 0, "GET /second HTTP/1.1\r\n"
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: ftp.example.com\r\n"
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n"
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "User-Agent:\r\n"
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Accept-Encoding: gzip,deflate\r\n"
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Accept-Language: en-us,fr\r\n\r\n"),
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead reads1[] = {
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 2, "Content-Length: 10\r\n\r\n"),
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 3, "test1.html"),
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead reads2[] = {
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 2, "Content-Length: 10\r\n\r\n"),
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 3, "test2.html"),
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddSocket(reads1, arraysize(reads1), writes1, arraysize(writes1));
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddSocket(reads2, arraysize(reads2), writes2, arraysize(writes2));
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestDelegate request_delegate1;
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRequest url_request1(GURL("ftp://ftp.example.com/first"),
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          &request_delegate1,
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          request_context(),
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          network_delegate());
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_request1.Start();
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(url_request1.is_pending());
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  socket_data(0)->RunFor(4);
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(url_request1.status().is_success());
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, network_delegate()->completed_requests());
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(request_delegate1.auth_required_called());
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("test1.html", request_delegate1.data_received());
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestDelegate request_delegate2;
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLRequest url_request2(GURL("http://ftp.example.com/second"),
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          &request_delegate2,
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          request_context(),
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          network_delegate());
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_request2.Start();
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(url_request2.is_pending());
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  socket_data(1)->RunFor(4);
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(url_request2.status().is_success());
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, network_delegate()->completed_requests());
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, network_delegate()->error_count());
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(request_delegate2.auth_required_called());
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("test2.html", request_delegate2.data_received());
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
711