aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/windows/sender/crash_report_sender.cc4
-rw-r--r--src/client/windows/sender/crash_report_sender.h9
-rw-r--r--src/common/windows/http_upload.cc64
-rw-r--r--src/common/windows/http_upload.h18
-rw-r--r--src/tools/windows/symupload/symupload.cc2
5 files changed, 86 insertions, 11 deletions
diff --git a/src/client/windows/sender/crash_report_sender.cc b/src/client/windows/sender/crash_report_sender.cc
index 0c48c875..485ffc36 100644
--- a/src/client/windows/sender/crash_report_sender.cc
+++ b/src/client/windows/sender/crash_report_sender.cc
@@ -38,10 +38,10 @@ namespace google_airbag {
// static
bool CrashReportSender::SendCrashReport(
const wstring &url, const map<wstring, wstring> &parameters,
- const wstring &dump_file_name) {
+ const wstring &dump_file_name, wstring *report_code) {
return HTTPUpload::SendRequest(url, parameters, dump_file_name,
- L"upload_file_minidump");
+ L"upload_file_minidump", report_code);
}
} // namespace google_airbag
diff --git a/src/client/windows/sender/crash_report_sender.h b/src/client/windows/sender/crash_report_sender.h
index a909c466..c44c5e74 100644
--- a/src/client/windows/sender/crash_report_sender.h
+++ b/src/client/windows/sender/crash_report_sender.h
@@ -56,11 +56,16 @@ class CrashReportSender {
// name value pairs, as a multipart POST request to the given URL.
// Parameter names must contain only printable ASCII characters,
// and may not contain a quote (") character.
+ // If the report is sent successfully (the return value is true), a
+ // code uniquely identifying the report will be returned in report_code.
// Only HTTP(S) URLs are currently supported. Returns true on success.
- // TODO(bryner): we should expose the response to the caller.
+ // If report_code is non-NULL and the report is sent successfully (that is,
+ // the return value is true), a code uniquely identifying the report will be
+ // returned in report_code. (Otherwise, report_code will be unchanged.)
static bool SendCrashReport(const wstring &url,
const map<wstring, wstring> &parameters,
- const wstring &dump_file_name);
+ const wstring &dump_file_name,
+ wstring *report_code);
private:
// No instances of this class should be created.
diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc
index 54e7ff85..59e541f0 100644
--- a/src/common/windows/http_upload.cc
+++ b/src/common/windows/http_upload.cc
@@ -28,8 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assert.h>
-#include <Windows.h>
-#include <WinInet.h>
// Disable exception handler warnings.
#pragma warning( disable : 4530 )
@@ -67,7 +65,8 @@ class HTTPUpload::AutoInternetHandle {
bool HTTPUpload::SendRequest(const wstring &url,
const map<wstring, wstring> &parameters,
const wstring &upload_file,
- const wstring &file_part_name) {
+ const wstring &file_part_name,
+ wstring *response_body) {
// TODO(bryner): support non-ASCII parameter names
if (!CheckParameters(parameters)) {
return false;
@@ -154,7 +153,43 @@ bool HTTPUpload::SendRequest(const wstring &url,
return false;
}
- return (wcscmp(http_status, L"200") == 0);
+ bool result = (wcscmp(http_status, L"200") == 0);
+
+ if (result) {
+ result = ReadResponse(request.get(), response_body);
+ }
+
+ return result;
+}
+
+// static
+bool HTTPUpload::ReadResponse(HINTERNET request, wstring *response) {
+ wchar_t content_length[32];
+ DWORD content_length_size = sizeof(content_length);
+ if (!HttpQueryInfo(request, HTTP_QUERY_CONTENT_LENGTH,
+ static_cast<LPVOID>(&content_length), &content_length_size,
+ 0)) {
+ return false;
+ }
+ DWORD claimed_size = wcstol(content_length, NULL, 10);
+
+ char *response_buffer = new char[claimed_size];
+ DWORD size_read;
+ DWORD total_read = 0;
+ BOOL read_result;
+ do {
+ read_result = InternetReadFile(request, response_buffer + total_read,
+ claimed_size - total_read, &size_read);
+ total_read += size_read;
+ } while (read_result && (size_read != 0) && (total_read < claimed_size));
+
+ bool succeeded = (total_read == claimed_size);
+ if (succeeded && response) {
+ *response = UTF8ToWide(string(response_buffer, total_read));
+ }
+
+ delete[] response_buffer;
+ return succeeded;
}
// static
@@ -262,6 +297,27 @@ void HTTPUpload::GetFileContents(const wstring &filename,
}
// static
+wstring HTTPUpload::UTF8ToWide(const string &utf8) {
+ if (utf8.length() == 0) {
+ return wstring();
+ }
+
+ // compute the length of the buffer we'll need
+ int charcount = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, NULL, 0);
+
+ if (charcount == 0) {
+ return wstring();
+ }
+
+ // convert
+ wchar_t* buf = new wchar_t[charcount];
+ MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, buf, charcount);
+ wstring result(buf);
+ delete[] buf;
+ return result;
+}
+
+// static
string HTTPUpload::WideToUTF8(const wstring &wide) {
if (wide.length() == 0) {
return string();
diff --git a/src/common/windows/http_upload.h b/src/common/windows/http_upload.h
index 4d86eded..a23a0f2b 100644
--- a/src/common/windows/http_upload.h
+++ b/src/common/windows/http_upload.h
@@ -38,6 +38,9 @@
// Disable exception handler warnings.
#pragma warning( disable : 4530 )
+#include <Windows.h>
+#include <WinInet.h>
+
#include <map>
#include <string>
#include <vector>
@@ -58,15 +61,23 @@ class HTTPUpload {
// Parameter names must contain only printable ASCII characters,
// and may not contain a quote (") character.
// Only HTTP(S) URLs are currently supported. Returns true on success.
- // TODO(bryner): we should expose the response to the caller.
+ // If the request is successful and response_body is non-NULL,
+ // the response body will be returned in response_body.
static bool SendRequest(const wstring &url,
const map<wstring, wstring> &parameters,
const wstring &upload_file,
- const wstring &file_part_name);
+ const wstring &file_part_name,
+ wstring *response_body);
private:
class AutoInternetHandle;
+ // Retrieves the HTTP response. If NULL is passed in for response,
+ // this merely checks (via the return value) that we were successfully
+ // able to retrieve exactly as many bytes of content in the response as
+ // were specified in the Content-Length header.
+ static bool HTTPUpload::ReadResponse(HINTERNET request, wstring* response);
+
// Generates a new multipart boundary for a POST request
static wstring GenerateMultipartBoundary();
@@ -85,6 +96,9 @@ class HTTPUpload {
// Fills the supplied vector with the contents of filename.
static void GetFileContents(const wstring &filename, vector<char> *contents);
+ // Converts a UTF8 string to UTF16.
+ static wstring UTF8ToWide(const string &utf8);
+
// Converts a UTF16 string to UTF8.
static string WideToUTF8(const wstring &wide);
diff --git a/src/tools/windows/symupload/symupload.cc b/src/tools/windows/symupload/symupload.cc
index d829aa91..25de747a 100644
--- a/src/tools/windows/symupload/symupload.cc
+++ b/src/tools/windows/symupload/symupload.cc
@@ -182,7 +182,7 @@ int wmain(int argc, wchar_t *argv[]) {
}
bool success = HTTPUpload::SendRequest(url, parameters,
- symbol_file, L"symbol_file");
+ symbol_file, L"symbol_file", NULL);
_wunlink(symbol_file.c_str());
if (!success) {