| 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 50%
|
| rename from content/browser/tracing/trace_uploader.cc
|
| rename to chrome/browser/tracing/crash_service_uploader.cc
|
| index 37ccb883ea083b8b06d0bedf5ae65583003a5b6e..4c5c12706f01c6cae36edb416fa40126244658d0 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,
|
| 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(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,
|
| UploadProgressCallback progress_callback,
|
| UploadDoneCallback done_callback) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::FILE);
|
| + 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()) {
|
| + 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
|
| +
|
| + // GetProduct() 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
|
|
|