aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/windows/sender/crash_report_sender.cc226
-rw-r--r--src/client/windows/sender/crash_report_sender.h30
-rw-r--r--src/client/windows/sender/crash_report_sender.vcproj8
3 files changed, 11 insertions, 253 deletions
diff --git a/src/client/windows/sender/crash_report_sender.cc b/src/client/windows/sender/crash_report_sender.cc
index 16c26c2b..2a4f8250 100644
--- a/src/client/windows/sender/crash_report_sender.cc
+++ b/src/client/windows/sender/crash_report_sender.cc
@@ -27,238 +27,18 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include <assert.h>
-#include <windows.h>
-#include <wininet.h>
-
-#include <fstream>
-
#include "client/windows/sender/crash_report_sender.h"
+#include "common/windows/http_upload.h"
namespace google_airbag {
-using std::ifstream;
-using std::ios;
-
-static const wchar_t kUserAgent[] = L"Airbag/1.0 (Windows)";
-
-// Helper class which closes an internet handle when it goes away
-class CrashReportSender::AutoInternetHandle {
- public:
- explicit AutoInternetHandle(HINTERNET handle) : handle_(handle) {}
- ~AutoInternetHandle() {
- if (handle_) {
- InternetCloseHandle(handle_);
- }
- }
-
- HINTERNET get() { return handle_; }
-
- private:
- HINTERNET handle_;
-};
-
// static
bool CrashReportSender::SendCrashReport(
const wstring &url, const map<wstring, wstring> &parameters,
const wstring &dump_file_name) {
- // TODO(bryner): support non-ASCII parameter names
- if (!CheckParameters(parameters)) {
- return false;
- }
-
- // Break up the URL and make sure we can handle it
- wchar_t scheme[16], host[256], path[256];
- URL_COMPONENTS components;
- memset(&components, 0, sizeof(components));
- components.dwStructSize = sizeof(components);
- components.lpszScheme = scheme;
- components.dwSchemeLength = sizeof(scheme);
- components.lpszHostName = host;
- components.dwHostNameLength = sizeof(host);
- components.lpszUrlPath = path;
- components.dwUrlPathLength = sizeof(path);
- if (!InternetCrackUrl(url.c_str(), static_cast<DWORD>(url.size()),
- 0, &components)) {
- return false;
- }
- if (wcscmp(scheme, L"http") != 0) {
- return false;
- }
-
- AutoInternetHandle internet(InternetOpen(kUserAgent,
- INTERNET_OPEN_TYPE_DIRECT,
- NULL, // proxy name
- NULL, // proxy bypass
- 0)); // flags
- if (!internet.get()) {
- return false;
- }
-
- AutoInternetHandle connection(InternetConnect(internet.get(),
- host,
- components.nPort,
- NULL, // user name
- NULL, // password
- INTERNET_SERVICE_HTTP,
- 0, // flags
- NULL)); // context
- if (!connection.get()) {
- return false;
- }
-
- AutoInternetHandle request(HttpOpenRequest(connection.get(),
- L"POST",
- path,
- NULL, // version
- NULL, // referer
- NULL, // agent type
- 0, // flags
- NULL)); // context
- if (!request.get()) {
- return false;
- }
-
- wstring boundary = GenerateMultipartBoundary();
- wstring content_type_header = GenerateRequestHeader(boundary);
- HttpAddRequestHeaders(request.get(),
- content_type_header.c_str(),
- -1, HTTP_ADDREQ_FLAG_ADD);
-
- string request_body;
- GenerateRequestBody(parameters, dump_file_name, boundary, &request_body);
-
- // The explicit comparison to TRUE avoids a warning (C4800).
- return (HttpSendRequest(request.get(), NULL, 0,
- const_cast<char *>(request_body.data()),
- static_cast<DWORD>(request_body.size())) == TRUE);
-}
-
-// static
-wstring CrashReportSender::GenerateMultipartBoundary() {
- // The boundary has 27 '-' characters followed by 16 hex digits
- static const wchar_t kBoundaryPrefix[] = L"---------------------------";
- static const int kBoundaryLength = 27 + 16 + 1;
-
- // Generate some random numbers to fill out the boundary
- int r0 = rand();
- int r1 = rand();
-
- wchar_t temp[kBoundaryLength];
- swprintf_s(temp, kBoundaryLength, L"%s%08X%08X", kBoundaryPrefix, r0, r1);
- return wstring(temp);
-}
-
-// static
-wstring CrashReportSender::GenerateRequestHeader(const wstring &boundary) {
- wstring header = L"Content-Type: multipart/form-data; boundary=";
- header += boundary;
- return header;
-}
-
-// static
-bool CrashReportSender::GenerateRequestBody(
- const map<wstring, wstring> &parameters,
- const wstring &minidump_filename, const wstring &boundary,
- string *request_body) {
- vector<char> contents;
- GetFileContents(minidump_filename, &contents);
- if (contents.empty()) {
- return false;
- }
-
- string boundary_str = WideToUTF8(boundary);
- if (boundary_str.empty()) {
- return false;
- }
-
- request_body->clear();
-
- // Append each of the parameter pairs as a form-data part
- for (map<wstring, wstring>::const_iterator pos = parameters.begin();
- pos != parameters.end(); ++pos) {
- request_body->append("--" + boundary_str + "\r\n");
- request_body->append("Content-Disposition: form-data; name=\"" +
- WideToUTF8(pos->first) + "\"\r\n\r\n" +
- WideToUTF8(pos->second) + "\r\n");
- }
-
- // Now append the minidump file as a binary (octet-stream) part
- string filename_utf8 = WideToUTF8(minidump_filename);
- if (filename_utf8.empty()) {
- return false;
- }
-
- request_body->append("--" + boundary_str + "\r\n");
- request_body->append("Content-Disposition: form-data; "
- "name=\"upload_file_minidump\"; "
- "filename=\"" + filename_utf8 + "\"\r\n");
- request_body->append("Content-Type: application/octet-stream\r\n");
- request_body->append("\r\n");
-
- request_body->append(&(contents[0]), contents.size());
- request_body->append("\r\n");
- request_body->append("--" + boundary_str + "--\r\n");
- return true;
-}
-// static
-void CrashReportSender::GetFileContents(const wstring &filename,
- vector<char> *contents) {
- ifstream file;
- file.open(filename.c_str(), ios::binary);
- if (file.is_open()) {
- file.seekg(0, ios::end);
- int length = file.tellg();
- contents->resize(length);
- file.seekg(0, ios::beg);
- file.read(&((*contents)[0]), length);
- file.close();
- } else {
- contents->clear();
- }
-}
-
-// static
-string CrashReportSender::WideToUTF8(const wstring &wide) {
- if (wide.length() == 0) {
- return string();
- }
-
- // compute the length of the buffer we'll need
- int charcount = WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1,
- NULL, 0, NULL, NULL);
- if (charcount == 0) {
- return string();
- }
-
- // convert
- char *buf = new char[charcount];
- WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1, buf, charcount,
- NULL, NULL);
-
- string result(buf);
- delete[] buf;
- return result;
-}
-
-// static
-bool CrashReportSender::CheckParameters(
- const map<wstring, wstring> &parameters) {
- for (map<wstring, wstring>::const_iterator pos = parameters.begin();
- pos != parameters.end(); ++pos) {
- const wstring &str = pos->first;
- if (str.size() == 0) {
- return false; // disallow empty parameter names
- }
- for (unsigned int i = 0; i < str.size(); ++i) {
- wchar_t c = str[i];
- if (c < 32 || c == '"' || c > 127) {
- return false;
- }
- }
- }
- return true;
+ return HTTPUpload::SendRequest(url, parameters, dump_file_name,
+ L"upload_file_minidump");
}
} // namespace google_airbag
diff --git a/src/client/windows/sender/crash_report_sender.h b/src/client/windows/sender/crash_report_sender.h
index 52bec788..39267243 100644
--- a/src/client/windows/sender/crash_report_sender.h
+++ b/src/client/windows/sender/crash_report_sender.h
@@ -40,14 +40,11 @@
#include <string>
#include <map>
-#include <vector>
namespace google_airbag {
-using std::string;
using std::wstring;
using std::map;
-using std::vector;
class CrashReportSender {
public:
@@ -62,33 +59,6 @@ class CrashReportSender {
const wstring &dump_file_name);
private:
- class AutoInternetHandle;
-
- // Generates a new multipart boundary for a POST request
- static wstring GenerateMultipartBoundary();
-
- // Generates a HTTP request header for a multipart form submit.
- static wstring GenerateRequestHeader(const wstring &boundary);
-
- // Given a set of parameters and a minidump file name,
- // generates a multipart request body string with these parameters
- // and minidump contents. Returns true on success.
- static bool GenerateRequestBody(const map<wstring, wstring> &parameters,
- const wstring &minidump_filename,
- const wstring &boundary,
- string *request_body);
-
- // Fills the supplied vector with the contents of filename.
- static void GetFileContents(const wstring &filename, vector<char> *contents);
-
- // Converts a UTF16 string to UTF8.
- static string WideToUTF8(const wstring &wide);
-
- // Checks that the given list of parameters has only printable
- // ASCII characters in the parameter name, and does not contain
- // any quote (") characters. Returns true if so.
- static bool CheckParameters(const map<wstring, wstring> &parameters);
-
// No instances of this class should be created.
// Disallow all constructors, destructors, and operator=.
CrashReportSender();
diff --git a/src/client/windows/sender/crash_report_sender.vcproj b/src/client/windows/sender/crash_report_sender.vcproj
index eabb76ce..fc131ef5 100644
--- a/src/client/windows/sender/crash_report_sender.vcproj
+++ b/src/client/windows/sender/crash_report_sender.vcproj
@@ -276,6 +276,10 @@
RelativePath=".\crash_report_sender.cc"
>
</File>
+ <File
+ RelativePath="..\..\..\common\windows\http_upload.cc"
+ >
+ </File>
</Filter>
<Filter
Name="Header Files"
@@ -286,6 +290,10 @@
RelativePath=".\crash_report_sender.h"
>
</File>
+ <File
+ RelativePath="..\..\..\common\windows\http_upload.h"
+ >
+ </File>
</Filter>
<Filter
Name="Resource Files"