/ src / common / linux / google_crashdump_uploader.cc
google_crashdump_uploader.cc
  1  // Copyright 2009 Google LLC
  2  //
  3  // Redistribution and use in source and binary forms, with or without
  4  // modification, are permitted provided that the following conditions are
  5  // met:
  6  //
  7  //     * Redistributions of source code must retain the above copyright
  8  // notice, this list of conditions and the following disclaimer.
  9  //     * Redistributions in binary form must reproduce the above
 10  // copyright notice, this list of conditions and the following disclaimer
 11  // in the documentation and/or other materials provided with the
 12  // distribution.
 13  //     * Neither the name of Google LLC nor the names of its
 14  // contributors may be used to endorse or promote products derived from
 15  // this software without specific prior written permission.
 16  //
 17  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 21  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 22  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 23  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 24  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 25  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 26  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 27  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28  
 29  
 30  #ifdef HAVE_CONFIG_H
 31  #include <config.h>  // Must come first
 32  #endif
 33  
 34  #include "common/linux/google_crashdump_uploader.h"
 35  
 36  #include <sys/types.h>
 37  #include <sys/stat.h>
 38  #include <unistd.h>
 39  
 40  #include <iostream>
 41  #include <utility>
 42  
 43  #include "common/using_std_string.h"
 44  
 45  namespace google_breakpad {
 46  
 47  GoogleCrashdumpUploader::GoogleCrashdumpUploader(const string& product,
 48                                                   const string& version,
 49                                                   const string& guid,
 50                                                   const string& ptime,
 51                                                   const string& ctime,
 52                                                   const string& email,
 53                                                   const string& comments,
 54                                                   const string& minidump_pathname,
 55                                                   const string& crash_server,
 56                                                   const string& proxy_host,
 57                                                   const string& proxy_userpassword) {
 58    std::unique_ptr<LibcurlWrapper> http_layer{new LibcurlWrapper()};
 59    Init(product,
 60         version,
 61         guid,
 62         ptime,
 63         ctime,
 64         email,
 65         comments,
 66         minidump_pathname,
 67         crash_server,
 68         proxy_host,
 69         proxy_userpassword,
 70         std::move(http_layer));
 71  }
 72  
 73  GoogleCrashdumpUploader::GoogleCrashdumpUploader(
 74      const string& product,
 75      const string& version,
 76      const string& guid,
 77      const string& ptime,
 78      const string& ctime,
 79      const string& email,
 80      const string& comments,
 81      const string& minidump_pathname,
 82      const string& crash_server,
 83      const string& proxy_host,
 84      const string& proxy_userpassword,
 85      std::unique_ptr<LibcurlWrapper> http_layer) {
 86    Init(product,
 87         version,
 88         guid,
 89         ptime,
 90         ctime,
 91         email,
 92         comments,
 93         minidump_pathname,
 94         crash_server,
 95         proxy_host,
 96         proxy_userpassword,
 97         std::move(http_layer));
 98  }
 99  
100  void GoogleCrashdumpUploader::Init(const string& product,
101                                     const string& version,
102                                     const string& guid,
103                                     const string& ptime,
104                                     const string& ctime,
105                                     const string& email,
106                                     const string& comments,
107                                     const string& minidump_pathname,
108                                     const string& crash_server,
109                                     const string& proxy_host,
110                                     const string& proxy_userpassword,
111                                     std::unique_ptr<LibcurlWrapper> http_layer) {
112    product_ = product;
113    version_ = version;
114    guid_ = guid;
115    ptime_ = ptime;
116    ctime_ = ctime;
117    email_ = email;
118    comments_ = comments;
119    http_layer_ = std::move(http_layer);
120  
121    crash_server_ = crash_server;
122    proxy_host_ = proxy_host;
123    proxy_userpassword_ = proxy_userpassword;
124    minidump_pathname_ = minidump_pathname;
125    std::cout << "Uploader initializing";
126    std::cout << "\tProduct: " << product_;
127    std::cout << "\tVersion: " << version_;
128    std::cout << "\tGUID: " << guid_;
129    if (!ptime_.empty()) {
130      std::cout << "\tProcess uptime: " << ptime_;
131    }
132    if (!ctime_.empty()) {
133      std::cout << "\tCumulative Process uptime: " << ctime_;
134    }
135    if (!email_.empty()) {
136      std::cout << "\tEmail: " << email_;
137    }
138    if (!comments_.empty()) {
139      std::cout << "\tComments: " << comments_;
140    }
141  }
142  
143  bool GoogleCrashdumpUploader::CheckRequiredParametersArePresent() {
144    string error_text;
145    if (product_.empty()) {
146      error_text.append("\nProduct name must be specified.");
147    }
148  
149    if (version_.empty()) {
150      error_text.append("\nProduct version must be specified.");
151    }
152  
153    if (guid_.empty()) {
154      error_text.append("\nClient ID must be specified.");
155    }
156  
157    if (minidump_pathname_.empty()) {
158      error_text.append("\nMinidump pathname must be specified.");
159    }
160  
161    if (!error_text.empty()) {
162      std::cout << error_text;
163      return false;
164    }
165    return true;
166  
167  }
168  
169  bool GoogleCrashdumpUploader::Upload(int* http_status_code,
170                                       string* http_response_header,
171                                       string* http_response_body) {
172    bool ok = http_layer_->Init();
173    if (!ok) {
174      std::cout << "http layer init failed";
175      return ok;
176    }
177  
178    if (!CheckRequiredParametersArePresent()) {
179      return false;
180    }
181  
182    struct stat st;
183    int err = stat(minidump_pathname_.c_str(), &st);
184    if (err) {
185      std::cout << minidump_pathname_ << " could not be found";
186      return false;
187    }
188  
189    parameters_["prod"] = product_;
190    parameters_["ver"] = version_;
191    parameters_["guid"] = guid_;
192    parameters_["ptime"] = ptime_;
193    parameters_["ctime"] = ctime_;
194    parameters_["email"] = email_;
195    parameters_["comments_"] = comments_;
196    if (!http_layer_->AddFile(minidump_pathname_,
197                              "upload_file_minidump")) {
198      return false;
199    }
200    std::cout << "Sending request to " << crash_server_;
201    long status_code;
202    bool success = http_layer_->SendRequest(crash_server_,
203                                            parameters_,
204                                            &status_code,
205                                            http_response_header,
206                                            http_response_body);
207    if (http_status_code) {
208      *http_status_code = status_code;
209    }
210    return success;
211  }
212  }