OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/tracing/crash_service_uploader.h" | 5 #include "chrome/browser/tracing/crash_service_uploader.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 net::URLRequestContextGetter* request_context) | 43 net::URLRequestContextGetter* request_context) |
44 : request_context_(request_context) { | 44 : request_context_(request_context) { |
45 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 45 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
46 const base::CommandLine& command_line = | 46 const base::CommandLine& command_line = |
47 *base::CommandLine::ForCurrentProcess(); | 47 *base::CommandLine::ForCurrentProcess(); |
48 std::string upload_url = kUploadURL; | 48 std::string upload_url = kUploadURL; |
49 if (command_line.HasSwitch(switches::kTraceUploadURL)) { | 49 if (command_line.HasSwitch(switches::kTraceUploadURL)) { |
50 upload_url = command_line.GetSwitchValueASCII(switches::kTraceUploadURL); | 50 upload_url = command_line.GetSwitchValueASCII(switches::kTraceUploadURL); |
51 } | 51 } |
52 SetUploadURL(upload_url); | 52 SetUploadURL(upload_url); |
53 | |
54 #if defined(OS_WIN) | |
55 const char product[] = "Chrome"; | |
56 #elif defined(OS_MACOSX) | |
57 const char product[] = "Chrome_Mac"; | |
58 #elif defined(OS_LINUX) | |
59 const char product[] = "Chrome_Linux"; | |
60 #elif defined(OS_ANDROID) | |
61 const char product[] = "Chrome_Android"; | |
62 #elif defined(OS_CHROMEOS) | |
63 const char product[] = "Chrome_ChromeOS"; | |
64 #else | |
65 #error Platform not supported. | |
66 #endif | |
67 | |
68 // VersionInfo::ProductNameAndVersionForUserAgent() returns a string like | |
69 // "Chrome/aa.bb.cc.dd", split out the part before the "/". | |
70 chrome::VersionInfo version_info; | |
71 std::vector<std::string> product_components; | |
72 base::SplitString(version_info.ProductNameAndVersionForUserAgent(), '/', | |
oystein (OOO til 10th of July)
2015/06/12 18:14:16
Why have this twice now?
shatch
2015/06/12 19:05:54
This was actually just moved from earlier in the f
| |
73 &product_components); | |
74 DCHECK_EQ(2U, product_components.size()); | |
75 std::string version; | |
76 if (product_components.size() == 2U) { | |
77 version = product_components[1]; | |
78 } else { | |
79 version = "unknown"; | |
80 } | |
81 | |
82 metadata_.insert(std::pair<std::string, std::string>("prod", product)); | |
83 metadata_.insert( | |
84 std::pair<std::string, std::string>("ver", version + "-trace")); | |
85 metadata_.insert(std::pair<std::string, std::string>("guid", "0")); | |
86 metadata_.insert(std::pair<std::string, std::string>("type", "trace")); | |
87 // No minidump means no need for crash to process the report. | |
88 metadata_.insert( | |
89 std::pair<std::string, std::string>("should_process", "false")); | |
53 } | 90 } |
54 | 91 |
55 TraceCrashServiceUploader::~TraceCrashServiceUploader() { | 92 TraceCrashServiceUploader::~TraceCrashServiceUploader() { |
56 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 93 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
57 } | 94 } |
58 | 95 |
59 void TraceCrashServiceUploader::SetUploadURL(const std::string& url) { | 96 void TraceCrashServiceUploader::SetUploadURL(const std::string& url) { |
60 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 97 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
61 upload_url_ = url; | 98 upload_url_ = url; |
62 | 99 |
63 if (!GURL(upload_url_).is_valid()) | 100 if (!GURL(upload_url_).is_valid()) |
64 upload_url_.clear(); | 101 upload_url_.clear(); |
65 } | 102 } |
66 | 103 |
104 void TraceCrashServiceUploader::SetMetadata( | |
105 const std::map<std::string, std::string>& metadata) { | |
106 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
107 metadata_.insert(metadata.begin(), metadata.end()); | |
108 } | |
109 | |
67 void TraceCrashServiceUploader::OnURLFetchComplete( | 110 void TraceCrashServiceUploader::OnURLFetchComplete( |
68 const net::URLFetcher* source) { | 111 const net::URLFetcher* source) { |
69 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 112 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
70 DCHECK_EQ(source, url_fetcher_.get()); | 113 DCHECK_EQ(source, url_fetcher_.get()); |
71 int response_code = source->GetResponseCode(); | 114 int response_code = source->GetResponseCode(); |
72 string feedback; | 115 string feedback; |
73 bool success = (response_code == kHttpResponseOk); | 116 bool success = (response_code == kHttpResponseOk); |
74 if (success) { | 117 if (success) { |
75 source->GetResponseAsString(&feedback); | 118 source->GetResponseAsString(&feedback); |
76 } else { | 119 } else { |
(...skipping 20 matching lines...) Expand all Loading... | |
97 } | 140 } |
98 | 141 |
99 void TraceCrashServiceUploader::DoUpload( | 142 void TraceCrashServiceUploader::DoUpload( |
100 const std::string& file_contents, | 143 const std::string& file_contents, |
101 const UploadProgressCallback& progress_callback, | 144 const UploadProgressCallback& progress_callback, |
102 const UploadDoneCallback& done_callback) { | 145 const UploadDoneCallback& done_callback) { |
103 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 146 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
104 content::BrowserThread::PostTask( | 147 content::BrowserThread::PostTask( |
105 content::BrowserThread::FILE, FROM_HERE, | 148 content::BrowserThread::FILE, FROM_HERE, |
106 base::Bind(&TraceCrashServiceUploader::DoUploadOnFileThread, | 149 base::Bind(&TraceCrashServiceUploader::DoUploadOnFileThread, |
107 base::Unretained(this), file_contents, upload_url_, | 150 base::Unretained(this), file_contents, upload_url_, metadata_, |
108 progress_callback, done_callback)); | 151 progress_callback, done_callback)); |
109 } | 152 } |
110 | 153 |
111 void TraceCrashServiceUploader::DoUploadOnFileThread( | 154 void TraceCrashServiceUploader::DoUploadOnFileThread( |
112 const std::string& file_contents, | 155 const std::string& file_contents, |
113 const std::string& upload_url, | 156 const std::string& upload_url, |
157 const std::map<std::string, std::string>& metadata, | |
114 const UploadProgressCallback& progress_callback, | 158 const UploadProgressCallback& progress_callback, |
115 const UploadDoneCallback& done_callback) { | 159 const UploadDoneCallback& done_callback) { |
116 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); | 160 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); |
117 DCHECK(!url_fetcher_.get()); | 161 DCHECK(!url_fetcher_.get()); |
118 | 162 |
119 progress_callback_ = progress_callback; | 163 progress_callback_ = progress_callback; |
120 done_callback_ = done_callback; | 164 done_callback_ = done_callback; |
121 | 165 |
122 if (upload_url.empty()) { | 166 if (upload_url.empty()) { |
123 OnUploadError("Upload URL empty or invalid"); | 167 OnUploadError("Upload URL empty or invalid"); |
124 return; | 168 return; |
125 } | 169 } |
126 | 170 |
127 #if defined(OS_WIN) | |
128 const char product[] = "Chrome"; | |
129 #elif defined(OS_MACOSX) | |
130 const char product[] = "Chrome_Mac"; | |
131 #elif defined(OS_LINUX) | |
132 const char product[] = "Chrome_Linux"; | |
133 #elif defined(OS_ANDROID) | |
134 const char product[] = "Chrome_Android"; | |
135 #elif defined(OS_CHROMEOS) | |
136 const char product[] = "Chrome_ChromeOS"; | |
137 #else | |
138 #error Platform not supported. | |
139 #endif | |
140 | |
141 // VersionInfo::ProductNameAndVersionForUserAgent() returns a string like | |
142 // "Chrome/aa.bb.cc.dd", split out the part before the "/". | |
143 chrome::VersionInfo version_info; | |
144 std::vector<std::string> product_components; | |
145 base::SplitString(version_info.ProductNameAndVersionForUserAgent(), '/', | |
146 &product_components); | |
147 DCHECK_EQ(2U, product_components.size()); | |
148 std::string version; | |
149 if (product_components.size() == 2U) { | |
150 version = product_components[1]; | |
151 } else { | |
152 version = "unknown"; | |
153 } | |
154 | |
155 if (url_fetcher_.get()) { | 171 if (url_fetcher_.get()) { |
156 OnUploadError("Already uploading."); | 172 OnUploadError("Already uploading."); |
157 return; | 173 return; |
158 } | 174 } |
159 | 175 |
160 scoped_ptr<char[]> compressed_contents(new char[kMaxUploadBytes]); | 176 scoped_ptr<char[]> compressed_contents(new char[kMaxUploadBytes]); |
161 int compressed_bytes; | 177 int compressed_bytes; |
162 if (!Compress(file_contents, kMaxUploadBytes, compressed_contents.get(), | 178 if (!Compress(file_contents, kMaxUploadBytes, compressed_contents.get(), |
163 &compressed_bytes)) { | 179 &compressed_bytes)) { |
164 OnUploadError("Compressing file failed."); | 180 OnUploadError("Compressing file failed."); |
165 return; | 181 return; |
166 } | 182 } |
167 | 183 |
168 std::string post_data; | 184 std::string post_data; |
169 SetupMultipart(product, version, "trace.json.gz", | 185 SetupMultipart(metadata, "trace.json.gz", |
170 std::string(compressed_contents.get(), compressed_bytes), | 186 std::string(compressed_contents.get(), compressed_bytes), |
171 &post_data); | 187 &post_data); |
172 | 188 |
173 content::BrowserThread::PostTask( | 189 content::BrowserThread::PostTask( |
174 content::BrowserThread::UI, FROM_HERE, | 190 content::BrowserThread::UI, FROM_HERE, |
175 base::Bind(&TraceCrashServiceUploader::CreateAndStartURLFetcher, | 191 base::Bind(&TraceCrashServiceUploader::CreateAndStartURLFetcher, |
176 base::Unretained(this), upload_url, post_data)); | 192 base::Unretained(this), upload_url, post_data)); |
177 } | 193 } |
178 | 194 |
179 void TraceCrashServiceUploader::OnUploadError(std::string error_message) { | 195 void TraceCrashServiceUploader::OnUploadError(std::string error_message) { |
180 LOG(ERROR) << error_message; | 196 LOG(ERROR) << error_message; |
181 content::BrowserThread::PostTask( | 197 content::BrowserThread::PostTask( |
182 content::BrowserThread::UI, FROM_HERE, | 198 content::BrowserThread::UI, FROM_HERE, |
183 base::Bind(done_callback_, false, error_message)); | 199 base::Bind(done_callback_, false, error_message)); |
184 } | 200 } |
185 | 201 |
186 void TraceCrashServiceUploader::SetupMultipart( | 202 void TraceCrashServiceUploader::SetupMultipart( |
187 const std::string& product, | 203 const std::map<std::string, std::string> metadata, |
188 const std::string& version, | |
189 const std::string& trace_filename, | 204 const std::string& trace_filename, |
190 const std::string& trace_contents, | 205 const std::string& trace_contents, |
191 std::string* post_data) { | 206 std::string* post_data) { |
192 net::AddMultipartValueForUpload("prod", product, kMultipartBoundary, "", | 207 for (auto it = metadata.begin(); it != metadata.end(); ++it) { |
193 post_data); | 208 net::AddMultipartValueForUpload(it->first, it->second, kMultipartBoundary, |
194 net::AddMultipartValueForUpload("ver", version + "-trace", kMultipartBoundary, | 209 "", post_data); |
195 "", post_data); | 210 } |
196 net::AddMultipartValueForUpload("guid", "0", kMultipartBoundary, "", | |
197 post_data); | |
198 net::AddMultipartValueForUpload("type", "trace", kMultipartBoundary, "", | |
199 post_data); | |
200 // No minidump means no need for crash to process the report. | |
201 net::AddMultipartValueForUpload("should_process", "false", kMultipartBoundary, | |
202 "", post_data); | |
203 | 211 |
204 AddTraceFile(trace_filename, trace_contents, post_data); | 212 AddTraceFile(trace_filename, trace_contents, post_data); |
205 | 213 |
206 net::AddMultipartFinalDelimiterForUpload(kMultipartBoundary, post_data); | 214 net::AddMultipartFinalDelimiterForUpload(kMultipartBoundary, post_data); |
207 } | 215 } |
208 | 216 |
209 void TraceCrashServiceUploader::AddTraceFile(const std::string& trace_filename, | 217 void TraceCrashServiceUploader::AddTraceFile(const std::string& trace_filename, |
210 const std::string& trace_contents, | 218 const std::string& trace_contents, |
211 std::string* post_data) { | 219 std::string* post_data) { |
212 post_data->append("--"); | 220 post_data->append("--"); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
262 std::string content_type = kUploadContentType; | 270 std::string content_type = kUploadContentType; |
263 content_type.append("; boundary="); | 271 content_type.append("; boundary="); |
264 content_type.append(kMultipartBoundary); | 272 content_type.append(kMultipartBoundary); |
265 | 273 |
266 url_fetcher_ = | 274 url_fetcher_ = |
267 net::URLFetcher::Create(GURL(upload_url), net::URLFetcher::POST, this); | 275 net::URLFetcher::Create(GURL(upload_url), net::URLFetcher::POST, this); |
268 url_fetcher_->SetRequestContext(request_context_); | 276 url_fetcher_->SetRequestContext(request_context_); |
269 url_fetcher_->SetUploadData(content_type, post_data); | 277 url_fetcher_->SetUploadData(content_type, post_data); |
270 url_fetcher_->Start(); | 278 url_fetcher_->Start(); |
271 } | 279 } |
OLD | NEW |