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