// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chromecast/crash/cast_crashdump_uploader.h" #include #include "base/logging.h" // TODO(slan): Find a replacement for LibcurlWrapper in Chromium to remove the // breakpad dependency. #include "breakpad/src/common/linux/libcurl_wrapper.h" namespace chromecast { namespace { // Keep these in sync with "//breakpad/src/client/mac/sender/uploader.mm" const char kProdKey[] = "prod"; const char kVerKey[] = "ver"; const char kGuidKey[] = "guid"; const char kPtimeKey[] = "ptime"; const char kCtimeKey[] = "ctime"; const char kEmailKey[] = "email"; const char kCommentsKey[] = "comments"; } // namespace CastCrashdumpData::CastCrashdumpData() { } CastCrashdumpData::~CastCrashdumpData() { } CastCrashdumpUploader::CastCrashdumpUploader(const CastCrashdumpData& data) : CastCrashdumpUploader(data, new google_breakpad::LibcurlWrapper()) { // This instance of libcurlwrapper will leak. } CastCrashdumpUploader::CastCrashdumpUploader( const CastCrashdumpData& data, google_breakpad::LibcurlWrapper* http_layer) : http_layer_(http_layer), data_(data) { DCHECK(http_layer_); } CastCrashdumpUploader::~CastCrashdumpUploader() { } bool CastCrashdumpUploader::AddAttachment(const std::string& label, const std::string& filename) { attachments_[label] = filename; return true; } bool CastCrashdumpUploader::CheckRequiredParametersArePresent() { return !(data_.product.empty() || data_.version.empty() || data_.guid.empty() || data_.minidump_pathname.empty()); } bool CastCrashdumpUploader::Upload(std::string* response) { if (!http_layer_->Init()) { LOG(ERROR) << "http layer Init failed"; return false; } if (!CheckRequiredParametersArePresent()) { LOG(ERROR) << "Missing required parameters"; return false; } struct stat st; if (0 != stat(data_.minidump_pathname.c_str(), &st)) { LOG(ERROR) << data_.minidump_pathname << " does not exist."; return false; } if (!http_layer_->AddFile(data_.minidump_pathname, "upload_file_minidump")) { LOG(ERROR) << "Failed to add file: " << data_.minidump_pathname; return false; } // Populate |parameters_|. parameters_[kProdKey] = data_.product; parameters_[kVerKey] = data_.version; parameters_[kGuidKey] = data_.guid; parameters_[kPtimeKey] = data_.ptime; parameters_[kCtimeKey] = data_.ctime; parameters_[kEmailKey] = data_.email; parameters_[kCommentsKey] = data_.comments; // Add each attachement in |attachments_|. for (auto iter = attachments_.begin(); iter != attachments_.end(); ++iter) { // Search for the attachment. if (0 != stat(iter->second.c_str(), &st)) { LOG(ERROR) << iter->second << " could not be found"; return false; } // Add the attachment if (!http_layer_->AddFile(iter->second, iter->first)) { LOG(ERROR) << "Failed to add file: " << iter->second << " with label: " << iter->first; return false; } } LOG(INFO) << "Sending request to " << data_.crash_server; int http_status_code; std::string http_header_data; return http_layer_->SendRequest(data_.crash_server, parameters_, &http_status_code, &http_header_data, response); } void CastCrashdumpUploader::SetParameter(const std::string& key, const std::string& value) { parameters_[key] = value; } } // namespace chromecast