summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/breakpad-patches/09-json-upload.patch
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/crashreporter/breakpad-patches/09-json-upload.patch')
-rw-r--r--toolkit/crashreporter/breakpad-patches/09-json-upload.patch333
1 files changed, 333 insertions, 0 deletions
diff --git a/toolkit/crashreporter/breakpad-patches/09-json-upload.patch b/toolkit/crashreporter/breakpad-patches/09-json-upload.patch
new file mode 100644
index 0000000000..8ad73bc681
--- /dev/null
+++ b/toolkit/crashreporter/breakpad-patches/09-json-upload.patch
@@ -0,0 +1,333 @@
+diff --git a/src/common/linux/http_upload.cc b/src/common/linux/http_upload.cc
+index 702526af..0a1019dd 100644
+--- a/src/common/linux/http_upload.cc
++++ b/src/common/linux/http_upload.cc
+@@ -55,7 +55,7 @@ static const char kUserAgent[] = "Breakpad/1.0 (Linux)";
+
+ // static
+ bool HTTPUpload::SendRequest(const string &url,
+- const map<string, string> &parameters,
++ const string &parameters,
+ const map<string, string> &files,
+ const string &proxy,
+ const string &proxy_user_pwd,
+@@ -66,9 +66,6 @@ bool HTTPUpload::SendRequest(const string &url,
+ if (response_code != NULL)
+ *response_code = 0;
+
+- if (!CheckParameters(parameters))
+- return false;
+-
+ // We may have been linked statically; if curl_easy_init is in the
+ // current binary, no need to search for a dynamic version.
+ void* curl_lib = dlopen(NULL, RTLD_NOW);
+@@ -133,14 +130,14 @@ bool HTTPUpload::SendRequest(const string &url,
+ // Add form data.
+ CURLFORMcode (*curl_formadd)(struct curl_httppost **, struct curl_httppost **, ...);
+ *(void**) (&curl_formadd) = dlsym(curl_lib, "curl_formadd");
+- map<string, string>::const_iterator iter = parameters.begin();
+- for (; iter != parameters.end(); ++iter)
+- (*curl_formadd)(&formpost, &lastptr,
+- CURLFORM_COPYNAME, iter->first.c_str(),
+- CURLFORM_COPYCONTENTS, iter->second.c_str(),
+- CURLFORM_END);
++ (*curl_formadd)(&formpost, &lastptr, CURLFORM_COPYNAME, "extra",
++ CURLFORM_BUFFER, "extra.json", CURLFORM_BUFFERPTR,
++ parameters.c_str(), CURLFORM_BUFFERLENGTH,
++ parameters.length(), CURLFORM_CONTENTTYPE, "application/json",
++ CURLFORM_END);
+
+ // Add form files.
++ map<string, string>::const_iterator iter = files.begin();
+ for (iter = files.begin(); iter != files.end(); ++iter) {
+ (*curl_formadd)(&formpost, &lastptr,
+ CURLFORM_COPYNAME, iter->first.c_str(),
+@@ -210,21 +207,4 @@ bool HTTPUpload::CheckCurlLib(void* curl_lib) {
+ dlsym(curl_lib, "curl_easy_setopt");
+ }
+
+-// static
+-bool HTTPUpload::CheckParameters(const map<string, string> &parameters) {
+- for (map<string, string>::const_iterator pos = parameters.begin();
+- pos != parameters.end(); ++pos) {
+- const string &str = pos->first;
+- if (str.size() == 0)
+- return false; // disallow empty parameter names
+- for (unsigned int i = 0; i < str.size(); ++i) {
+- int c = str[i];
+- if (c < 32 || c == '"' || c > 127) {
+- return false;
+- }
+- }
+- }
+- return true;
+-}
+-
+ } // namespace google_breakpad
+diff --git a/src/common/linux/http_upload.h b/src/common/linux/http_upload.h
+index bc1d5d57..95dedebc 100644
+--- a/src/common/linux/http_upload.h
++++ b/src/common/linux/http_upload.h
+@@ -29,7 +29,7 @@
+
+ // HTTPUpload provides a "nice" API to send a multipart HTTP(S) POST
+ // request using libcurl. It currently supports requests that contain
+-// a set of string parameters (key/value pairs), and a file to upload.
++// parameters encoded in a JSON string, and a file to upload.
+
+ #ifndef COMMON_LINUX_HTTP_UPLOAD_H__
+ #define COMMON_LINUX_HTTP_UPLOAD_H__
+@@ -49,8 +49,7 @@ class HTTPUpload {
+ // 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.
++ // Parameters are specified as a JSON-encoded string in |parameters|.
+ // Only HTTP(S) URLs are currently supported. Returns true on success.
+ // If the request is successful and response_body is non-NULL,
+ // the response body will be returned in response_body.
+@@ -59,7 +58,7 @@ class HTTPUpload {
+ // If the send fails, a description of the error will be
+ // returned in error_description.
+ static bool SendRequest(const string &url,
+- const map<string, string> &parameters,
++ const string &parameters,
+ const map<string, string> &files,
+ const string &proxy,
+ const string &proxy_user_pwd,
+@@ -69,11 +68,6 @@ class HTTPUpload {
+ string *error_description);
+
+ private:
+- // Checks that the given list of parameters has only printable
+- // ASCII characters in the parameter name, and does not contain
+- // any quote (") characters. Returns true if so.
+- static bool CheckParameters(const map<string, string> &parameters);
+-
+ // Checks the curl_lib parameter points to a valid curl lib.
+ static bool CheckCurlLib(void* curl_lib);
+
+diff --git a/src/common/mac/HTTPMultipartUpload.h b/src/common/mac/HTTPMultipartUpload.h
+index 42e8fed3..0cea733e 100644
+--- a/src/common/mac/HTTPMultipartUpload.h
++++ b/src/common/mac/HTTPMultipartUpload.h
+@@ -37,7 +37,7 @@
+ @interface HTTPMultipartUpload : NSObject {
+ @protected
+ NSURL *url_; // The destination URL (STRONG)
+- NSDictionary *parameters_; // The key/value pairs for sending data (STRONG)
++ NSMutableString *parameters_; // The JSON payload for sending data (STRONG)
+ NSMutableDictionary *files_; // Dictionary of name/file-path (STRONG)
+ NSString *boundary_; // The boundary string (STRONG)
+ NSHTTPURLResponse *response_; // The response from the send (STRONG)
+@@ -47,8 +47,8 @@
+
+ - (NSURL *)URL;
+
+-- (void)setParameters:(NSDictionary *)parameters;
+-- (NSDictionary *)parameters;
++- (void)setParameters:(NSMutableString *)parameters;
++- (NSMutableString *)parameters;
+
+ - (void)addFileAtPath:(NSString *)path name:(NSString *)name;
+ - (void)addFileContents:(NSData *)data name:(NSString *)name;
+diff --git a/src/common/mac/HTTPMultipartUpload.m b/src/common/mac/HTTPMultipartUpload.m
+index a3677f25..d2480493 100644
+--- a/src/common/mac/HTTPMultipartUpload.m
++++ b/src/common/mac/HTTPMultipartUpload.m
+@@ -93,7 +93,7 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req,
+ - (NSString *)multipartBoundary;
+ // Each of the following methods will append the starting multipart boundary,
+ // but not the ending one.
+-- (NSData *)formDataForKey:(NSString *)key value:(NSString *)value;
++- (NSData *)formDataForJSON:(NSString *)json;
+ - (NSData *)formDataForFileContents:(NSData *)contents name:(NSString *)name;
+ - (NSData *)formDataForFile:(NSString *)file name:(NSString *)name;
+ @end
+@@ -110,13 +110,16 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req,
+ }
+
+ //=============================================================================
+-- (NSData *)formDataForKey:(NSString *)key value:(NSString *)value {
+- NSString *escaped = PercentEncodeNSString(key);
+- NSString *fmt =
+- @"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n";
+- NSString *form = [NSString stringWithFormat:fmt, boundary_, escaped, value];
++- (NSData *)formDataForJSON:(NSString *)json {
++ NSMutableData *data = [NSMutableData data];
++ NSString *fmt = @"--%@\r\nContent-Disposition: form-data; name=\"extra\"; "
++ "filename=\"extra.json\"\r\nContent-Type: application/json\r\n\r\n";
++ NSString *form = [NSString stringWithFormat:fmt, boundary_];
++
++ [data appendData:[form dataUsingEncoding:NSUTF8StringEncoding]];
++ [data appendData:[json dataUsingEncoding:NSUTF8StringEncoding]];
+
+- return [form dataUsingEncoding:NSUTF8StringEncoding];
++ return data;
+ }
+
+ //=============================================================================
+@@ -171,15 +174,15 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req,
+ }
+
+ //=============================================================================
+-- (void)setParameters:(NSDictionary *)parameters {
++- (void)setParameters:(NSMutableString *)parameters {
+ if (parameters != parameters_) {
+ [parameters_ release];
+- parameters_ = [parameters copy];
++ parameters_ = [parameters mutableCopy];
+ }
+ }
+
+ //=============================================================================
+-- (NSDictionary *)parameters {
++- (NSMutableString *)parameters {
+ return parameters_;
+ }
+
+@@ -210,16 +213,8 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req,
+ [req setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",
+ boundary_] forHTTPHeaderField:@"Content-type"];
+
+- // Add any parameters to the message
+- NSArray *parameterKeys = [parameters_ allKeys];
+- NSString *key;
+-
+- NSInteger count = [parameterKeys count];
+- for (NSInteger i = 0; i < count; ++i) {
+- key = [parameterKeys objectAtIndex:i];
+- [postBody appendData:[self formDataForKey:key
+- value:[parameters_ objectForKey:key]]];
+- }
++ // Add JSON parameters to the message
++ [postBody appendData:[self formDataForJSON:parameters_]];
+
+ // Add any files to the message
+ NSArray *fileNames = [files_ allKeys];
+diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc
+index b0cc9078..5df17e1a 100644
+--- a/src/common/windows/http_upload.cc
++++ b/src/common/windows/http_upload.cc
+@@ -141,23 +141,6 @@ namespace {
+ return rv;
+ }
+
+- bool CheckParameters(const map<wstring, wstring> &parameters) {
+- for (map<wstring, wstring>::const_iterator pos = parameters.begin();
+- pos != parameters.end(); ++pos) {
+- const wstring &str = pos->first;
+- if (str.size() == 0) {
+- return false; // disallow empty parameter names
+- }
+- for (unsigned int i = 0; i < str.size(); ++i) {
+- wchar_t c = str[i];
+- if (c < 32 || c == '"' || c > 127) {
+- return false;
+- }
+- }
+- }
+- return true;
+- }
+-
+ // Converts a UTF16 string to UTF8.
+ string WideToUTF8(const wstring &wide) {
+ return WideToMBCP(wide, CP_UTF8);
+@@ -390,7 +373,7 @@ namespace {
+ return true;
+ }
+
+- bool GenerateRequestBody(const map<wstring, wstring> &parameters,
++ bool GenerateRequestBody(const string &parameters,
+ const map<wstring, wstring> &files,
+ const wstring &boundary,
+ string *request_body) {
+@@ -401,14 +384,19 @@ namespace {
+
+ request_body->clear();
+
+- // Append each of the parameter pairs as a form-data part
+- for (map<wstring, wstring>::const_iterator pos = parameters.begin();
+- pos != parameters.end(); ++pos) {
+- request_body->append("--" + boundary_str + "\r\n");
+- request_body->append("Content-Disposition: form-data; name=\"" +
+- WideToUTF8(pos->first) + "\"\r\n\r\n" +
+- WideToUTF8(pos->second) + "\r\n");
++ // Append the extra data as a single JSON form entry
++ request_body->append("--" + boundary_str + "\r\n");
++ request_body->append(
++ "Content-Disposition: form-data; "
++ "name=\"extra\"; "
++ "filename=\"extra.json\"\r\n");
++ request_body->append("Content-Type: application/json\r\n");
++ request_body->append("\r\n");
++
++ if (!parameters.empty()) {
++ request_body->append(parameters);
+ }
++ request_body->append("\r\n");
+
+ // Now append each upload file as a binary (octet-stream) part
+ for (map<wstring, wstring>::const_iterator pos = files.begin();
+@@ -463,16 +451,11 @@ namespace google_breakpad {
+
+ bool HTTPUpload::SendMultipartPostRequest(
+ const wstring& url,
+- const map<wstring, wstring>& parameters,
++ const string& parameters,
+ const map<wstring, wstring>& files,
+ int* timeout_ms,
+ wstring* response_body,
+ int* response_code) {
+- // TODO(bryner): support non-ASCII parameter names
+- if (!CheckParameters(parameters)) {
+- return false;
+- }
+-
+ wstring boundary = GenerateMultipartBoundary();
+ wstring content_type_header = GenerateMultipartPostRequestHeader(boundary);
+
+diff --git a/src/common/windows/http_upload.h b/src/common/windows/http_upload.h
+index 57e526e3..1e47f582 100644
+--- a/src/common/windows/http_upload.h
++++ b/src/common/windows/http_upload.h
+@@ -29,7 +29,7 @@
+
+ // HTTPUpload provides a "nice" API to send a multipart HTTP(S) POST
+ // request using wininet. It currently supports requests that contain
+-// a set of string parameters (key/value pairs), and a file to upload.
++// parameters encoded in a JSON string, and a file to upload.
+
+ #ifndef COMMON_WINDOWS_HTTP_UPLOAD_H_
+ #define COMMON_WINDOWS_HTTP_UPLOAD_H_
+@@ -45,9 +45,9 @@
+
+ namespace google_breakpad {
+
++using std::map;
+ using std::string;
+ using std::wstring;
+-using std::map;
+
+ class HTTPUpload {
+ public:
+@@ -81,8 +81,7 @@ class HTTPUpload {
+ // 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.
++ // Parameters are specified as a JSON-encoded string in |parameters|.
+ // Only HTTP(S) URLs are currently supported. Returns true on success.
+ // If the request is successful and response_body is non-NULL,
+ // the response body will be returned in response_body.
+@@ -90,7 +89,7 @@ class HTTPUpload {
+ // received (or 0 if the request failed before getting an HTTP response).
+ static bool SendMultipartPostRequest(
+ const wstring& url,
+- const map<wstring, wstring>& parameters,
++ const string& parameters,
+ const map<wstring, wstring>& files,
+ int *timeout_ms,
+ wstring *response_body,