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/component_updater/component_updater_configurator.h" 6 7 #include <algorithm> 8 #include <string> 9 #include <vector> 10 11 #include "base/command_line.h" 12 #include "base/compiler_specific.h" 13 #include "base/strings/string_util.h" 14 #include "base/win/windows_version.h" 15 #include "build/build_config.h" 16 #include "chrome/browser/component_updater/component_patcher.h" 17 #include "chrome/common/chrome_switches.h" 18 #include "net/url_request/url_request_context_getter.h" 19 20 #if defined(OS_WIN) 21 #include "chrome/browser/component_updater/component_patcher_win.h" 22 #endif 23 24 namespace { 25 26 // Default time constants. 27 const int kDelayOneMinute = 60; 28 const int kDelayOneHour = kDelayOneMinute * 60; 29 30 // Debug values you can pass to --component-updater=value1,value2. 31 // Speed up component checking. 32 const char kSwitchFastUpdate[] = "fast-update"; 33 34 // Add "testrequest=1" attribute to the update check request. 35 const char kSwitchRequestParam[] = "test-request"; 36 37 // Disables pings. Pings are the requests sent to the update server that report 38 // the success or the failure of component install or update attempts. 39 extern const char kSwitchDisablePings[] = "disable-pings"; 40 41 // Sets the URL for updates. 42 const char kSwitchUrlSource[] = "url-source"; 43 44 #define COMPONENT_UPDATER_SERVICE_ENDPOINT \ 45 "//clients2.google.com/service/update2" 46 47 // The default url for the v3 protocol service endpoint. Can be 48 // overridden with --component-updater=url-source=someurl. 49 const char kDefaultUrlSource[] = "https:" COMPONENT_UPDATER_SERVICE_ENDPOINT; 50 51 // The url to send the pings to. 52 const char kPingUrl[] = "http:" COMPONENT_UPDATER_SERVICE_ENDPOINT; 53 54 #if defined(OS_WIN) 55 // Disables differential updates. 56 const char kSwitchDisableDeltaUpdates[] = "disable-delta-updates"; 57 // Disables background downloads. 58 const char kSwitchDisableBackgroundDownloads[] = "disable-background-downloads"; 59 #endif // defined(OS_WIN) 60 61 // Returns true if and only if |test| is contained in |vec|. 62 bool HasSwitchValue(const std::vector<std::string>& vec, const char* test) { 63 if (vec.empty()) 64 return 0; 65 return (std::find(vec.begin(), vec.end(), test) != vec.end()); 66 } 67 68 // If there is an element of |vec| of the form |test|=.*, returns the right- 69 // hand side of that assignment. Otherwise, returns an empty string. 70 // The right-hand side may contain additional '=' characters, allowing for 71 // further nesting of switch arguments. 72 std::string GetSwitchArgument(const std::vector<std::string>& vec, 73 const char* test) { 74 if (vec.empty()) 75 return std::string(); 76 for (std::vector<std::string>::const_iterator it = vec.begin(); 77 it != vec.end(); 78 ++it) { 79 const std::size_t found = it->find("="); 80 if (found != std::string::npos) { 81 if (it->substr(0, found) == test) { 82 return it->substr(found + 1); 83 } 84 } 85 } 86 return std::string(); 87 } 88 89 } // namespace 90 91 class ChromeConfigurator : public ComponentUpdateService::Configurator { 92 public: 93 ChromeConfigurator(const CommandLine* cmdline, 94 net::URLRequestContextGetter* url_request_getter); 95 96 virtual ~ChromeConfigurator() {} 97 98 virtual int InitialDelay() OVERRIDE; 99 virtual int NextCheckDelay() OVERRIDE; 100 virtual int StepDelay() OVERRIDE; 101 virtual int StepDelayMedium() OVERRIDE; 102 virtual int MinimumReCheckWait() OVERRIDE; 103 virtual int OnDemandDelay() OVERRIDE; 104 virtual GURL UpdateUrl() OVERRIDE; 105 virtual GURL PingUrl() OVERRIDE; 106 virtual std::string ExtraRequestParams() OVERRIDE; 107 virtual size_t UrlSizeLimit() OVERRIDE; 108 virtual net::URLRequestContextGetter* RequestContext() OVERRIDE; 109 virtual bool InProcess() OVERRIDE; 110 virtual ComponentPatcher* CreateComponentPatcher() OVERRIDE; 111 virtual bool DeltasEnabled() const OVERRIDE; 112 virtual bool UseBackgroundDownloader() const OVERRIDE; 113 114 private: 115 net::URLRequestContextGetter* url_request_getter_; 116 std::string extra_info_; 117 std::string url_source_; 118 bool fast_update_; 119 bool pings_enabled_; 120 bool deltas_enabled_; 121 bool background_downloads_enabled_; 122 }; 123 124 ChromeConfigurator::ChromeConfigurator(const CommandLine* cmdline, 125 net::URLRequestContextGetter* url_request_getter) 126 : url_request_getter_(url_request_getter), 127 fast_update_(false), 128 pings_enabled_(false), 129 deltas_enabled_(false), 130 background_downloads_enabled_(false) { 131 // Parse comma-delimited debug flags. 132 std::vector<std::string> switch_values; 133 Tokenize(cmdline->GetSwitchValueASCII(switches::kComponentUpdater), 134 ",", &switch_values); 135 fast_update_ = HasSwitchValue(switch_values, kSwitchFastUpdate); 136 pings_enabled_ = !HasSwitchValue(switch_values, kSwitchDisablePings); 137 #if defined(OS_WIN) 138 deltas_enabled_ = !HasSwitchValue(switch_values, kSwitchDisableDeltaUpdates); 139 background_downloads_enabled_ = 140 !HasSwitchValue(switch_values, kSwitchDisableBackgroundDownloads); 141 #else 142 deltas_enabled_ = false; 143 background_downloads_enabled_ = false; 144 #endif 145 146 url_source_ = GetSwitchArgument(switch_values, kSwitchUrlSource); 147 if (url_source_.empty()) { 148 url_source_ = kDefaultUrlSource; 149 } 150 151 if (HasSwitchValue(switch_values, kSwitchRequestParam)) 152 extra_info_ += "testrequest=\"1\""; 153 } 154 155 int ChromeConfigurator::InitialDelay() { 156 return fast_update_ ? 1 : (6 * kDelayOneMinute); 157 } 158 159 int ChromeConfigurator::NextCheckDelay() { 160 return fast_update_ ? 3 : (6 * kDelayOneHour); 161 } 162 163 int ChromeConfigurator::StepDelayMedium() { 164 return fast_update_ ? 3 : (15 * kDelayOneMinute); 165 } 166 167 int ChromeConfigurator::StepDelay() { 168 return fast_update_ ? 1 : 1; 169 } 170 171 int ChromeConfigurator::MinimumReCheckWait() { 172 return fast_update_ ? 30 : (6 * kDelayOneHour); 173 } 174 175 int ChromeConfigurator::OnDemandDelay() { 176 return fast_update_ ? 2 : (30 * kDelayOneMinute); 177 } 178 179 GURL ChromeConfigurator::UpdateUrl() { 180 return GURL(url_source_); 181 } 182 183 GURL ChromeConfigurator::PingUrl() { 184 return pings_enabled_ ? GURL(kPingUrl) : GURL(); 185 } 186 187 std::string ChromeConfigurator::ExtraRequestParams() { 188 return extra_info_; 189 } 190 191 size_t ChromeConfigurator::UrlSizeLimit() { 192 return 1024ul; 193 } 194 195 net::URLRequestContextGetter* ChromeConfigurator::RequestContext() { 196 return url_request_getter_; 197 } 198 199 bool ChromeConfigurator::InProcess() { 200 return false; 201 } 202 203 ComponentPatcher* ChromeConfigurator::CreateComponentPatcher() { 204 #if defined(OS_WIN) 205 return new ComponentPatcherWin(); 206 #else 207 return new ComponentPatcherCrossPlatform(); 208 #endif 209 } 210 211 bool ChromeConfigurator::DeltasEnabled() const { 212 return deltas_enabled_; 213 } 214 215 bool ChromeConfigurator::UseBackgroundDownloader() const { 216 return background_downloads_enabled_; 217 } 218 219 ComponentUpdateService::Configurator* MakeChromeComponentUpdaterConfigurator( 220 const CommandLine* cmdline, net::URLRequestContextGetter* context_getter) { 221 return new ChromeConfigurator(cmdline, context_getter); 222 } 223