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