diff options
-rw-r--r-- | src/client/windows/sender/crash_report_sender.cc | 4 | ||||
-rw-r--r-- | src/client/windows/sender/crash_report_sender.h | 9 | ||||
-rw-r--r-- | src/common/windows/http_upload.cc | 64 | ||||
-rw-r--r-- | src/common/windows/http_upload.h | 18 | ||||
-rw-r--r-- | src/tools/windows/symupload/symupload.cc | 2 |
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> ¶meters, - 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> ¶meters, - 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> ¶meters, 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> ¶meters, 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) { |