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:
incrementalist 2006-12-08 20:45:20 +00:00
parent f33b8d2d07
commit dd7c38baae
5 changed files with 86 additions and 11 deletions

View file

@ -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

View file

@ -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.

View file

@ -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
@ -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) {

View file

@ -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);

View file

@ -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) {