This patch fixes Airbag issue #44.
Summary of this patch: * It adds a new wstring* parameter to the end of both SendCrashReport() and HTTPUpload::SendRequest(), which can be NULL. * If the request isn't successful, the result parameter isn't touched. * It adds HTTPUpload::UTF8ToWide() to allow the response to be returned as a wstring, * It changes the return value of SendRequest (and by extension, SendCrashReport) so that if the size of the response body isn't exactly the same as the value given in the Content-Length header, the return value is false (in addition to the previous semantics). * It also updates symupload.cc to account for the new parameter in SendRequest(). git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@81 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
f33b8d2d07
commit
dd7c38baae
5 changed files with 86 additions and 11 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
@ -261,6 +296,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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue