1 // Copyright 2013 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_utils.h" 6 #include "base/file_util.h" 7 #include "base/files/file_path.h" 8 #include "base/guid.h" 9 #include "base/strings/stringprintf.h" 10 #include "base/sys_info.h" 11 #include "base/win/windows_version.h" 12 #include "chrome/browser/component_updater/crx_update_item.h" 13 #include "chrome/common/chrome_version_info.h" 14 #include "chrome/common/omaha_query_params/omaha_query_params.h" 15 #include "net/base/load_flags.h" 16 #include "net/url_request/url_fetcher.h" 17 #include "net/url_request/url_request_context_getter.h" 18 #include "net/url_request/url_request_status.h" 19 20 namespace component_updater { 21 22 std::string BuildProtocolRequest(const std::string& request_body, 23 const std::string& additional_attributes) { 24 const std::string prod_id(chrome::OmahaQueryParams::GetProdIdString( 25 chrome::OmahaQueryParams::CHROME)); 26 const chrome::VersionInfo chrome_version_info; 27 const std::string chrome_version(chrome_version_info.Version()); 28 29 std::string request( 30 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 31 "<request protocol=\"3.0\" "); 32 33 if (!additional_attributes.empty()) 34 base::StringAppendF(&request, "%s ", additional_attributes.c_str()); 35 36 // Chrome version and platform information. 37 base::StringAppendF( 38 &request, 39 "version=\"%s-%s\" prodversion=\"%s\" " 40 "requestid=\"{%s}\" updaterchannel=\"%s\" prodchannel=\"%s\" " 41 "os=\"%s\" arch=\"%s\" nacl_arch=\"%s\"", 42 prod_id.c_str(), chrome_version.c_str(), // "version" 43 chrome_version.c_str(), // "prodversion" 44 base::GenerateGUID().c_str(), // "requestid" 45 chrome::OmahaQueryParams::GetChannelString(), // "updaterchannel" 46 chrome::OmahaQueryParams::GetChannelString(), // "prodchannel" 47 chrome::OmahaQueryParams::getOS(), // "os" 48 chrome::OmahaQueryParams::getArch(), // "arch" 49 chrome::OmahaQueryParams::getNaclArch()); // "nacl_arch" 50 #if defined(OS_WIN) 51 const bool is_wow64( 52 base::win::OSInfo::GetInstance()->wow64_status() == 53 base::win::OSInfo::WOW64_ENABLED); 54 if (is_wow64) 55 base::StringAppendF(&request, " wow64=\"1\""); 56 #endif 57 base::StringAppendF(&request, ">"); 58 59 // OS version and platform information. 60 base::StringAppendF( 61 &request, 62 "<os platform=\"%s\" version=\"%s\" arch=\"%s\"/>", 63 chrome::VersionInfo().OSType().c_str(), // "platform" 64 base::SysInfo().OperatingSystemVersion().c_str(), // "version" 65 base::SysInfo().OperatingSystemArchitecture().c_str()); // "arch" 66 67 // The actual payload of the request. 68 base::StringAppendF(&request, "%s</request>", request_body.c_str()); 69 70 return request; 71 } 72 73 net::URLFetcher* SendProtocolRequest( 74 const GURL& url, 75 const std::string& protocol_request, 76 net::URLFetcherDelegate* url_fetcher_delegate, 77 net::URLRequestContextGetter* url_request_context_getter) { 78 net::URLFetcher* url_fetcher( 79 net::URLFetcher::Create(0, 80 url, 81 net::URLFetcher::POST, 82 url_fetcher_delegate)); 83 84 url_fetcher->SetUploadData("application/xml", protocol_request); 85 url_fetcher->SetRequestContext(url_request_context_getter); 86 url_fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 87 net::LOAD_DO_NOT_SAVE_COOKIES | 88 net::LOAD_DISABLE_CACHE); 89 url_fetcher->SetAutomaticallyRetryOn5xx(false); 90 url_fetcher->Start(); 91 92 return url_fetcher; 93 } 94 95 bool FetchSuccess(const net::URLFetcher& fetcher) { 96 return GetFetchError(fetcher) == 0; 97 } 98 99 int GetFetchError(const net::URLFetcher& fetcher) { 100 const net::URLRequestStatus::Status status(fetcher.GetStatus().status()); 101 switch (status) { 102 case net::URLRequestStatus::IO_PENDING: 103 case net::URLRequestStatus::CANCELED: 104 // Network status is a small positive number. 105 return status; 106 107 case net::URLRequestStatus::SUCCESS: { 108 // Response codes are positive numbers, greater than 100. 109 const int response_code(fetcher.GetResponseCode()); 110 if (response_code == 200) 111 return 0; 112 else 113 return response_code ? response_code : -1; 114 } 115 116 case net::URLRequestStatus::FAILED: { 117 // Network errors are small negative numbers. 118 const int error = fetcher.GetStatus().error(); 119 return error ? error : -1; 120 } 121 122 default: 123 return -1; 124 } 125 } 126 127 bool HasDiffUpdate(const CrxUpdateItem* update_item) { 128 return !update_item->crx_diffurls.empty(); 129 } 130 131 bool IsHttpServerError(int status_code) { 132 return 500 <= status_code && status_code < 600; 133 } 134 135 bool DeleteFileAndEmptyParentDirectory(const base::FilePath& filepath) { 136 if (!base::DeleteFile(filepath, false)) 137 return false; 138 139 const base::FilePath dirname(filepath.DirName()); 140 if (!base::IsDirectoryEmpty(dirname)) 141 return true; 142 143 return base::DeleteFile(dirname, false); 144 } 145 146 } // namespace component_updater 147 148