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