1 // Copyright 2014 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.
5 #include "chrome/browser/component_updater/chrome_component_updater_configurator.h"
11 #include "base/command_line.h"
12 #include "base/compiler_specific.h"
13 #include "base/strings/string_util.h"
14 #include "base/version.h"
16 #include "base/win/win_util.h"
18 #include "build/build_config.h"
19 #include "chrome/browser/component_updater/component_patcher_operation_out_of_process.h"
20 #include "chrome/browser/update_client/chrome_update_query_params_delegate.h"
21 #include "chrome/common/chrome_version_info.h"
22 #include "components/component_updater/component_updater_switches.h"
23 #include "components/update_client/configurator.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "net/url_request/url_request_context_getter.h"
28 using update_client::Configurator
;
29 using update_client::OutOfProcessPatcher
;
31 namespace component_updater
{
35 // Default time constants.
36 const int kDelayOneMinute
= 60;
37 const int kDelayOneHour
= kDelayOneMinute
* 60;
39 // Debug values you can pass to --component-updater=value1,value2.
40 // Speed up component checking.
41 const char kSwitchFastUpdate
[] = "fast-update";
43 // Add "testrequest=1" attribute to the update check request.
44 const char kSwitchRequestParam
[] = "test-request";
46 // Disables pings. Pings are the requests sent to the update server that report
47 // the success or the failure of component install or update attempts.
48 extern const char kSwitchDisablePings
[] = "disable-pings";
50 // Sets the URL for updates.
51 const char kSwitchUrlSource
[] = "url-source";
53 #define COMPONENT_UPDATER_SERVICE_ENDPOINT \
54 "//clients2.google.com/service/update2"
56 // The default URL for the v3 protocol service endpoint. In some cases, the
57 // component updater is allowed to fall back to and alternate URL source, if
58 // the request to the default URL source fails.
59 // The value of |kDefaultUrlSource| can be overridden with
60 // --component-updater=url-source=someurl.
61 const char kDefaultUrlSource
[] = "https:" COMPONENT_UPDATER_SERVICE_ENDPOINT
;
62 const char kAltUrlSource
[] = "http:" COMPONENT_UPDATER_SERVICE_ENDPOINT
;
64 // Disables differential updates.
65 const char kSwitchDisableDeltaUpdates
[] = "disable-delta-updates";
68 // Disables background downloads.
69 const char kSwitchDisableBackgroundDownloads
[] = "disable-background-downloads";
70 #endif // defined(OS_WIN)
72 // Returns true if and only if |test| is contained in |vec|.
73 bool HasSwitchValue(const std::vector
<std::string
>& vec
, const char* test
) {
76 return (std::find(vec
.begin(), vec
.end(), test
) != vec
.end());
79 // Returns true if falling back on an alternate, unsafe, service URL is
80 // allowed. In the fallback case, the security of the component update relies
81 // only on the integrity of the CRX payloads, which is self-validating.
82 // This is allowed only for some of the pre-Windows Vista versions not including
83 // Windows XP SP3. As a side note, pings could be sent to the alternate URL too.
84 bool CanUseAltUrlSource() {
86 return !base::win::MaybeHasSHA256Support();
92 // If there is an element of |vec| of the form |test|=.*, returns the right-
93 // hand side of that assignment. Otherwise, returns an empty string.
94 // The right-hand side may contain additional '=' characters, allowing for
95 // further nesting of switch arguments.
96 std::string
GetSwitchArgument(const std::vector
<std::string
>& vec
,
100 for (std::vector
<std::string
>::const_iterator it
= vec
.begin();
103 const std::size_t found
= it
->find("=");
104 if (found
!= std::string::npos
) {
105 if (it
->substr(0, found
) == test
) {
106 return it
->substr(found
+ 1);
110 return std::string();
113 class ChromeConfigurator
: public Configurator
{
115 ChromeConfigurator(const base::CommandLine
* cmdline
,
116 net::URLRequestContextGetter
* url_request_getter
);
118 ~ChromeConfigurator() override
{}
120 int InitialDelay() const override
;
121 int NextCheckDelay() override
;
122 int StepDelay() const override
;
123 int StepDelayMedium() override
;
124 int MinimumReCheckWait() const override
;
125 int OnDemandDelay() const override
;
126 std::vector
<GURL
> UpdateUrl() const override
;
127 std::vector
<GURL
> PingUrl() const override
;
128 base::Version
GetBrowserVersion() const override
;
129 std::string
GetChannel() const override
;
130 std::string
GetLang() const override
;
131 std::string
GetOSLongName() const override
;
132 std::string
ExtraRequestParams() const override
;
133 size_t UrlSizeLimit() const override
;
134 net::URLRequestContextGetter
* RequestContext() const override
;
135 scoped_refptr
<OutOfProcessPatcher
> CreateOutOfProcessPatcher() const override
;
136 bool DeltasEnabled() const override
;
137 bool UseBackgroundDownloader() const override
;
138 scoped_refptr
<base::SequencedTaskRunner
> GetSequencedTaskRunner()
140 scoped_refptr
<base::SingleThreadTaskRunner
> GetSingleThreadTaskRunner()
144 net::URLRequestContextGetter
* url_request_getter_
;
145 std::string extra_info_
;
146 GURL url_source_override_
;
149 bool deltas_enabled_
;
150 bool background_downloads_enabled_
;
151 bool fallback_to_alt_source_url_enabled_
;
154 ChromeConfigurator::ChromeConfigurator(
155 const base::CommandLine
* cmdline
,
156 net::URLRequestContextGetter
* url_request_getter
)
157 : url_request_getter_(url_request_getter
),
159 pings_enabled_(false),
160 deltas_enabled_(false),
161 background_downloads_enabled_(false),
162 fallback_to_alt_source_url_enabled_(false) {
163 // Parse comma-delimited debug flags.
164 std::vector
<std::string
> switch_values
;
165 Tokenize(cmdline
->GetSwitchValueASCII(switches::kComponentUpdater
),
168 fast_update_
= HasSwitchValue(switch_values
, kSwitchFastUpdate
);
169 pings_enabled_
= !HasSwitchValue(switch_values
, kSwitchDisablePings
);
170 deltas_enabled_
= !HasSwitchValue(switch_values
, kSwitchDisableDeltaUpdates
);
173 background_downloads_enabled_
=
174 !HasSwitchValue(switch_values
, kSwitchDisableBackgroundDownloads
);
176 background_downloads_enabled_
= false;
179 const std::string switch_url_source
=
180 GetSwitchArgument(switch_values
, kSwitchUrlSource
);
181 if (!switch_url_source
.empty()) {
182 url_source_override_
= GURL(switch_url_source
);
183 DCHECK(url_source_override_
.is_valid());
186 if (HasSwitchValue(switch_values
, kSwitchRequestParam
))
187 extra_info_
+= "testrequest=\"1\"";
189 fallback_to_alt_source_url_enabled_
= CanUseAltUrlSource();
192 int ChromeConfigurator::InitialDelay() const {
193 return fast_update_
? 1 : (6 * kDelayOneMinute
);
196 int ChromeConfigurator::NextCheckDelay() {
197 return fast_update_
? 3 : (6 * kDelayOneHour
);
200 int ChromeConfigurator::StepDelayMedium() {
201 return fast_update_
? 3 : (15 * kDelayOneMinute
);
204 int ChromeConfigurator::StepDelay() const {
205 return fast_update_
? 1 : 1;
208 int ChromeConfigurator::MinimumReCheckWait() const {
209 return fast_update_
? 30 : (6 * kDelayOneHour
);
212 int ChromeConfigurator::OnDemandDelay() const {
213 return fast_update_
? 2 : (30 * kDelayOneMinute
);
216 std::vector
<GURL
> ChromeConfigurator::UpdateUrl() const {
217 std::vector
<GURL
> urls
;
218 if (url_source_override_
.is_valid()) {
219 urls
.push_back(GURL(url_source_override_
));
221 urls
.push_back(GURL(kDefaultUrlSource
));
222 if (fallback_to_alt_source_url_enabled_
) {
223 urls
.push_back(GURL(kAltUrlSource
));
229 std::vector
<GURL
> ChromeConfigurator::PingUrl() const {
230 return pings_enabled_
? UpdateUrl() : std::vector
<GURL
>();
233 base::Version
ChromeConfigurator::GetBrowserVersion() const {
234 return base::Version(chrome::VersionInfo().Version());
237 std::string
ChromeConfigurator::GetChannel() const {
238 return ChromeUpdateQueryParamsDelegate::GetChannelString();
241 std::string
ChromeConfigurator::GetLang() const {
242 return ChromeUpdateQueryParamsDelegate::GetLang();
245 std::string
ChromeConfigurator::GetOSLongName() const {
246 return chrome::VersionInfo().OSType();
249 std::string
ChromeConfigurator::ExtraRequestParams() const {
253 size_t ChromeConfigurator::UrlSizeLimit() const {
257 net::URLRequestContextGetter
* ChromeConfigurator::RequestContext() const {
258 return url_request_getter_
;
261 scoped_refptr
<OutOfProcessPatcher
>
262 ChromeConfigurator::CreateOutOfProcessPatcher() const {
263 return make_scoped_refptr(new ChromeOutOfProcessPatcher
);
266 bool ChromeConfigurator::DeltasEnabled() const {
267 return deltas_enabled_
;
270 bool ChromeConfigurator::UseBackgroundDownloader() const {
271 return background_downloads_enabled_
;
274 scoped_refptr
<base::SequencedTaskRunner
>
275 ChromeConfigurator::GetSequencedTaskRunner() const {
276 return content::BrowserThread::GetBlockingPool()
277 ->GetSequencedTaskRunnerWithShutdownBehavior(
278 content::BrowserThread::GetBlockingPool()->GetSequenceToken(),
279 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
);
282 scoped_refptr
<base::SingleThreadTaskRunner
>
283 ChromeConfigurator::GetSingleThreadTaskRunner() const {
284 return content::BrowserThread::GetMessageLoopProxyForThread(
285 content::BrowserThread::FILE);
290 Configurator
* MakeChromeComponentUpdaterConfigurator(
291 const base::CommandLine
* cmdline
,
292 net::URLRequestContextGetter
* context_getter
) {
293 return new ChromeConfigurator(cmdline
, context_getter
);
296 } // namespace component_updater