summaryrefslogtreecommitdiffstats
path: root/chromecast/crash/cast_crashdump_uploader.cc
blob: 1c15ac6a8647ce332b57468e3dc40da6bcb59a08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// 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 <sys/stat.h>

#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