Support for multiple upload files in CrashReportSender/HTTPUpload
A=David Major <dmajor@mozilla.com> BUG=https://bugzilla.mozilla.org/show_bug.cgi?id=1048091 R=ted@mielczarek.org Review URL: https://bugzilla.mozilla.org/show_bug.cgi?id=1048091 .
This commit is contained in:
parent
dbf56c53a0
commit
7685dfc567
9 changed files with 63 additions and 58 deletions
|
@ -59,7 +59,7 @@ CrashReportSender::CrashReportSender(const wstring &checkpoint_file)
|
|||
|
||||
ReportResult CrashReportSender::SendCrashReport(
|
||||
const wstring &url, const map<wstring, wstring> ¶meters,
|
||||
const wstring &dump_file_name, wstring *report_code) {
|
||||
const map<wstring, wstring> &files, wstring *report_code) {
|
||||
int today = GetCurrentDate();
|
||||
if (today == last_sent_date_ &&
|
||||
max_reports_per_day_ != -1 &&
|
||||
|
@ -69,7 +69,7 @@ ReportResult CrashReportSender::SendCrashReport(
|
|||
|
||||
int http_response = 0;
|
||||
bool result = HTTPUpload::SendRequest(
|
||||
url, parameters, dump_file_name, L"upload_file_minidump", NULL, report_code,
|
||||
url, parameters, files, NULL, report_code,
|
||||
&http_response);
|
||||
|
||||
if (result) {
|
||||
|
|
|
@ -77,7 +77,7 @@ class CrashReportSender {
|
|||
|
||||
int max_reports_per_day() const { return max_reports_per_day_; }
|
||||
|
||||
// Sends the specified minidump file, along with the map of
|
||||
// Sends the specified files, along with the map of
|
||||
// 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.
|
||||
|
@ -89,7 +89,7 @@ class CrashReportSender {
|
|||
// (Otherwise, report_code will be unchanged.)
|
||||
ReportResult SendCrashReport(const wstring &url,
|
||||
const map<wstring, wstring> ¶meters,
|
||||
const wstring &dump_file_name,
|
||||
const map<wstring, wstring> &files,
|
||||
wstring *report_code);
|
||||
|
||||
private:
|
||||
|
|
|
@ -56,8 +56,7 @@ static const char kUserAgent[] = "Breakpad/1.0 (Linux)";
|
|||
// static
|
||||
bool HTTPUpload::SendRequest(const string &url,
|
||||
const map<string, string> ¶meters,
|
||||
const string &upload_file,
|
||||
const string &file_part_name,
|
||||
const map<string, string> &files,
|
||||
const string &proxy,
|
||||
const string &proxy_user_pwd,
|
||||
const string &ca_certificate_file,
|
||||
|
@ -135,11 +134,13 @@ bool HTTPUpload::SendRequest(const string &url,
|
|||
CURLFORM_COPYCONTENTS, iter->second.c_str(),
|
||||
CURLFORM_END);
|
||||
|
||||
// Add form file.
|
||||
(*curl_formadd)(&formpost, &lastptr,
|
||||
CURLFORM_COPYNAME, file_part_name.c_str(),
|
||||
CURLFORM_FILE, upload_file.c_str(),
|
||||
CURLFORM_END);
|
||||
// Add form files.
|
||||
for (iter = files.begin(); iter != files.end(); ++iter) {
|
||||
(*curl_formadd)(&formpost, &lastptr,
|
||||
CURLFORM_COPYNAME, iter->first.c_str(),
|
||||
CURLFORM_FILE, iter->second.c_str(),
|
||||
CURLFORM_END);
|
||||
}
|
||||
|
||||
(*curl_easy_setopt)(curl, CURLOPT_HTTPPOST, formpost);
|
||||
|
||||
|
|
|
@ -45,9 +45,9 @@ using std::map;
|
|||
|
||||
class HTTPUpload {
|
||||
public:
|
||||
// Sends the given set of parameters, along with the contents of
|
||||
// upload_file, as a multipart POST request to the given URL.
|
||||
// file_part_name contains the name of the file part of the request
|
||||
// Sends the given sets of parameters and files as a multipart POST
|
||||
// request to the given URL.
|
||||
// Each key in |files| is the name of the file part of the request
|
||||
// (i.e. it corresponds to the name= attribute on an <input type="file">.
|
||||
// Parameter names must contain only printable ASCII characters,
|
||||
// and may not contain a quote (") character.
|
||||
|
@ -60,8 +60,7 @@ class HTTPUpload {
|
|||
// returned in error_description.
|
||||
static bool SendRequest(const string &url,
|
||||
const map<string, string> ¶meters,
|
||||
const string &upload_file,
|
||||
const string &file_part_name,
|
||||
const map<string, string> &files,
|
||||
const string &proxy,
|
||||
const string &proxy_user_pwd,
|
||||
const string &ca_certificate_file,
|
||||
|
|
|
@ -64,8 +64,7 @@ class HTTPUpload::AutoInternetHandle {
|
|||
// static
|
||||
bool HTTPUpload::SendRequest(const wstring &url,
|
||||
const map<wstring, wstring> ¶meters,
|
||||
const wstring &upload_file,
|
||||
const wstring &file_part_name,
|
||||
const map<wstring, wstring> &files,
|
||||
int *timeout,
|
||||
wstring *response_body,
|
||||
int *response_code) {
|
||||
|
@ -143,8 +142,7 @@ bool HTTPUpload::SendRequest(const wstring &url,
|
|||
HTTP_ADDREQ_FLAG_ADD);
|
||||
|
||||
string request_body;
|
||||
if (!GenerateRequestBody(parameters, upload_file,
|
||||
file_part_name, boundary, &request_body)) {
|
||||
if (!GenerateRequestBody(parameters, files, boundary, &request_body)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -268,15 +266,9 @@ wstring HTTPUpload::GenerateRequestHeader(const wstring &boundary) {
|
|||
|
||||
// static
|
||||
bool HTTPUpload::GenerateRequestBody(const map<wstring, wstring> ¶meters,
|
||||
const wstring &upload_file,
|
||||
const wstring &file_part_name,
|
||||
const map<wstring, wstring> &files,
|
||||
const wstring &boundary,
|
||||
string *request_body) {
|
||||
vector<char> contents;
|
||||
if (!GetFileContents(upload_file, &contents)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string boundary_str = WideToUTF8(boundary);
|
||||
if (boundary_str.empty()) {
|
||||
return false;
|
||||
|
@ -293,28 +285,36 @@ bool HTTPUpload::GenerateRequestBody(const map<wstring, wstring> ¶meters,
|
|||
WideToUTF8(pos->second) + "\r\n");
|
||||
}
|
||||
|
||||
// Now append the upload file as a binary (octet-stream) part
|
||||
string filename_utf8 = WideToUTF8(upload_file);
|
||||
if (filename_utf8.empty()) {
|
||||
return false;
|
||||
}
|
||||
for (map<wstring, wstring>::const_iterator pos = files.begin();
|
||||
pos != files.end(); ++pos) {
|
||||
vector<char> contents;
|
||||
if (!GetFileContents(pos->second, &contents)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string file_part_name_utf8 = WideToUTF8(file_part_name);
|
||||
if (file_part_name_utf8.empty()) {
|
||||
return false;
|
||||
}
|
||||
// Now append the upload files as a binary (octet-stream) part
|
||||
string filename_utf8 = WideToUTF8(pos->second);
|
||||
if (filename_utf8.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
request_body->append("--" + boundary_str + "\r\n");
|
||||
request_body->append("Content-Disposition: form-data; "
|
||||
"name=\"" + file_part_name_utf8 + "\"; "
|
||||
"filename=\"" + filename_utf8 + "\"\r\n");
|
||||
request_body->append("Content-Type: application/octet-stream\r\n");
|
||||
request_body->append("\r\n");
|
||||
string file_part_name_utf8 = WideToUTF8(pos->first);
|
||||
if (file_part_name_utf8.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!contents.empty()) {
|
||||
request_body->append("--" + boundary_str + "\r\n");
|
||||
request_body->append("Content-Disposition: form-data; "
|
||||
"name=\"" + file_part_name_utf8 + "\"; "
|
||||
"filename=\"" + filename_utf8 + "\"\r\n");
|
||||
request_body->append("Content-Type: application/octet-stream\r\n");
|
||||
request_body->append("\r\n");
|
||||
|
||||
if (!contents.empty()) {
|
||||
request_body->append(&(contents[0]), contents.size());
|
||||
}
|
||||
request_body->append("\r\n");
|
||||
}
|
||||
request_body->append("\r\n");
|
||||
request_body->append("--" + boundary_str + "--\r\n");
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -54,9 +54,9 @@ using std::vector;
|
|||
|
||||
class HTTPUpload {
|
||||
public:
|
||||
// Sends the given set of parameters, along with the contents of
|
||||
// upload_file, as a multipart POST request to the given URL.
|
||||
// file_part_name contains the name of the file part of the request
|
||||
// Sends the given sets of parameters and files as a multipart POST
|
||||
// request to the given URL.
|
||||
// Each key in |files| is the name of the file part of the request
|
||||
// (i.e. it corresponds to the name= attribute on an <input type="file">.
|
||||
// Parameter names must contain only printable ASCII characters,
|
||||
// and may not contain a quote (") character.
|
||||
|
@ -67,8 +67,7 @@ class HTTPUpload {
|
|||
// received (or 0 if the request failed before getting an HTTP response).
|
||||
static bool SendRequest(const wstring &url,
|
||||
const map<wstring, wstring> ¶meters,
|
||||
const wstring &upload_file,
|
||||
const wstring &file_part_name,
|
||||
const map<wstring, wstring> &files,
|
||||
int *timeout,
|
||||
wstring *response_body,
|
||||
int *response_code);
|
||||
|
@ -88,12 +87,11 @@ class HTTPUpload {
|
|||
// Generates a HTTP request header for a multipart form submit.
|
||||
static wstring GenerateRequestHeader(const wstring &boundary);
|
||||
|
||||
// Given a set of parameters, an upload filename, and a file part name,
|
||||
// Given a set of parameters, a set of upload files, and a file part name,
|
||||
// generates a multipart request body string with these parameters
|
||||
// and minidump contents. Returns true on success.
|
||||
static bool GenerateRequestBody(const map<wstring, wstring> ¶meters,
|
||||
const wstring &upload_file,
|
||||
const wstring &file_part_name,
|
||||
const map<wstring, wstring> &files,
|
||||
const wstring &boundary,
|
||||
string *request_body);
|
||||
|
||||
|
|
|
@ -62,12 +62,14 @@ static void Start(Options *options) {
|
|||
parameters["prod"] = options->product;
|
||||
parameters["ver"] = options->version;
|
||||
|
||||
std::map<string, string> files;
|
||||
files["upload_file_minidump"] = options->minidumpPath;
|
||||
|
||||
// Send it
|
||||
string response, error;
|
||||
bool success = HTTPUpload::SendRequest(options->uploadURLStr,
|
||||
parameters,
|
||||
options->minidumpPath,
|
||||
"upload_file_minidump",
|
||||
files,
|
||||
options->proxy,
|
||||
options->proxy_user_pwd,
|
||||
"",
|
||||
|
|
|
@ -139,12 +139,15 @@ static void Start(Options *options) {
|
|||
parameters["debug_file"] = module_parts[4];
|
||||
parameters["code_file"] = module_parts[4];
|
||||
parameters["debug_identifier"] = compacted_id;
|
||||
|
||||
std::map<string, string> files;
|
||||
files["symbol_file"] = options->symbolsPath;
|
||||
|
||||
string response, error;
|
||||
long response_code;
|
||||
bool success = HTTPUpload::SendRequest(options->uploadURLStr,
|
||||
parameters,
|
||||
options->symbolsPath,
|
||||
"symbol_file",
|
||||
files,
|
||||
options->proxy,
|
||||
options->proxy_user_pwd,
|
||||
"",
|
||||
|
|
|
@ -228,12 +228,14 @@ int wmain(int argc, wchar_t *argv[]) {
|
|||
fwprintf(stderr, L"Warning: Could not get file version for %s\n", module);
|
||||
}
|
||||
|
||||
map<wstring, wstring> files;
|
||||
files[L"symbol_file"] = symbol_file;
|
||||
|
||||
bool success = true;
|
||||
|
||||
while (currentarg < argc) {
|
||||
int response_code;
|
||||
if (!HTTPUpload::SendRequest(argv[currentarg], parameters,
|
||||
symbol_file, L"symbol_file",
|
||||
if (!HTTPUpload::SendRequest(argv[currentarg], parameters, files,
|
||||
timeout == -1 ? NULL : &timeout,
|
||||
nullptr, &response_code)) {
|
||||
success = false;
|
||||
|
|
Loading…
Reference in a new issue