Home | History | Annotate | Download | only in net
      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 "chrome/browser/net/proxy_service_factory.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/strings/string_number_conversions.h"
      9 #include "base/threading/thread.h"
     10 #include "chrome/browser/browser_process.h"
     11 #include "chrome/browser/io_thread.h"
     12 #include "chrome/browser/net/pref_proxy_config_tracker_impl.h"
     13 #include "chrome/common/chrome_switches.h"
     14 #include "chrome/common/pref_names.h"
     15 #include "content/public/browser/browser_thread.h"
     16 #include "net/base/net_log.h"
     17 #include "net/proxy/dhcp_proxy_script_fetcher_factory.h"
     18 #include "net/proxy/proxy_config_service.h"
     19 #include "net/proxy/proxy_script_fetcher_impl.h"
     20 #include "net/proxy/proxy_service.h"
     21 #include "net/proxy/proxy_service_v8.h"
     22 #include "net/url_request/url_request_context.h"
     23 
     24 #if defined(OS_CHROMEOS)
     25 #include "chrome/browser/chromeos/proxy_config_service_impl.h"
     26 #include "chromeos/network/dhcp_proxy_script_fetcher_chromeos.h"
     27 #endif  // defined(OS_CHROMEOS)
     28 
     29 #if !defined(OS_IOS)
     30 #include "net/proxy/proxy_resolver_v8.h"
     31 #endif
     32 
     33 using content::BrowserThread;
     34 
     35 // static
     36 net::ProxyConfigService* ProxyServiceFactory::CreateProxyConfigService(
     37     PrefProxyConfigTracker* tracker) {
     38   // The linux gconf-based proxy settings getter relies on being initialized
     39   // from the UI thread.
     40   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     41 
     42   scoped_ptr<net::ProxyConfigService> base_service;
     43 
     44 #if !defined(OS_CHROMEOS)
     45   // On ChromeOS, base service is NULL; chromeos::ProxyConfigServiceImpl
     46   // determines the effective proxy config to take effect in the network layer,
     47   // be it from prefs or system (which is network shill on chromeos).
     48 
     49   // For other platforms, create a baseline service that provides proxy
     50   // configuration in case nothing is configured through prefs (Note: prefs
     51   // include command line and configuration policy).
     52 
     53   // TODO(port): the IO and FILE message loops are only used by Linux.  Can
     54   // that code be moved to chrome/browser instead of being in net, so that it
     55   // can use BrowserThread instead of raw MessageLoop pointers? See bug 25354.
     56   base_service.reset(net::ProxyService::CreateSystemProxyConfigService(
     57       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
     58       BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE)));
     59 #endif  // !defined(OS_CHROMEOS)
     60 
     61   return tracker->CreateTrackingProxyConfigService(base_service.Pass())
     62       .release();
     63 }
     64 
     65 // static
     66 PrefProxyConfigTracker*
     67 ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
     68     PrefService* profile_prefs,
     69     PrefService* local_state_prefs) {
     70 #if defined(OS_CHROMEOS)
     71   return new chromeos::ProxyConfigServiceImpl(profile_prefs, local_state_prefs);
     72 #else
     73   return new PrefProxyConfigTrackerImpl(profile_prefs);
     74 #endif  // defined(OS_CHROMEOS)
     75 }
     76 
     77 // static
     78 PrefProxyConfigTracker*
     79 ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
     80     PrefService* local_state_prefs) {
     81 #if defined(OS_CHROMEOS)
     82   return new chromeos::ProxyConfigServiceImpl(NULL, local_state_prefs);
     83 #else
     84   return new PrefProxyConfigTrackerImpl(local_state_prefs);
     85 #endif  // defined(OS_CHROMEOS)
     86 }
     87 
     88 // static
     89 net::ProxyService* ProxyServiceFactory::CreateProxyService(
     90     net::NetLog* net_log,
     91     net::URLRequestContext* context,
     92     net::NetworkDelegate* network_delegate,
     93     net::ProxyConfigService* proxy_config_service,
     94     const CommandLine& command_line,
     95     bool quick_check_enabled) {
     96   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     97 
     98 #if defined(OS_IOS)
     99   bool use_v8 = false;
    100 #else
    101   bool use_v8 = !command_line.HasSwitch(switches::kWinHttpProxyResolver);
    102   if (use_v8 && command_line.HasSwitch(switches::kSingleProcess)) {
    103     // See the note about V8 multithreading in net/proxy/proxy_resolver_v8.h
    104     // to understand why we have this limitation.
    105     LOG(ERROR) << "Cannot use V8 Proxy resolver in single process mode.";
    106     use_v8 = false;  // Fallback to non-v8 implementation.
    107   }
    108 #endif  // defined(OS_IOS)
    109 
    110   size_t num_pac_threads = 0u;  // Use default number of threads.
    111 
    112   // Check the command line for an override on the number of proxy resolver
    113   // threads to use.
    114   if (command_line.HasSwitch(switches::kNumPacThreads)) {
    115     std::string s = command_line.GetSwitchValueASCII(switches::kNumPacThreads);
    116 
    117     // Parse the switch (it should be a positive integer formatted as decimal).
    118     int n;
    119     if (base::StringToInt(s, &n) && n > 0) {
    120       num_pac_threads = static_cast<size_t>(n);
    121     } else {
    122       LOG(ERROR) << "Invalid switch for number of PAC threads: " << s;
    123     }
    124   }
    125 
    126   net::ProxyService* proxy_service = NULL;
    127   if (use_v8) {
    128 #if defined(OS_IOS)
    129     NOTREACHED();
    130 #else
    131     net::ProxyResolverV8::EnsureIsolateCreated();
    132 
    133     net::DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher;
    134 #if defined(OS_CHROMEOS)
    135     dhcp_proxy_script_fetcher =
    136         new chromeos::DhcpProxyScriptFetcherChromeos(context);
    137 #else
    138     net::DhcpProxyScriptFetcherFactory dhcp_factory;
    139     dhcp_proxy_script_fetcher = dhcp_factory.Create(context);
    140 #endif
    141 
    142     proxy_service = net::CreateProxyServiceUsingV8ProxyResolver(
    143         proxy_config_service,
    144         new net::ProxyScriptFetcherImpl(context),
    145         dhcp_proxy_script_fetcher,
    146         context->host_resolver(),
    147         net_log,
    148         network_delegate);
    149 #endif  // defined(OS_IOS)
    150   } else {
    151     proxy_service = net::ProxyService::CreateUsingSystemProxyResolver(
    152         proxy_config_service,
    153         num_pac_threads,
    154         net_log);
    155   }
    156 
    157   proxy_service->set_quick_check_enabled(quick_check_enabled);
    158 
    159   return proxy_service;
    160 }
    161