Chromium Code Reviews| Index: chrome/browser/tracing/crash_service_uploader.cc |
| diff --git a/content/browser/tracing/trace_uploader.cc b/chrome/browser/tracing/crash_service_uploader.cc |
| similarity index 49% |
| rename from content/browser/tracing/trace_uploader.cc |
| rename to chrome/browser/tracing/crash_service_uploader.cc |
| index 37ccb883ea083b8b06d0bedf5ae65583003a5b6e..4db80d69f8c24cc6865be1e830dfd7590681b911 100644 |
| --- a/content/browser/tracing/trace_uploader.cc |
| +++ b/chrome/browser/tracing/crash_service_uploader.cc |
| @@ -2,15 +2,21 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -#include "content/browser/tracing/trace_uploader.h" |
| +#include "chrome/browser/tracing/crash_service_uploader.h" |
| +#include "base/command_line.h" |
| #include "base/files/file_path.h" |
| #include "base/files/file_util.h" |
| +#include "base/format_macros.h" |
| #include "base/memory/shared_memory.h" |
| #include "base/strings/string_number_conversions.h" |
| +#include "base/strings/string_split.h" |
| +#include "base/strings/string_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/time/time.h" |
| +#include "chrome/common/chrome_version_info.h" |
| #include "content/public/browser/browser_thread.h" |
| +#include "content/public/common/content_switches.h" |
| #include "net/base/mime_util.h" |
| #include "net/base/network_delegate.h" |
| #include "net/proxy/proxy_config.h" |
| @@ -24,35 +30,28 @@ |
| using std::string; |
| -namespace content { |
| namespace { |
| +const char kUploadURL[] = "https://clients2.google.com/cr/staging_report"; |
| const char kUploadContentType[] = "multipart/form-data"; |
| const char kMultipartBoundary[] = |
| "----**--yradnuoBgoLtrapitluMklaTelgooG--**----"; |
| - |
| const int kHttpResponseOk = 200; |
| } // namespace |
| -TraceUploader::TraceUploader(const std::string& product, |
| - const std::string& version, |
| - const std::string& upload_url, |
| - net::URLRequestContextGetter* request_context) |
| - : product_(product), |
| - version_(version), |
| - upload_url_(upload_url), |
| - request_context_(request_context) { |
| - DCHECK(!product_.empty()); |
| - DCHECK(!version_.empty()); |
| - DCHECK(!upload_url_.empty()); |
| +TraceCrashServiceUploader::TraceCrashServiceUploader( |
| + net::URLRequestContextGetter* request_context) |
| + : request_context_(request_context) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| } |
| -TraceUploader::~TraceUploader() { |
| - DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| +TraceCrashServiceUploader::~TraceCrashServiceUploader() { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| } |
| -void TraceUploader::OnURLFetchComplete(const net::URLFetcher* source) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| +void TraceCrashServiceUploader::OnURLFetchComplete( |
| + const net::URLFetcher* source) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| DCHECK_EQ(source, url_fetcher_.get()); |
| int response_code = source->GetResponseCode(); |
| string report_id; |
| @@ -61,40 +60,96 @@ void TraceUploader::OnURLFetchComplete(const net::URLFetcher* source) { |
| if (success) { |
| source->GetResponseAsString(&report_id); |
| } else { |
| - error_message = "Uploading failed, response code: " + |
| - base::IntToString(response_code); |
| + error_message = |
| + "Uploading failed, response code: " + base::IntToString(response_code); |
| } |
| - BrowserThread::PostTask( |
| - content::BrowserThread::UI, |
| - FROM_HERE, |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::UI, FROM_HERE, |
|
dsinclair
2015/02/12 20:57:35
nit: This looks short enough to fit on one line?
oystein (OOO til 10th of July)
2015/02/13 17:02:45
The two first arguments yes, but the base::Bind()
|
| base::Bind(done_callback_, success, report_id, error_message)); |
| url_fetcher_.reset(); |
| } |
| -void TraceUploader::OnURLFetchUploadProgress( |
| - const net::URLFetcher* source, int64 current, int64 total) { |
| +void TraceCrashServiceUploader::OnURLFetchUploadProgress( |
| + const net::URLFetcher* source, |
| + int64 current, |
| + int64 total) { |
| DCHECK(url_fetcher_.get()); |
| LOG(WARNING) << "Upload progress: " << current << " of " << total; |
| - BrowserThread::PostTask( |
| - content::BrowserThread::UI, |
| - FROM_HERE, |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::UI, FROM_HERE, |
| base::Bind(progress_callback_, current, total)); |
| } |
| -void TraceUploader::DoUpload( |
| +void TraceCrashServiceUploader::DoUpload( |
| const std::string& file_contents, |
| - UploadProgressCallback progress_callback, |
| - UploadDoneCallback done_callback) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| + const UploadProgressCallback& progress_callback, |
| + const UploadDoneCallback& done_callback) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&TraceCrashServiceUploader::DoUploadOnFileThread, |
| + base::Unretained(this), file_contents, progress_callback, |
| + done_callback)); |
| +} |
| + |
| +void TraceCrashServiceUploader::DoUploadOnFileThread( |
| + const std::string& file_contents, |
| + const UploadProgressCallback& progress_callback, |
| + const UploadDoneCallback& done_callback) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); |
| DCHECK(!url_fetcher_.get()); |
| progress_callback_ = progress_callback; |
| done_callback_ = done_callback; |
| + const base::CommandLine& command_line = |
| + *base::CommandLine::ForCurrentProcess(); |
| + std::string upload_url = kUploadURL; |
| + if (command_line.HasSwitch(switches::kTraceUploadURL)) { |
| + upload_url = command_line.GetSwitchValueASCII(switches::kTraceUploadURL); |
| + } |
| + if (!GURL(upload_url).is_valid()) { |
|
dsinclair
2015/02/12 20:57:35
nit: Don't need {} on single line statement.
oystein (OOO til 10th of July)
2015/02/13 17:02:45
Done.
|
| + upload_url.clear(); |
| + } |
| + |
| + if (upload_url.empty()) { |
| + OnUploadError("Upload URL empty or invalid"); |
| + return; |
| + } |
| + |
| +#if defined(OS_WIN) |
| + const char product[] = "Chrome"; |
| +#elif defined(OS_MACOSX) |
| + const char product[] = "Chrome_Mac"; |
| +#elif defined(OS_LINUX) |
| + const char product[] = "Chrome_Linux"; |
| +#elif defined(OS_ANDROID) |
| + const char product[] = "Chrome_Android"; |
| +#elif defined(OS_CHROMEOS) |
| + const char product[] = "Chrome_ChromeOS"; |
| +#else |
| +#error Platform not supported. |
| +#endif |
| + |
| + // VersionInfo::ProductNameAndVersionForUserAgent() returns a string like |
| + // "Chrome/aa.bb.cc.dd", split out the part before the "/". |
| + chrome::VersionInfo version_info; |
| + std::vector<std::string> product_components; |
| + base::SplitString(version_info.ProductNameAndVersionForUserAgent(), '/', |
| + &product_components); |
| + DCHECK_EQ(2U, product_components.size()); |
| + std::string version; |
| + if (product_components.size() == 2U) { |
| + version = product_components[1]; |
| + } else { |
| + version = "unknown"; |
| + } |
| + |
| if (url_fetcher_.get()) { |
| OnUploadError("Already uploading."); |
| + return; |
| } |
| scoped_ptr<char[]> compressed_contents(new char[kMaxUploadBytes]); |
| @@ -106,36 +161,37 @@ void TraceUploader::DoUpload( |
| } |
| std::string post_data; |
| - SetupMultipart("trace.json.gz", |
| + SetupMultipart(product, version, "trace.json.gz", |
| std::string(compressed_contents.get(), compressed_bytes), |
| &post_data); |
| content::BrowserThread::PostTask( |
| content::BrowserThread::UI, FROM_HERE, |
| - base::Bind(&TraceUploader::CreateAndStartURLFetcher, |
| - base::Unretained(this), |
| - post_data)); |
| + base::Bind(&TraceCrashServiceUploader::CreateAndStartURLFetcher, |
| + base::Unretained(this), upload_url, post_data)); |
| } |
| -void TraceUploader::OnUploadError(std::string error_message) { |
| +void TraceCrashServiceUploader::OnUploadError(std::string error_message) { |
| LOG(ERROR) << error_message; |
| content::BrowserThread::PostTask( |
| - content::BrowserThread::UI, |
| - FROM_HERE, |
| + content::BrowserThread::UI, FROM_HERE, |
| base::Bind(done_callback_, false, "", error_message)); |
| } |
| -void TraceUploader::SetupMultipart(const std::string& trace_filename, |
| - const std::string& trace_contents, |
| - std::string* post_data) { |
| - net::AddMultipartValueForUpload("prod", product_, kMultipartBoundary, "", |
| +void TraceCrashServiceUploader::SetupMultipart( |
| + const std::string& product, |
| + const std::string& version, |
| + const std::string& trace_filename, |
| + const std::string& trace_contents, |
| + std::string* post_data) { |
| + net::AddMultipartValueForUpload("prod", product, kMultipartBoundary, "", |
| post_data); |
| - net::AddMultipartValueForUpload("ver", version_ + "-trace", |
| - kMultipartBoundary, "", post_data); |
| - net::AddMultipartValueForUpload("guid", "0", kMultipartBoundary, |
| - "", post_data); |
| - net::AddMultipartValueForUpload("type", "trace", kMultipartBoundary, |
| + net::AddMultipartValueForUpload("ver", version + "-trace", kMultipartBoundary, |
| "", post_data); |
| + net::AddMultipartValueForUpload("guid", "0", kMultipartBoundary, "", |
| + post_data); |
| + net::AddMultipartValueForUpload("type", "trace", kMultipartBoundary, "", |
| + post_data); |
| // No minidump means no need for crash to process the report. |
| net::AddMultipartValueForUpload("should_process", "false", kMultipartBoundary, |
| "", post_data); |
| @@ -145,9 +201,9 @@ void TraceUploader::SetupMultipart(const std::string& trace_filename, |
| net::AddMultipartFinalDelimiterForUpload(kMultipartBoundary, post_data); |
| } |
| -void TraceUploader::AddTraceFile(const std::string& trace_filename, |
| - const std::string& trace_contents, |
| - std::string* post_data) { |
| +void TraceCrashServiceUploader::AddTraceFile(const std::string& trace_filename, |
| + const std::string& trace_contents, |
| + std::string* post_data) { |
| post_data->append("--"); |
| post_data->append(kMultipartBoundary); |
| post_data->append("\r\n"); |
| @@ -160,16 +216,14 @@ void TraceUploader::AddTraceFile(const std::string& trace_filename, |
| post_data->append("\r\n"); |
| } |
| -bool TraceUploader::Compress(std::string input, |
| - int max_compressed_bytes, |
| - char* compressed, |
| - int* compressed_bytes) { |
| +bool TraceCrashServiceUploader::Compress(std::string input, |
| + int max_compressed_bytes, |
| + char* compressed, |
| + int* compressed_bytes) { |
| DCHECK(compressed); |
| DCHECK(compressed_bytes); |
| z_stream stream = {0}; |
| - int result = deflateInit2(&stream, |
| - Z_DEFAULT_COMPRESSION, |
| - Z_DEFLATED, |
| + int result = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, |
| // 16 is added to produce a gzip header + trailer. |
| MAX_WBITS + 16, |
| 8, // memLevel = 8 is default. |
| @@ -194,8 +248,10 @@ bool TraceUploader::Compress(std::string input, |
| return success; |
| } |
| -void TraceUploader::CreateAndStartURLFetcher(const std::string& post_data) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| +void TraceCrashServiceUploader::CreateAndStartURLFetcher( |
| + const std::string& upload_url, |
| + const std::string& post_data) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| DCHECK(!url_fetcher_.get()); |
| std::string content_type = kUploadContentType; |
| @@ -203,10 +259,8 @@ void TraceUploader::CreateAndStartURLFetcher(const std::string& post_data) { |
| content_type.append(kMultipartBoundary); |
| url_fetcher_.reset( |
| - net::URLFetcher::Create(GURL(upload_url_), net::URLFetcher::POST, this)); |
| + net::URLFetcher::Create(GURL(upload_url), net::URLFetcher::POST, this)); |
| url_fetcher_->SetRequestContext(request_context_); |
| url_fetcher_->SetUploadData(content_type, post_data); |
| url_fetcher_->Start(); |
| } |
| - |
| -} // namespace content |