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 #include "common/linux/libcurl_wrapper.h"
33 #include "third_party/linux/include/glog/logging.h"
34 
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <unistd.h>
38 
39 namespace google_breakpad {
40 
GoogleCrashdumpUploader(const std::string & product,const std::string & version,const std::string & guid,const std::string & ptime,const std::string & ctime,const std::string & email,const std::string & comments,const std::string & minidump_pathname,const std::string & crash_server,const std::string & proxy_host,const std::string & proxy_userpassword)41 GoogleCrashdumpUploader::GoogleCrashdumpUploader(const std::string& product,
42                                                  const std::string& version,
43                                                  const std::string& guid,
44                                                  const std::string& ptime,
45                                                  const std::string& ctime,
46                                                  const std::string& email,
47                                                  const std::string& comments,
48                                                  const std::string& minidump_pathname,
49                                                  const std::string& crash_server,
50                                                  const std::string& proxy_host,
51                                                  const std::string& proxy_userpassword) {
52   LibcurlWrapper* http_layer = new LibcurlWrapper();
53   Init(product,
54        version,
55        guid,
56        ptime,
57        ctime,
58        email,
59        comments,
60        minidump_pathname,
61        crash_server,
62        proxy_host,
63        proxy_userpassword,
64        http_layer);
65 }
66 
GoogleCrashdumpUploader(const std::string & product,const std::string & version,const std::string & guid,const std::string & ptime,const std::string & ctime,const std::string & email,const std::string & comments,const std::string & minidump_pathname,const std::string & crash_server,const std::string & proxy_host,const std::string & proxy_userpassword,LibcurlWrapper * http_layer)67 GoogleCrashdumpUploader::GoogleCrashdumpUploader(const std::string& product,
68                                                  const std::string& version,
69                                                  const std::string& guid,
70                                                  const std::string& ptime,
71                                                  const std::string& ctime,
72                                                  const std::string& email,
73                                                  const std::string& comments,
74                                                  const std::string& minidump_pathname,
75                                                  const std::string& crash_server,
76                                                  const std::string& proxy_host,
77                                                  const std::string& proxy_userpassword,
78                                                  LibcurlWrapper* http_layer) {
79   Init(product,
80        version,
81        guid,
82        ptime,
83        ctime,
84        email,
85        comments,
86        minidump_pathname,
87        crash_server,
88        proxy_host,
89        proxy_userpassword,
90        http_layer);
91 }
92 
Init(const std::string & product,const std::string & version,const std::string & guid,const std::string & ptime,const std::string & ctime,const std::string & email,const std::string & comments,const std::string & minidump_pathname,const std::string & crash_server,const std::string & proxy_host,const std::string & proxy_userpassword,LibcurlWrapper * http_layer)93 void GoogleCrashdumpUploader::Init(const std::string& product,
94                                    const std::string& version,
95                                    const std::string& guid,
96                                    const std::string& ptime,
97                                    const std::string& ctime,
98                                    const std::string& email,
99                                    const std::string& comments,
100                                    const std::string& minidump_pathname,
101                                    const std::string& crash_server,
102                                    const std::string& proxy_host,
103                                    const std::string& proxy_userpassword,
104                                    LibcurlWrapper* http_layer) {
105   product_ = product;
106   version_ = version;
107   guid_ = guid;
108   ptime_ = ptime;
109   ctime_ = ctime;
110   email_ = email;
111   comments_ = comments;
112   http_layer_ = http_layer;
113 
114   crash_server_ = crash_server;
115   proxy_host_ = proxy_host;
116   proxy_userpassword_ = proxy_userpassword;
117   minidump_pathname_ = minidump_pathname;
118   LOG(INFO) << "Uploader initializing";
119   LOG(INFO) << "\tProduct: " << product_;
120   LOG(INFO) << "\tVersion: " << version_;
121   LOG(INFO) << "\tGUID: " << guid_;
122   if (!ptime_.empty()) {
123     LOG(INFO) << "\tProcess uptime: " << ptime_;
124   }
125   if (!ctime_.empty()) {
126     LOG(INFO) << "\tCumulative Process uptime: " << ctime_;
127   }
128   if (!email_.empty()) {
129     LOG(INFO) << "\tEmail: " << email_;
130   }
131   if (!comments_.empty()) {
132     LOG(INFO) << "\tComments: " << comments_;
133   }
134 }
135 
CheckRequiredParametersArePresent()136 bool GoogleCrashdumpUploader::CheckRequiredParametersArePresent() {
137   std::string error_text;
138   if (product_.empty()) {
139     error_text.append("\nProduct name must be specified.");
140   }
141 
142   if (version_.empty()) {
143     error_text.append("\nProduct version must be specified.");
144   }
145 
146   if (guid_.empty()) {
147     error_text.append("\nClient ID must be specified.");
148   }
149 
150   if (minidump_pathname_.empty()) {
151     error_text.append("\nMinidump pathname must be specified.");
152   }
153 
154   if (!error_text.empty()) {
155     LOG(ERROR) << error_text;
156     return false;
157   }
158   return true;
159 
160 }
161 
Upload()162 bool GoogleCrashdumpUploader::Upload() {
163   bool ok = http_layer_->Init();
164   if (!ok) {
165     LOG(WARNING) << "http layer init failed";
166     return ok;
167   }
168 
169   if (!CheckRequiredParametersArePresent()) {
170     return false;
171   }
172 
173   struct stat st;
174   int err = stat(minidump_pathname_.c_str(), &st);
175   if (err) {
176     LOG(WARNING) << minidump_pathname_ << " could not be found: " << errno;
177     return false;
178   }
179 
180   parameters_["prod"] = product_;
181   parameters_["ver"] = version_;
182   parameters_["guid"] = guid_;
183   parameters_["ptime"] = ptime_;
184   parameters_["ctime"] = ctime_;
185   parameters_["email"] = email_;
186   parameters_["comments_"] = comments_;
187   if (!http_layer_->AddFile(minidump_pathname_,
188                             "upload_file_minidump")) {
189     return false;
190   }
191   LOG(INFO) << "Sending request to " << crash_server_;
192   return http_layer_->SendRequest(crash_server_,
193                                   parameters_,
194                                   NULL);
195 }
196 }
197