Home | History | Annotate | Download | only in url_request
      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.
      4 
      5 #include "net/url_request/url_request_context_builder.h"
      6 
      7 #include <string>
      8 
      9 #include "base/basictypes.h"
     10 #include "base/compiler_specific.h"
     11 #include "base/logging.h"
     12 #include "base/strings/string_util.h"
     13 #include "base/thread_task_runner_handle.h"
     14 #include "base/threading/thread.h"
     15 #include "net/base/cache_type.h"
     16 #include "net/base/net_errors.h"
     17 #include "net/base/network_delegate.h"
     18 #include "net/cert/cert_verifier.h"
     19 #include "net/cookies/cookie_monster.h"
     20 #include "net/dns/host_resolver.h"
     21 #include "net/ftp/ftp_network_layer.h"
     22 #include "net/http/http_auth_handler_factory.h"
     23 #include "net/http/http_cache.h"
     24 #include "net/http/http_network_layer.h"
     25 #include "net/http/http_network_session.h"
     26 #include "net/http/http_server_properties_impl.h"
     27 #include "net/http/transport_security_state.h"
     28 #include "net/proxy/proxy_service.h"
     29 #include "net/ssl/ssl_config_service_defaults.h"
     30 #include "net/url_request/data_protocol_handler.h"
     31 #include "net/url_request/file_protocol_handler.h"
     32 #include "net/url_request/ftp_protocol_handler.h"
     33 #include "net/url_request/static_http_user_agent_settings.h"
     34 #include "net/url_request/url_request_context.h"
     35 #include "net/url_request/url_request_context_storage.h"
     36 #include "net/url_request/url_request_job_factory_impl.h"
     37 
     38 namespace net {
     39 
     40 namespace {
     41 
     42 class BasicNetworkDelegate : public NetworkDelegate {
     43  public:
     44   BasicNetworkDelegate() {}
     45   virtual ~BasicNetworkDelegate() {}
     46 
     47  private:
     48   virtual int OnBeforeURLRequest(URLRequest* request,
     49                                  const CompletionCallback& callback,
     50                                  GURL* new_url) OVERRIDE {
     51     return OK;
     52   }
     53 
     54   virtual int OnBeforeSendHeaders(URLRequest* request,
     55                                   const CompletionCallback& callback,
     56                                   HttpRequestHeaders* headers) OVERRIDE {
     57     return OK;
     58   }
     59 
     60   virtual void OnSendHeaders(URLRequest* request,
     61                              const HttpRequestHeaders& headers) OVERRIDE {}
     62 
     63   virtual int OnHeadersReceived(
     64       URLRequest* request,
     65       const CompletionCallback& callback,
     66       const HttpResponseHeaders* original_response_headers,
     67       scoped_refptr<HttpResponseHeaders>* override_response_headers)
     68       OVERRIDE {
     69     return OK;
     70   }
     71 
     72   virtual void OnBeforeRedirect(URLRequest* request,
     73                                 const GURL& new_location) OVERRIDE {}
     74 
     75   virtual void OnResponseStarted(URLRequest* request) OVERRIDE {}
     76 
     77   virtual void OnRawBytesRead(const URLRequest& request,
     78                               int bytes_read) OVERRIDE {}
     79 
     80   virtual void OnCompleted(URLRequest* request, bool started) OVERRIDE {}
     81 
     82   virtual void OnURLRequestDestroyed(URLRequest* request) OVERRIDE {}
     83 
     84   virtual void OnPACScriptError(int line_number,
     85                                 const base::string16& error) OVERRIDE {}
     86 
     87   virtual NetworkDelegate::AuthRequiredResponse OnAuthRequired(
     88       URLRequest* request,
     89       const AuthChallengeInfo& auth_info,
     90       const AuthCallback& callback,
     91       AuthCredentials* credentials) OVERRIDE {
     92     return NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
     93   }
     94 
     95   virtual bool OnCanGetCookies(const URLRequest& request,
     96                                const CookieList& cookie_list) OVERRIDE {
     97     return true;
     98   }
     99 
    100   virtual bool OnCanSetCookie(const URLRequest& request,
    101                               const std::string& cookie_line,
    102                               CookieOptions* options) OVERRIDE {
    103     return true;
    104   }
    105 
    106   virtual bool OnCanAccessFile(const net::URLRequest& request,
    107                                const base::FilePath& path) const OVERRIDE {
    108     return true;
    109   }
    110 
    111   virtual bool OnCanThrottleRequest(const URLRequest& request) const OVERRIDE {
    112     return false;
    113   }
    114 
    115   virtual int OnBeforeSocketStreamConnect(
    116       SocketStream* stream,
    117       const CompletionCallback& callback) OVERRIDE {
    118     return OK;
    119   }
    120 
    121   virtual void OnRequestWaitStateChange(const URLRequest& request,
    122                                         RequestWaitState state) OVERRIDE {
    123   }
    124 
    125   DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
    126 };
    127 
    128 class BasicURLRequestContext : public URLRequestContext {
    129  public:
    130   BasicURLRequestContext()
    131       : cache_thread_("Cache Thread"),
    132         file_thread_("File Thread"),
    133         storage_(this) {}
    134 
    135   URLRequestContextStorage* storage() {
    136     return &storage_;
    137   }
    138 
    139   void StartCacheThread() {
    140     cache_thread_.StartWithOptions(
    141         base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
    142   }
    143 
    144   scoped_refptr<base::MessageLoopProxy> cache_message_loop_proxy() {
    145     DCHECK(cache_thread_.IsRunning());
    146     return cache_thread_.message_loop_proxy();
    147   }
    148 
    149   void StartFileThread() {
    150     file_thread_.StartWithOptions(
    151         base::Thread::Options(base::MessageLoop::TYPE_DEFAULT, 0));
    152   }
    153 
    154   base::MessageLoop* file_message_loop() {
    155     DCHECK(file_thread_.IsRunning());
    156     return file_thread_.message_loop();
    157   }
    158 
    159   scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy() {
    160     DCHECK(file_thread_.IsRunning());
    161     return file_thread_.message_loop_proxy();
    162   }
    163 
    164  protected:
    165   virtual ~BasicURLRequestContext() {}
    166 
    167  private:
    168   base::Thread cache_thread_;
    169   base::Thread file_thread_;
    170   URLRequestContextStorage storage_;
    171   DISALLOW_COPY_AND_ASSIGN(BasicURLRequestContext);
    172 };
    173 
    174 }  // namespace
    175 
    176 URLRequestContextBuilder::HttpCacheParams::HttpCacheParams()
    177     : type(IN_MEMORY),
    178       max_size(0) {}
    179 URLRequestContextBuilder::HttpCacheParams::~HttpCacheParams() {}
    180 
    181 URLRequestContextBuilder::HttpNetworkSessionParams::HttpNetworkSessionParams()
    182     : ignore_certificate_errors(false),
    183       host_mapping_rules(NULL),
    184       http_pipelining_enabled(false),
    185       testing_fixed_http_port(0),
    186       testing_fixed_https_port(0),
    187       trusted_spdy_proxy() {}
    188 
    189 URLRequestContextBuilder::HttpNetworkSessionParams::~HttpNetworkSessionParams()
    190 {}
    191 
    192 URLRequestContextBuilder::URLRequestContextBuilder()
    193     : data_enabled_(false),
    194       file_enabled_(false),
    195 #if !defined(DISABLE_FTP_SUPPORT)
    196       ftp_enabled_(false),
    197 #endif
    198       http_cache_enabled_(true) {
    199 }
    200 
    201 URLRequestContextBuilder::~URLRequestContextBuilder() {}
    202 
    203 void URLRequestContextBuilder::set_proxy_config_service(
    204     ProxyConfigService* proxy_config_service) {
    205   proxy_config_service_.reset(proxy_config_service);
    206 }
    207 
    208 URLRequestContext* URLRequestContextBuilder::Build() {
    209   BasicURLRequestContext* context = new BasicURLRequestContext;
    210   URLRequestContextStorage* storage = context->storage();
    211 
    212   storage->set_http_user_agent_settings(new StaticHttpUserAgentSettings(
    213       accept_language_, user_agent_));
    214 
    215   if (!network_delegate_)
    216     network_delegate_.reset(new BasicNetworkDelegate);
    217   NetworkDelegate* network_delegate = network_delegate_.release();
    218   storage->set_network_delegate(network_delegate);
    219 
    220   if (!host_resolver_)
    221     host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL);
    222   storage->set_host_resolver(host_resolver_.Pass());
    223 
    224   context->StartFileThread();
    225 
    226   // TODO(willchan): Switch to using this code when
    227   // ProxyService::CreateSystemProxyConfigService()'s signature doesn't suck.
    228 #if defined(OS_LINUX) || defined(OS_ANDROID)
    229   ProxyConfigService* proxy_config_service = proxy_config_service_.release();
    230 #else
    231   ProxyConfigService* proxy_config_service = NULL;
    232   if (proxy_config_service_) {
    233     proxy_config_service = proxy_config_service_.release();
    234   } else {
    235     proxy_config_service =
    236         ProxyService::CreateSystemProxyConfigService(
    237             base::ThreadTaskRunnerHandle::Get().get(),
    238             context->file_message_loop());
    239   }
    240 #endif  // defined(OS_LINUX) || defined(OS_ANDROID)
    241   storage->set_proxy_service(
    242       ProxyService::CreateUsingSystemProxyResolver(
    243           proxy_config_service,
    244           4,  // TODO(willchan): Find a better constant somewhere.
    245           context->net_log()));
    246   storage->set_ssl_config_service(new net::SSLConfigServiceDefaults);
    247   storage->set_http_auth_handler_factory(
    248       net::HttpAuthHandlerRegistryFactory::CreateDefault(
    249           context->host_resolver()));
    250   storage->set_cookie_store(new CookieMonster(NULL, NULL));
    251   storage->set_transport_security_state(new net::TransportSecurityState());
    252   storage->set_http_server_properties(
    253       scoped_ptr<net::HttpServerProperties>(
    254           new net::HttpServerPropertiesImpl()));
    255   storage->set_cert_verifier(CertVerifier::CreateDefault());
    256 
    257   net::HttpNetworkSession::Params network_session_params;
    258   network_session_params.host_resolver = context->host_resolver();
    259   network_session_params.cert_verifier = context->cert_verifier();
    260   network_session_params.transport_security_state =
    261       context->transport_security_state();
    262   network_session_params.proxy_service = context->proxy_service();
    263   network_session_params.ssl_config_service =
    264       context->ssl_config_service();
    265   network_session_params.http_auth_handler_factory =
    266       context->http_auth_handler_factory();
    267   network_session_params.network_delegate = network_delegate;
    268   network_session_params.http_server_properties =
    269       context->http_server_properties();
    270   network_session_params.net_log = context->net_log();
    271   network_session_params.ignore_certificate_errors =
    272       http_network_session_params_.ignore_certificate_errors;
    273   network_session_params.host_mapping_rules =
    274       http_network_session_params_.host_mapping_rules;
    275   network_session_params.http_pipelining_enabled =
    276       http_network_session_params_.http_pipelining_enabled;
    277   network_session_params.testing_fixed_http_port =
    278       http_network_session_params_.testing_fixed_http_port;
    279   network_session_params.testing_fixed_https_port =
    280       http_network_session_params_.testing_fixed_https_port;
    281   network_session_params.trusted_spdy_proxy =
    282       http_network_session_params_.trusted_spdy_proxy;
    283 
    284   HttpTransactionFactory* http_transaction_factory = NULL;
    285   if (http_cache_enabled_) {
    286     network_session_params.server_bound_cert_service =
    287         context->server_bound_cert_service();
    288     HttpCache::BackendFactory* http_cache_backend = NULL;
    289     if (http_cache_params_.type == HttpCacheParams::DISK) {
    290       context->StartCacheThread();
    291       http_cache_backend = new HttpCache::DefaultBackend(
    292           DISK_CACHE,
    293           net::CACHE_BACKEND_DEFAULT,
    294           http_cache_params_.path,
    295           http_cache_params_.max_size,
    296           context->cache_message_loop_proxy().get());
    297     } else {
    298       http_cache_backend =
    299           HttpCache::DefaultBackend::InMemory(http_cache_params_.max_size);
    300     }
    301 
    302     http_transaction_factory = new HttpCache(
    303         network_session_params, http_cache_backend);
    304   } else {
    305     scoped_refptr<net::HttpNetworkSession> network_session(
    306         new net::HttpNetworkSession(network_session_params));
    307 
    308     http_transaction_factory = new HttpNetworkLayer(network_session.get());
    309   }
    310   storage->set_http_transaction_factory(http_transaction_factory);
    311 
    312   URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl;
    313   if (data_enabled_)
    314     job_factory->SetProtocolHandler("data", new DataProtocolHandler);
    315   if (file_enabled_)
    316     job_factory->SetProtocolHandler(
    317         "file", new FileProtocolHandler(context->file_message_loop_proxy()));
    318 #if !defined(DISABLE_FTP_SUPPORT)
    319   if (ftp_enabled_) {
    320     ftp_transaction_factory_.reset(
    321         new FtpNetworkLayer(context->host_resolver()));
    322     job_factory->SetProtocolHandler("ftp",
    323         new FtpProtocolHandler(ftp_transaction_factory_.get()));
    324   }
    325 #endif
    326   storage->set_job_factory(job_factory);
    327 
    328   // TODO(willchan): Support sdch.
    329 
    330   return context;
    331 }
    332 
    333 }  // namespace net
    334