aboutsummaryrefslogtreecommitdiff
path: root/src/common/windows/symbol_collector_client.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/windows/symbol_collector_client.cc')
-rw-r--r--src/common/windows/symbol_collector_client.cc155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/common/windows/symbol_collector_client.cc b/src/common/windows/symbol_collector_client.cc
new file mode 100644
index 00000000..30c663ed
--- /dev/null
+++ b/src/common/windows/symbol_collector_client.cc
@@ -0,0 +1,155 @@
+#include "common/windows/symbol_collector_client.h"
+
+#include <stdio.h>
+
+#include <regex>
+
+#include "common/windows/http_upload.h"
+
+namespace google_breakpad {
+
+ // static
+ bool SymbolCollectorClient::CreateUploadUrl(
+ wstring& api_url,
+ wstring& api_key,
+ UploadUrlResponse *uploadUrlResponse) {
+ wstring url = api_url +
+ L"/v1/uploads:create"
+ L"?key=" + api_key;
+ wstring response;
+ int response_code;
+
+ if (!HTTPUpload::SendSimplePostRequest(
+ url,
+ L"",
+ L"",
+ NULL,
+ &response,
+ &response_code)) {
+ wprintf(L"Failed to create upload url.\n");
+ wprintf(L"Response code: %ld\n", response_code);
+ wprintf(L"Response:\n");
+ wprintf(L"%s\n", response.c_str());
+ return false;
+ }
+
+ // Note camel-case rather than underscores.
+ std::wregex upload_url_regex(L"\"uploadUrl\": \"([^\"]+)\"");
+ std::wregex upload_key_regex(L"\"uploadKey\": \"([^\"]+)\"");
+
+ std::wsmatch upload_url_match;
+ if (!std::regex_search(response, upload_url_match, upload_url_regex) ||
+ upload_url_match.size() != 2) {
+ wprintf(L"Failed to parse create url response.");
+ wprintf(L"Response:\n");
+ wprintf(L"%s\n", response.c_str());
+ return false;
+ }
+ wstring upload_url = upload_url_match[1].str();
+
+ std::wsmatch upload_key_match;
+ if (!std::regex_search(response, upload_key_match, upload_key_regex) ||
+ upload_key_match.size() != 2) {
+ wprintf(L"Failed to parse create url response.");
+ wprintf(L"Response:\n");
+ wprintf(L"%s\n", response.c_str());
+ return false;
+ }
+ wstring upload_key = upload_key_match[1].str();
+
+ uploadUrlResponse->upload_url = upload_url;
+ uploadUrlResponse->upload_key = upload_key;
+ return true;
+ }
+
+ // static
+ CompleteUploadResult SymbolCollectorClient::CompleteUpload(
+ wstring& api_url,
+ wstring& api_key,
+ const wstring& upload_key,
+ const wstring& debug_file,
+ const wstring& debug_id) {
+ wstring url = api_url +
+ L"/v1/uploads/" + upload_key + L":complete"
+ L"?key=" + api_key;
+ wstring body =
+ L"{ symbol_id: {"
+ L"debug_file: \"" + debug_file + L"\", "
+ L"debug_id: \"" + debug_id + L"\" "
+ L"} }";
+ wstring response;
+ int response_code;
+
+ if (!HTTPUpload::SendSimplePostRequest(
+ url,
+ body,
+ L"application/json",
+ NULL,
+ &response,
+ &response_code)) {
+ wprintf(L"Failed to complete upload.\n");
+ wprintf(L"Response code: %ld\n", response_code);
+ wprintf(L"Response:\n");
+ wprintf(L"%s\n", response.c_str());
+ return CompleteUploadResult::Error;
+ }
+
+ std::wregex result_regex(L"\"result\": \"([^\"]+)\"");
+ std::wsmatch result_match;
+ if (!std::regex_search(response, result_match, result_regex) ||
+ result_match.size() != 2) {
+ wprintf(L"Failed to parse complete upload response.");
+ wprintf(L"Response:\n");
+ wprintf(L"%s\n", response.c_str());
+ return CompleteUploadResult::Error;
+ }
+ wstring result = result_match[1].str();
+
+ if (result.compare(L"DUPLICATE_DATA") == 0) {
+ return CompleteUploadResult::DuplicateData;
+ }
+
+ return CompleteUploadResult::Ok;
+ }
+
+ // static
+ SymbolStatus SymbolCollectorClient::CheckSymbolStatus(
+ wstring& api_url,
+ wstring& api_key,
+ const wstring& debug_file,
+ const wstring& debug_id) {
+ wstring response;
+ int response_code;
+ wstring url = api_url +
+ L"/v1/symbols/" + debug_file + L"/" + debug_id + L":checkStatus"
+ L"?key=" + api_key;
+
+ if (!HTTPUpload::SendGetRequest(
+ url,
+ NULL,
+ &response,
+ &response_code)) {
+ wprintf(L"Failed to check symbol status.\n");
+ wprintf(L"Response code: %ld\n", response_code);
+ wprintf(L"Response:\n");
+ wprintf(L"%s\n", response.c_str());
+ return SymbolStatus::Unknown;
+ }
+
+ std::wregex status_regex(L"\"status\": \"([^\"]+)\"");
+ std::wsmatch status_match;
+ if (!std::regex_search(response, status_match, status_regex) ||
+ status_match.size() != 2) {
+ wprintf(L"Failed to parse check symbol status response.");
+ wprintf(L"Response:\n");
+ wprintf(L"%s\n", response.c_str());
+ return SymbolStatus::Unknown;
+ }
+ wstring status = status_match[1].str();
+
+ return (status.compare(L"FOUND") == 0) ?
+ SymbolStatus::Found :
+ SymbolStatus::Missing;
+ }
+
+} // namespace google_breakpad \ No newline at end of file