| 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" |
| 11 #include "base/json/json_writer.h" |
| 11 #include "base/memory/shared_memory.h" | 12 #include "base/memory/shared_memory.h" |
| 12 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
| 14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 15 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 16 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 17 #include "chrome/common/chrome_version_info.h" | 18 #include "chrome/common/chrome_version_info.h" |
| 18 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 19 #include "content/public/common/content_switches.h" | 20 #include "content/public/common/content_switches.h" |
| 20 #include "net/base/mime_util.h" | 21 #include "net/base/mime_util.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 DCHECK(url_fetcher_.get()); | 92 DCHECK(url_fetcher_.get()); |
| 92 | 93 |
| 93 LOG(WARNING) << "Upload progress: " << current << " of " << total; | 94 LOG(WARNING) << "Upload progress: " << current << " of " << total; |
| 94 content::BrowserThread::PostTask( | 95 content::BrowserThread::PostTask( |
| 95 content::BrowserThread::UI, FROM_HERE, | 96 content::BrowserThread::UI, FROM_HERE, |
| 96 base::Bind(progress_callback_, current, total)); | 97 base::Bind(progress_callback_, current, total)); |
| 97 } | 98 } |
| 98 | 99 |
| 99 void TraceCrashServiceUploader::DoUpload( | 100 void TraceCrashServiceUploader::DoUpload( |
| 100 const std::string& file_contents, | 101 const std::string& file_contents, |
| 102 scoped_ptr<base::DictionaryValue> metadata, |
| 101 const UploadProgressCallback& progress_callback, | 103 const UploadProgressCallback& progress_callback, |
| 102 const UploadDoneCallback& done_callback) { | 104 const UploadDoneCallback& done_callback) { |
| 103 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 105 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 104 content::BrowserThread::PostTask( | 106 content::BrowserThread::PostTask( |
| 105 content::BrowserThread::FILE, FROM_HERE, | 107 content::BrowserThread::FILE, FROM_HERE, |
| 106 base::Bind(&TraceCrashServiceUploader::DoUploadOnFileThread, | 108 base::Bind(&TraceCrashServiceUploader::DoUploadOnFileThread, |
| 107 base::Unretained(this), file_contents, upload_url_, | 109 base::Unretained(this), file_contents, upload_url_, |
| 108 progress_callback, done_callback)); | 110 base::Passed(metadata.Pass()), progress_callback, |
| 111 done_callback)); |
| 109 } | 112 } |
| 110 | 113 |
| 111 void TraceCrashServiceUploader::DoUploadOnFileThread( | 114 void TraceCrashServiceUploader::DoUploadOnFileThread( |
| 112 const std::string& file_contents, | 115 const std::string& file_contents, |
| 113 const std::string& upload_url, | 116 const std::string& upload_url, |
| 117 scoped_ptr<base::DictionaryValue> metadata, |
| 114 const UploadProgressCallback& progress_callback, | 118 const UploadProgressCallback& progress_callback, |
| 115 const UploadDoneCallback& done_callback) { | 119 const UploadDoneCallback& done_callback) { |
| 116 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); | 120 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); |
| 117 DCHECK(!url_fetcher_.get()); | 121 DCHECK(!url_fetcher_.get()); |
| 118 | 122 |
| 119 progress_callback_ = progress_callback; | 123 progress_callback_ = progress_callback; |
| 120 done_callback_ = done_callback; | 124 done_callback_ = done_callback; |
| 121 | 125 |
| 122 if (upload_url.empty()) { | 126 if (upload_url.empty()) { |
| 123 OnUploadError("Upload URL empty or invalid"); | 127 OnUploadError("Upload URL empty or invalid"); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 | 163 |
| 160 scoped_ptr<char[]> compressed_contents(new char[kMaxUploadBytes]); | 164 scoped_ptr<char[]> compressed_contents(new char[kMaxUploadBytes]); |
| 161 int compressed_bytes; | 165 int compressed_bytes; |
| 162 if (!Compress(file_contents, kMaxUploadBytes, compressed_contents.get(), | 166 if (!Compress(file_contents, kMaxUploadBytes, compressed_contents.get(), |
| 163 &compressed_bytes)) { | 167 &compressed_bytes)) { |
| 164 OnUploadError("Compressing file failed."); | 168 OnUploadError("Compressing file failed."); |
| 165 return; | 169 return; |
| 166 } | 170 } |
| 167 | 171 |
| 168 std::string post_data; | 172 std::string post_data; |
| 169 SetupMultipart(product, version, "trace.json.gz", | 173 SetupMultipart(product, version, metadata.Pass(), "trace.json.gz", |
| 170 std::string(compressed_contents.get(), compressed_bytes), | 174 std::string(compressed_contents.get(), compressed_bytes), |
| 171 &post_data); | 175 &post_data); |
| 172 | 176 |
| 173 content::BrowserThread::PostTask( | 177 content::BrowserThread::PostTask( |
| 174 content::BrowserThread::UI, FROM_HERE, | 178 content::BrowserThread::UI, FROM_HERE, |
| 175 base::Bind(&TraceCrashServiceUploader::CreateAndStartURLFetcher, | 179 base::Bind(&TraceCrashServiceUploader::CreateAndStartURLFetcher, |
| 176 base::Unretained(this), upload_url, post_data)); | 180 base::Unretained(this), upload_url, post_data)); |
| 177 } | 181 } |
| 178 | 182 |
| 179 void TraceCrashServiceUploader::OnUploadError(std::string error_message) { | 183 void TraceCrashServiceUploader::OnUploadError(std::string error_message) { |
| 180 LOG(ERROR) << error_message; | 184 LOG(ERROR) << error_message; |
| 181 content::BrowserThread::PostTask( | 185 content::BrowserThread::PostTask( |
| 182 content::BrowserThread::UI, FROM_HERE, | 186 content::BrowserThread::UI, FROM_HERE, |
| 183 base::Bind(done_callback_, false, error_message)); | 187 base::Bind(done_callback_, false, error_message)); |
| 184 } | 188 } |
| 185 | 189 |
| 186 void TraceCrashServiceUploader::SetupMultipart( | 190 void TraceCrashServiceUploader::SetupMultipart( |
| 187 const std::string& product, | 191 const std::string& product, |
| 188 const std::string& version, | 192 const std::string& version, |
| 193 scoped_ptr<base::DictionaryValue> metadata, |
| 189 const std::string& trace_filename, | 194 const std::string& trace_filename, |
| 190 const std::string& trace_contents, | 195 const std::string& trace_contents, |
| 191 std::string* post_data) { | 196 std::string* post_data) { |
| 192 net::AddMultipartValueForUpload("prod", product, kMultipartBoundary, "", | 197 net::AddMultipartValueForUpload("prod", product, kMultipartBoundary, "", |
| 193 post_data); | 198 post_data); |
| 194 net::AddMultipartValueForUpload("ver", version + "-trace", kMultipartBoundary, | 199 net::AddMultipartValueForUpload("ver", version + "-trace", kMultipartBoundary, |
| 195 "", post_data); | 200 "", post_data); |
| 196 net::AddMultipartValueForUpload("guid", "0", kMultipartBoundary, "", | 201 net::AddMultipartValueForUpload("guid", "0", kMultipartBoundary, "", |
| 197 post_data); | 202 post_data); |
| 198 net::AddMultipartValueForUpload("type", "trace", kMultipartBoundary, "", | 203 net::AddMultipartValueForUpload("type", "trace", kMultipartBoundary, "", |
| 199 post_data); | 204 post_data); |
| 200 // No minidump means no need for crash to process the report. | 205 // No minidump means no need for crash to process the report. |
| 201 net::AddMultipartValueForUpload("should_process", "false", kMultipartBoundary, | 206 net::AddMultipartValueForUpload("should_process", "false", kMultipartBoundary, |
| 202 "", post_data); | 207 "", post_data); |
| 208 if (metadata) { |
| 209 for (base::DictionaryValue::Iterator it(*metadata); !it.IsAtEnd(); |
| 210 it.Advance()) { |
| 211 std::string value; |
| 212 if (!it.value().GetAsString(&value)) { |
| 213 if (!base::JSONWriter::Write(it.value(), &value)) |
| 214 continue; |
| 215 } |
| 216 |
| 217 net::AddMultipartValueForUpload(it.key(), value, kMultipartBoundary, "", |
| 218 post_data); |
| 219 } |
| 220 } |
| 203 | 221 |
| 204 AddTraceFile(trace_filename, trace_contents, post_data); | 222 AddTraceFile(trace_filename, trace_contents, post_data); |
| 205 | 223 |
| 206 net::AddMultipartFinalDelimiterForUpload(kMultipartBoundary, post_data); | 224 net::AddMultipartFinalDelimiterForUpload(kMultipartBoundary, post_data); |
| 207 } | 225 } |
| 208 | 226 |
| 209 void TraceCrashServiceUploader::AddTraceFile(const std::string& trace_filename, | 227 void TraceCrashServiceUploader::AddTraceFile(const std::string& trace_filename, |
| 210 const std::string& trace_contents, | 228 const std::string& trace_contents, |
| 211 std::string* post_data) { | 229 std::string* post_data) { |
| 212 post_data->append("--"); | 230 post_data->append("--"); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 std::string content_type = kUploadContentType; | 280 std::string content_type = kUploadContentType; |
| 263 content_type.append("; boundary="); | 281 content_type.append("; boundary="); |
| 264 content_type.append(kMultipartBoundary); | 282 content_type.append(kMultipartBoundary); |
| 265 | 283 |
| 266 url_fetcher_ = | 284 url_fetcher_ = |
| 267 net::URLFetcher::Create(GURL(upload_url), net::URLFetcher::POST, this); | 285 net::URLFetcher::Create(GURL(upload_url), net::URLFetcher::POST, this); |
| 268 url_fetcher_->SetRequestContext(request_context_); | 286 url_fetcher_->SetRequestContext(request_context_); |
| 269 url_fetcher_->SetUploadData(content_type, post_data); | 287 url_fetcher_->SetUploadData(content_type, post_data); |
| 270 url_fetcher_->Start(); | 288 url_fetcher_->Start(); |
| 271 } | 289 } |
| OLD | NEW |