[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 1 | // Copyright (c) 2010 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/io_thread.h" |
[email protected] | e83326f | 2010-07-31 17:29:25 | [diff] [blame^] | 6 | |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 7 | #include "base/command_line.h" |
| 8 | #include "base/leak_tracker.h" |
| 9 | #include "base/logging.h" |
[email protected] | e83326f | 2010-07-31 17:29:25 | [diff] [blame^] | 10 | #include "base/string_number_conversions.h" |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 11 | #include "chrome/browser/browser_process.h" |
| 12 | #include "chrome/browser/chrome_thread.h" |
[email protected] | 1082b1d | 2010-03-30 00:31:22 | [diff] [blame] | 13 | #include "chrome/browser/gpu_process_host.h" |
[email protected] | 9e743cd | 2010-03-16 07:03:53 | [diff] [blame] | 14 | #include "chrome/browser/net/chrome_net_log.h" |
[email protected] | 3530cd9 | 2010-06-27 06:22:01 | [diff] [blame] | 15 | #include "chrome/browser/net/predictor_api.h" |
[email protected] | 9e743cd | 2010-03-16 07:03:53 | [diff] [blame] | 16 | #include "chrome/browser/net/passive_log_collector.h" |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 17 | #include "chrome/common/chrome_switches.h" |
[email protected] | 68d2a05f | 2010-05-07 21:39:55 | [diff] [blame] | 18 | #include "chrome/common/net/url_fetcher.h" |
[email protected] | 9087aa3 | 2010-02-18 08:03:38 | [diff] [blame] | 19 | #include "net/base/mapped_host_resolver.h" |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 20 | #include "net/base/host_cache.h" |
| 21 | #include "net/base/host_resolver.h" |
[email protected] | f2d8c421 | 2010-02-02 00:56:35 | [diff] [blame] | 22 | #include "net/base/host_resolver_impl.h" |
[email protected] | 32eaa33 | 2010-02-08 22:15:54 | [diff] [blame] | 23 | #include "net/base/net_util.h" |
[email protected] | eb3cac7 | 2010-02-26 21:07:45 | [diff] [blame] | 24 | #include "net/http/http_auth_filter.h" |
[email protected] | fa55e19 | 2010-02-15 14:25:50 | [diff] [blame] | 25 | #include "net/http/http_auth_handler_factory.h" |
[email protected] | e5ae96a | 2010-04-14 20:12:45 | [diff] [blame] | 26 | #include "net/http/http_auth_handler_negotiate.h" |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 27 | |
| 28 | namespace { |
| 29 | |
[email protected] | 66761b95 | 2010-06-25 21:30:38 | [diff] [blame] | 30 | net::HostResolver* CreateGlobalHostResolver() { |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 31 | const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
[email protected] | 962b9821 | 2010-07-17 03:37:51 | [diff] [blame] | 32 | |
| 33 | size_t parallelism = net::HostResolver::kDefaultParallelism; |
| 34 | |
| 35 | // Use the concurrency override from the command-line, if any. |
| 36 | if (command_line.HasSwitch(switches::kHostResolverParallelism)) { |
| 37 | std::string s = |
| 38 | command_line.GetSwitchValueASCII(switches::kHostResolverParallelism); |
| 39 | |
| 40 | // Parse the switch (it should be a positive integer formatted as decimal). |
| 41 | int n; |
[email protected] | e83326f | 2010-07-31 17:29:25 | [diff] [blame^] | 42 | if (base::StringToInt(s, &n) && n > 0) { |
[email protected] | 962b9821 | 2010-07-17 03:37:51 | [diff] [blame] | 43 | parallelism = static_cast<size_t>(n); |
| 44 | } else { |
| 45 | LOG(ERROR) << "Invalid switch for host resolver parallelism: " << s; |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | net::HostResolver* global_host_resolver = |
| 50 | net::CreateSystemHostResolver(parallelism); |
[email protected] | 9087aa3 | 2010-02-18 08:03:38 | [diff] [blame] | 51 | |
[email protected] | 0f8f1b43 | 2010-03-16 19:06:03 | [diff] [blame] | 52 | // Determine if we should disable IPv6 support. |
[email protected] | 9087aa3 | 2010-02-18 08:03:38 | [diff] [blame] | 53 | if (!command_line.HasSwitch(switches::kEnableIPv6)) { |
[email protected] | 0f8f1b43 | 2010-03-16 19:06:03 | [diff] [blame] | 54 | if (command_line.HasSwitch(switches::kDisableIPv6)) { |
[email protected] | 46f6e20 | 2010-02-26 06:07:25 | [diff] [blame] | 55 | global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4); |
[email protected] | 0f8f1b43 | 2010-03-16 19:06:03 | [diff] [blame] | 56 | } else { |
| 57 | net::HostResolverImpl* host_resolver_impl = |
| 58 | global_host_resolver->GetAsHostResolverImpl(); |
| 59 | if (host_resolver_impl != NULL) { |
| 60 | // (optionally) Use probe to decide if support is warranted. |
[email protected] | 26b0f37 | 2010-03-24 21:58:31 | [diff] [blame] | 61 | bool use_ipv6_probe = true; |
[email protected] | 0f8f1b43 | 2010-03-16 19:06:03 | [diff] [blame] | 62 | |
[email protected] | 26b0f37 | 2010-03-24 21:58:31 | [diff] [blame] | 63 | #if defined(OS_WIN) |
[email protected] | 0f8f1b43 | 2010-03-16 19:06:03 | [diff] [blame] | 64 | // Measure impact of probing to allow IPv6. |
| 65 | // Some users report confused OS handling of IPv6, leading to large |
| 66 | // latency. If we can show that IPv6 is not supported, then disabliing |
[email protected] | 26b0f37 | 2010-03-24 21:58:31 | [diff] [blame] | 67 | // it will work around such problems. This is the test of the probe. |
[email protected] | 0f8f1b43 | 2010-03-16 19:06:03 | [diff] [blame] | 68 | const FieldTrial::Probability kDivisor = 100; |
| 69 | const FieldTrial::Probability kProbability = 50; // 50% probability. |
| 70 | FieldTrial* trial = new FieldTrial("IPv6_Probe", kDivisor); |
| 71 | int skip_group = trial->AppendGroup("_IPv6_probe_skipped", |
| 72 | kProbability); |
| 73 | trial->AppendGroup("_IPv6_probe_done", |
| 74 | FieldTrial::kAllRemainingProbability); |
[email protected] | 26b0f37 | 2010-03-24 21:58:31 | [diff] [blame] | 75 | use_ipv6_probe = (trial->group() != skip_group); |
| 76 | #endif |
| 77 | |
[email protected] | 0f8f1b43 | 2010-03-16 19:06:03 | [diff] [blame] | 78 | if (use_ipv6_probe) |
| 79 | host_resolver_impl->ProbeIPv6Support(); |
| 80 | } |
| 81 | } |
[email protected] | 9087aa3 | 2010-02-18 08:03:38 | [diff] [blame] | 82 | } |
| 83 | |
[email protected] | 9087aa3 | 2010-02-18 08:03:38 | [diff] [blame] | 84 | // If hostname remappings were specified on the command-line, layer these |
| 85 | // rules on top of the real host resolver. This allows forwarding all requests |
| 86 | // through a designated test server. |
[email protected] | 0f8f1b43 | 2010-03-16 19:06:03 | [diff] [blame] | 87 | if (!command_line.HasSwitch(switches::kHostResolverRules)) |
| 88 | return global_host_resolver; |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 89 | |
[email protected] | 0f8f1b43 | 2010-03-16 19:06:03 | [diff] [blame] | 90 | net::MappedHostResolver* remapped_resolver = |
| 91 | new net::MappedHostResolver(global_host_resolver); |
| 92 | remapped_resolver->SetRulesFromString( |
| 93 | command_line.GetSwitchValueASCII(switches::kHostResolverRules)); |
| 94 | return remapped_resolver; |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 95 | } |
| 96 | |
[email protected] | 58bc704 | 2010-07-07 18:04:14 | [diff] [blame] | 97 | class LoggingNetworkChangeObserver |
| 98 | : public net::NetworkChangeNotifier::Observer { |
| 99 | public: |
| 100 | // |net_log| must remain valid throughout our lifetime. |
| 101 | explicit LoggingNetworkChangeObserver(net::NetLog* net_log) |
| 102 | : net_log_(net_log) { |
| 103 | net::NetworkChangeNotifier::AddObserver(this); |
| 104 | } |
| 105 | |
| 106 | ~LoggingNetworkChangeObserver() { |
| 107 | net::NetworkChangeNotifier::RemoveObserver(this); |
| 108 | } |
| 109 | |
| 110 | virtual void OnIPAddressChanged() { |
| 111 | LOG(INFO) << "Observed a change to the network IP addresses"; |
| 112 | |
| 113 | net::NetLog::Source global_source; |
| 114 | |
| 115 | // TODO(eroman): We shouldn't need to assign an ID to this source, since |
| 116 | // conceptually it is the "global event stream". However |
| 117 | // currently the javascript does a grouping on source id, so |
| 118 | // the display will look weird if we don't give it one. |
| 119 | global_source.id = net_log_->NextID(); |
| 120 | |
| 121 | net_log_->AddEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSSES_CHANGED, |
| 122 | base::TimeTicks::Now(), |
| 123 | global_source, |
| 124 | net::NetLog::PHASE_NONE, |
| 125 | NULL); |
| 126 | } |
| 127 | |
| 128 | private: |
| 129 | net::NetLog* net_log_; |
| 130 | DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver); |
| 131 | }; |
| 132 | |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 133 | } // namespace |
| 134 | |
| 135 | // The IOThread object must outlive any tasks posted to the IO thread before the |
| 136 | // Quit task. |
[email protected] | c56428f2 | 2010-06-16 02:17:23 | [diff] [blame] | 137 | DISABLE_RUNNABLE_METHOD_REFCOUNT(IOThread); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 138 | |
| 139 | IOThread::IOThread() |
| 140 | : BrowserProcessSubThread(ChromeThread::IO), |
[email protected] | d13c327 | 2010-02-04 00:24:51 | [diff] [blame] | 141 | globals_(NULL), |
[email protected] | c5629c3 | 2010-06-23 01:22:43 | [diff] [blame] | 142 | speculative_interceptor_(NULL), |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 143 | prefetch_observer_(NULL), |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 144 | predictor_(NULL) {} |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 145 | |
| 146 | IOThread::~IOThread() { |
| 147 | // We cannot rely on our base class to stop the thread since we want our |
| 148 | // CleanUp function to run. |
| 149 | Stop(); |
[email protected] | d13c327 | 2010-02-04 00:24:51 | [diff] [blame] | 150 | DCHECK(!globals_); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 151 | } |
| 152 | |
[email protected] | d13c327 | 2010-02-04 00:24:51 | [diff] [blame] | 153 | IOThread::Globals* IOThread::globals() { |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 154 | DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
[email protected] | d13c327 | 2010-02-04 00:24:51 | [diff] [blame] | 155 | return globals_; |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 156 | } |
| 157 | |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 158 | void IOThread::InitNetworkPredictor( |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 159 | bool prefetching_enabled, |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 160 | base::TimeDelta max_dns_queue_delay, |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 161 | size_t max_concurrent, |
[email protected] | c5629c3 | 2010-06-23 01:22:43 | [diff] [blame] | 162 | const chrome_common_net::UrlList& startup_urls, |
[email protected] | 760d970a | 2010-05-18 00:39:18 | [diff] [blame] | 163 | ListValue* referral_list, |
| 164 | bool preconnect_enabled) { |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 165 | DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
| 166 | message_loop()->PostTask( |
| 167 | FROM_HERE, |
| 168 | NewRunnableMethod( |
| 169 | this, |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 170 | &IOThread::InitNetworkPredictorOnIOThread, |
| 171 | prefetching_enabled, max_dns_queue_delay, max_concurrent, |
[email protected] | c5629c3 | 2010-06-23 01:22:43 | [diff] [blame] | 172 | startup_urls, referral_list, preconnect_enabled)); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 173 | } |
| 174 | |
| 175 | void IOThread::ChangedToOnTheRecord() { |
| 176 | DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
| 177 | message_loop()->PostTask( |
| 178 | FROM_HERE, |
| 179 | NewRunnableMethod( |
| 180 | this, |
| 181 | &IOThread::ChangedToOnTheRecordOnIOThread)); |
| 182 | } |
| 183 | |
| 184 | void IOThread::Init() { |
| 185 | BrowserProcessSubThread::Init(); |
| 186 | |
[email protected] | d13c327 | 2010-02-04 00:24:51 | [diff] [blame] | 187 | DCHECK(!globals_); |
| 188 | globals_ = new Globals; |
| 189 | |
[email protected] | aa92ba2 | 2010-06-21 23:17:24 | [diff] [blame] | 190 | globals_->net_log.reset(new ChromeNetLog()); |
[email protected] | 58bc704 | 2010-07-07 18:04:14 | [diff] [blame] | 191 | |
| 192 | // Add an observer that will emit network change events to the ChromeNetLog. |
| 193 | // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be |
| 194 | // logging the network change before other IO thread consumers respond to it. |
| 195 | network_change_observer_.reset( |
| 196 | new LoggingNetworkChangeObserver(globals_->net_log.get())); |
| 197 | |
[email protected] | 66761b95 | 2010-06-25 21:30:38 | [diff] [blame] | 198 | globals_->host_resolver = CreateGlobalHostResolver(); |
[email protected] | 65d3438 | 2010-07-01 18:12:26 | [diff] [blame] | 199 | globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory( |
| 200 | globals_->host_resolver)); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 201 | } |
| 202 | |
[email protected] | 2a92cd9 | 2010-04-27 00:01:41 | [diff] [blame] | 203 | void IOThread::CleanUp() { |
[email protected] | 58bc704 | 2010-07-07 18:04:14 | [diff] [blame] | 204 | // This must be reset before the ChromeNetLog is destroyed. |
| 205 | network_change_observer_.reset(); |
| 206 | |
[email protected] | 325a71f | 2010-05-21 23:05:27 | [diff] [blame] | 207 | // If any child processes are still running, terminate them and |
[email protected] | d27893f6 | 2010-07-03 05:47:42 | [diff] [blame] | 208 | // and delete the BrowserChildProcessHost instances to release whatever |
[email protected] | 325a71f | 2010-05-21 23:05:27 | [diff] [blame] | 209 | // IO thread only resources they are referencing. |
[email protected] | d27893f6 | 2010-07-03 05:47:42 | [diff] [blame] | 210 | BrowserChildProcessHost::TerminateAll(); |
[email protected] | 325a71f | 2010-05-21 23:05:27 | [diff] [blame] | 211 | |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 212 | // Not initialized in Init(). May not be initialized. |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 213 | if (predictor_) { |
| 214 | predictor_->Shutdown(); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 215 | |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 216 | // TODO(willchan): Stop reference counting Predictor. It's owned by |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 217 | // IOThread now. |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 218 | predictor_->Release(); |
| 219 | predictor_ = NULL; |
| 220 | chrome_browser_net::FreePredictorResources(); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 221 | } |
| 222 | |
[email protected] | c5629c3 | 2010-06-23 01:22:43 | [diff] [blame] | 223 | // Deletion will unregister this interceptor. |
| 224 | delete speculative_interceptor_; |
| 225 | speculative_interceptor_ = NULL; |
| 226 | |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 227 | // Not initialized in Init(). May not be initialized. |
| 228 | if (prefetch_observer_) { |
[email protected] | d13c327 | 2010-02-04 00:24:51 | [diff] [blame] | 229 | globals_->host_resolver->RemoveObserver(prefetch_observer_); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 230 | delete prefetch_observer_; |
| 231 | prefetch_observer_ = NULL; |
| 232 | } |
| 233 | |
[email protected] | e4d2dd82 | 2010-02-05 20:57:33 | [diff] [blame] | 234 | // TODO(eroman): hack for http://crbug.com/15513 |
[email protected] | 970210c | 2010-02-19 20:27:02 | [diff] [blame] | 235 | if (globals_->host_resolver->GetAsHostResolverImpl()) { |
| 236 | globals_->host_resolver.get()->GetAsHostResolverImpl()->Shutdown(); |
[email protected] | e4d2dd82 | 2010-02-05 20:57:33 | [diff] [blame] | 237 | } |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 238 | |
[email protected] | 2a92cd9 | 2010-04-27 00:01:41 | [diff] [blame] | 239 | // We will delete the NetLog as part of CleanUpAfterMessageLoopDestruction() |
| 240 | // in case any of the message loop destruction observers try to access it. |
| 241 | deferred_net_log_to_delete_.reset(globals_->net_log.release()); |
| 242 | |
[email protected] | d13c327 | 2010-02-04 00:24:51 | [diff] [blame] | 243 | delete globals_; |
| 244 | globals_ = NULL; |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 245 | |
[email protected] | 7119743 | 2010-06-15 03:09:12 | [diff] [blame] | 246 | // URLRequest instances must NOT outlive the IO thread. |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 247 | base::LeakTracker<URLRequest>::CheckForLeaks(); |
| 248 | |
[email protected] | 2a92cd9 | 2010-04-27 00:01:41 | [diff] [blame] | 249 | BrowserProcessSubThread::CleanUp(); |
| 250 | } |
| 251 | |
| 252 | void IOThread::CleanUpAfterMessageLoopDestruction() { |
| 253 | // TODO(eroman): get rid of this special case for 39723. If we could instead |
| 254 | // have a method that runs after the message loop destruction obsevers have |
| 255 | // run, but before the message loop itself is destroyed, we could safely |
| 256 | // combine the two cleanups. |
| 257 | deferred_net_log_to_delete_.reset(); |
[email protected] | 9aa33e8 | 2010-04-15 00:15:39 | [diff] [blame] | 258 | BrowserProcessSubThread::CleanUpAfterMessageLoopDestruction(); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 259 | } |
| 260 | |
[email protected] | 65d3438 | 2010-07-01 18:12:26 | [diff] [blame] | 261 | net::HttpAuthHandlerFactory* IOThread::CreateDefaultAuthHandlerFactory( |
| 262 | net::HostResolver* resolver) { |
[email protected] | b4955e7d | 2010-04-16 20:22:30 | [diff] [blame] | 263 | net::HttpAuthFilterWhitelist* auth_filter = NULL; |
[email protected] | eb3cac7 | 2010-02-26 21:07:45 | [diff] [blame] | 264 | |
| 265 | // Get the whitelist information from the command line, create an |
| 266 | // HttpAuthFilterWhitelist, and attach it to the HttpAuthHandlerFactory. |
| 267 | const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 268 | |
[email protected] | eb3cac7 | 2010-02-26 21:07:45 | [diff] [blame] | 269 | if (command_line.HasSwitch(switches::kAuthServerWhitelist)) { |
[email protected] | 8f777e5 | 2010-03-30 20:48:15 | [diff] [blame] | 270 | std::string auth_server_whitelist = |
[email protected] | eb3cac7 | 2010-02-26 21:07:45 | [diff] [blame] | 271 | command_line.GetSwitchValueASCII(switches::kAuthServerWhitelist); |
[email protected] | 8f777e5 | 2010-03-30 20:48:15 | [diff] [blame] | 272 | |
[email protected] | b4955e7d | 2010-04-16 20:22:30 | [diff] [blame] | 273 | // Create a whitelist filter. |
| 274 | auth_filter = new net::HttpAuthFilterWhitelist(); |
| 275 | auth_filter->SetWhitelist(auth_server_whitelist); |
[email protected] | eb3cac7 | 2010-02-26 21:07:45 | [diff] [blame] | 276 | } |
| 277 | |
[email protected] | aef0427 | 2010-06-28 18:03:04 | [diff] [blame] | 278 | // Set the flag that enables or disables the Negotiate auth handler. |
[email protected] | aef0427 | 2010-06-28 18:03:04 | [diff] [blame] | 279 | static const bool kNegotiateAuthEnabledDefault = true; |
[email protected] | 9bc3b4a | 2010-07-20 02:30:49 | [diff] [blame] | 280 | |
[email protected] | aef0427 | 2010-06-28 18:03:04 | [diff] [blame] | 281 | bool negotiate_auth_enabled = kNegotiateAuthEnabledDefault; |
| 282 | if (command_line.HasSwitch(switches::kExperimentalEnableNegotiateAuth)) { |
| 283 | std::string enable_negotiate_auth = command_line.GetSwitchValueASCII( |
| 284 | switches::kExperimentalEnableNegotiateAuth); |
| 285 | // Enabled if no value, or value is 'true'. Disabled otherwise. |
| 286 | negotiate_auth_enabled = |
| 287 | enable_negotiate_auth.empty() || |
| 288 | (StringToLowerASCII(enable_negotiate_auth) == "true"); |
| 289 | } |
| 290 | |
[email protected] | b4955e7d | 2010-04-16 20:22:30 | [diff] [blame] | 291 | net::HttpAuthHandlerRegistryFactory* registry_factory = |
| 292 | net::HttpAuthHandlerFactory::CreateDefault(); |
| 293 | |
| 294 | globals_->url_security_manager.reset( |
| 295 | net::URLSecurityManager::Create(auth_filter)); |
| 296 | |
| 297 | // Add the security manager to the auth factories that need it. |
| 298 | registry_factory->SetURLSecurityManager("ntlm", |
| 299 | globals_->url_security_manager.get()); |
| 300 | registry_factory->SetURLSecurityManager("negotiate", |
| 301 | globals_->url_security_manager.get()); |
[email protected] | aef0427 | 2010-06-28 18:03:04 | [diff] [blame] | 302 | if (negotiate_auth_enabled) { |
| 303 | // Configure the Negotiate settings for the Kerberos SPN. |
| 304 | // TODO(cbentzel): Read the related IE registry settings on Windows builds. |
| 305 | // TODO(cbentzel): Ugly use of static_cast here. |
| 306 | net::HttpAuthHandlerNegotiate::Factory* negotiate_factory = |
| 307 | static_cast<net::HttpAuthHandlerNegotiate::Factory*>( |
| 308 | registry_factory->GetSchemeFactory("negotiate")); |
| 309 | DCHECK(negotiate_factory); |
[email protected] | 7658fb22b | 2010-07-10 00:27:00 | [diff] [blame] | 310 | negotiate_factory->set_host_resolver(resolver); |
[email protected] | aef0427 | 2010-06-28 18:03:04 | [diff] [blame] | 311 | if (command_line.HasSwitch(switches::kDisableAuthNegotiateCnameLookup)) |
| 312 | negotiate_factory->set_disable_cname_lookup(true); |
| 313 | if (command_line.HasSwitch(switches::kEnableAuthNegotiatePort)) |
| 314 | negotiate_factory->set_use_port(true); |
| 315 | } else { |
| 316 | // Disable the Negotiate authentication handler. |
| 317 | registry_factory->RegisterSchemeFactory("negotiate", NULL); |
| 318 | } |
[email protected] | eb3cac7 | 2010-02-26 21:07:45 | [diff] [blame] | 319 | return registry_factory; |
| 320 | } |
| 321 | |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 322 | void IOThread::InitNetworkPredictorOnIOThread( |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 323 | bool prefetching_enabled, |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 324 | base::TimeDelta max_dns_queue_delay, |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 325 | size_t max_concurrent, |
[email protected] | c5629c3 | 2010-06-23 01:22:43 | [diff] [blame] | 326 | const chrome_common_net::UrlList& startup_urls, |
[email protected] | 760d970a | 2010-05-18 00:39:18 | [diff] [blame] | 327 | ListValue* referral_list, |
| 328 | bool preconnect_enabled) { |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 329 | DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 330 | CHECK(!predictor_); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 331 | |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 332 | chrome_browser_net::EnablePredictor(prefetching_enabled); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 333 | |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 334 | predictor_ = new chrome_browser_net::Predictor( |
[email protected] | 760d970a | 2010-05-18 00:39:18 | [diff] [blame] | 335 | globals_->host_resolver, |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 336 | max_dns_queue_delay, |
[email protected] | 760d970a | 2010-05-18 00:39:18 | [diff] [blame] | 337 | max_concurrent, |
| 338 | preconnect_enabled); |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 339 | predictor_->AddRef(); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 340 | |
[email protected] | f4ef861ba | 2010-07-28 22:37:23 | [diff] [blame] | 341 | // Speculative_interceptor_ is used to predict subresource usage. |
| 342 | DCHECK(!speculative_interceptor_); |
| 343 | speculative_interceptor_ = new chrome_browser_net::ConnectInterceptor; |
| 344 | |
| 345 | // TODO(jar): We can completely replace prefetch_observer with |
| 346 | // speculative_interceptor. |
| 347 | // Prefetch_observer is used to monitor initial resolutions. |
| 348 | DCHECK(!prefetch_observer_); |
| 349 | prefetch_observer_ = chrome_browser_net::CreateResolverObserver(); |
| 350 | globals_->host_resolver->AddObserver(prefetch_observer_); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 351 | |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 352 | FinalizePredictorInitialization( |
| 353 | predictor_, prefetch_observer_, startup_urls, referral_list); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 354 | } |
| 355 | |
| 356 | void IOThread::ChangedToOnTheRecordOnIOThread() { |
| 357 | DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
| 358 | |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 359 | if (predictor_) { |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 360 | // Destroy all evidence of our OTR session. |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 361 | predictor_->Predictor::DiscardAllResults(); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 362 | } |
| 363 | |
| 364 | // Clear the host cache to avoid showing entries from the OTR session |
| 365 | // in about:net-internals. |
[email protected] | 970210c | 2010-02-19 20:27:02 | [diff] [blame] | 366 | if (globals_->host_resolver->GetAsHostResolverImpl()) { |
| 367 | net::HostCache* host_cache = |
| 368 | globals_->host_resolver.get()->GetAsHostResolverImpl()->cache(); |
[email protected] | f2d8c421 | 2010-02-02 00:56:35 | [diff] [blame] | 369 | if (host_cache) |
| 370 | host_cache->clear(); |
| 371 | } |
[email protected] | 9e743cd | 2010-03-16 07:03:53 | [diff] [blame] | 372 | // Clear all of the passively logged data. |
| 373 | // TODO(eroman): this is a bit heavy handed, really all we need to do is |
| 374 | // clear the data pertaining to off the record context. |
| 375 | globals_->net_log->passive_collector()->Clear(); |
[email protected] | 0ac8368 | 2010-01-22 17:46:27 | [diff] [blame] | 376 | } |