From c34fc8697282277d8cf5ec625aa709ff125d5d6d Mon Sep 17 00:00:00 2001 From: Nelson Billing Date: Thu, 19 May 2022 15:16:12 -0700 Subject: [PATCH] Make sym-upload-v2 windows code shareable. Change-Id: I228c93655203977b27052a85705c42bafef1e1ef Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3656055 Reviewed-by: Ivan Penkov --- src/common/windows/sym_upload_v2_protocol.cc | 87 +++++++++++++++ src/common/windows/sym_upload_v2_protocol.h | 52 +++++++++ src/tools/windows/symupload/symupload.cc | 105 ++----------------- 3 files changed, 145 insertions(+), 99 deletions(-) create mode 100644 src/common/windows/sym_upload_v2_protocol.cc create mode 100644 src/common/windows/sym_upload_v2_protocol.h diff --git a/src/common/windows/sym_upload_v2_protocol.cc b/src/common/windows/sym_upload_v2_protocol.cc new file mode 100644 index 00000000..4481cc25 --- /dev/null +++ b/src/common/windows/sym_upload_v2_protocol.cc @@ -0,0 +1,87 @@ +#include "common/windows/sym_upload_v2_protocol.h" + +#include + +#include "common/windows/http_upload.h" +#include "common/windows/symbol_collector_client.h" + +using google_breakpad::CompleteUploadResult; +using google_breakpad::HTTPUpload; +using google_breakpad::SymbolCollectorClient; +using google_breakpad::SymbolStatus; +using google_breakpad::UploadUrlResponse; +using std::wstring; + +namespace google_breakpad { + +static bool SymUploadV2ProtocolSend(const wchar_t* api_url, + const wchar_t* api_key, + int* timeout_ms, + const wstring& debug_file, + const wstring& debug_id, + const wstring& symbol_filename, + bool force) { + wstring url(api_url); + wstring key(api_key); + + if (!force) { + SymbolStatus symbolStatus = SymbolCollectorClient::CheckSymbolStatus( + url, key, timeout_ms, debug_file, debug_id); + if (symbolStatus == SymbolStatus::Found) { + wprintf( + L"Symbol file already exists, upload aborted." + L" Use \"-f\" to overwrite.\n"); + return true; + } else if (symbolStatus == SymbolStatus::Unknown) { + wprintf(L"Failed to get check for existing symbol.\n"); + return false; + } + } + + UploadUrlResponse uploadUrlResponse; + if (!SymbolCollectorClient::CreateUploadUrl(url, key, timeout_ms, + &uploadUrlResponse)) { + wprintf(L"Failed to create upload URL.\n"); + return false; + } + + wstring signed_url = uploadUrlResponse.upload_url; + wstring upload_key = uploadUrlResponse.upload_key; + wstring response; + int response_code; + bool success = HTTPUpload::SendPutRequest( + signed_url, symbol_filename, timeout_ms, &response, &response_code); + if (!success) { + wprintf(L"Failed to send symbol file.\n"); + wprintf(L"Response code: %ld\n", response_code); + wprintf(L"Response:\n"); + wprintf(L"%s\n", response.c_str()); + return false; + } else if (response_code == 0) { + wprintf(L"Failed to send symbol file: No response code\n"); + return false; + } else if (response_code != 200) { + wprintf(L"Failed to send symbol file: Response code %ld\n", response_code); + wprintf(L"Response:\n"); + wprintf(L"%s\n", response.c_str()); + return false; + } + + CompleteUploadResult completeUploadResult = + SymbolCollectorClient::CompleteUpload(url, key, timeout_ms, upload_key, + debug_file, debug_id); + if (completeUploadResult == CompleteUploadResult::Error) { + wprintf(L"Failed to complete upload.\n"); + return false; + } else if (completeUploadResult == CompleteUploadResult::DuplicateData) { + wprintf( + L"Uploaded file checksum matched existing file checksum," + L" no change necessary.\n"); + } else { + wprintf(L"Successfully sent the symbol file.\n"); + } + + return true; +} + +} // namespace google_breakpad \ No newline at end of file diff --git a/src/common/windows/sym_upload_v2_protocol.h b/src/common/windows/sym_upload_v2_protocol.h new file mode 100644 index 00000000..24f31f2c --- /dev/null +++ b/src/common/windows/sym_upload_v2_protocol.h @@ -0,0 +1,52 @@ +// Copyright (c) 2022, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef COMMON_WINDOWS_SYM_UPLOAD_V2_PROTOCOL_H_ +#define COMMON_WINDOWS_SYM_UPLOAD_V2_PROTOCOL_H_ + +#include + +namespace google_breakpad { + +// Sends file at |symbol_filename| using the sym-upload-v2 protocol to +// |api_url| using key |api_key|, and using identifiers |debug_file| and +// |debug_id|. |timeout_ms| is the number of milliseconds to wait before +// terminating the upload attempt. If |force| is set then it will overwrite an +// existing file with the same |debug_file| and |debug_id| in the store. +bool SymUploadV2ProtocolSend(const wchar_t* api_url, + const wchar_t* api_key, + int* timeout_ms, + const std::wstring& debug_file, + const std::wstring& debug_id, + const std::wstring& symbol_filename, + bool force); + +} // namespace google_breakpad + +#endif // COMMON_WINDOWS_SYM_UPLOAD_V2_PROTOCOL_H_ \ No newline at end of file diff --git a/src/tools/windows/symupload/symupload.cc b/src/tools/windows/symupload/symupload.cc index 3a26ca89..6d534e41 100644 --- a/src/tools/windows/symupload/symupload.cc +++ b/src/tools/windows/symupload/symupload.cc @@ -56,20 +56,17 @@ #include "common/windows/http_upload.h" #include "common/windows/pdb_source_line_writer.h" +#include "common/windows/sym_upload_v2_protocol.h" #include "common/windows/symbol_collector_client.h" -using std::string; -using std::wstring; -using std::vector; -using std::map; using google_breakpad::HTTPUpload; -using google_breakpad::SymbolCollectorClient; -using google_breakpad::SymbolStatus; -using google_breakpad::UploadUrlResponse; -using google_breakpad::CompleteUploadResult; using google_breakpad::PDBModuleInfo; using google_breakpad::PDBSourceLineWriter; using google_breakpad::WindowsStringUtils; +using std::map; +using std::string; +using std::vector; +using std::wstring; // Extracts the file version information for the given filename, // as a string, for example, "1.2.3.4". Returns true on success. @@ -160,96 +157,6 @@ static bool DumpSymbolsToTempFile(const wchar_t* file, return writer.GetModuleInfo(pdb_info); } -static bool DoSymUploadV2( - const wchar_t* api_url, - const wchar_t* api_key, - int* timeout_ms, - const wstring& debug_file, - const wstring& debug_id, - const wstring& symbol_file, - bool force) { - wstring url(api_url); - wstring key(api_key); - - if (!force) { - SymbolStatus symbolStatus = SymbolCollectorClient::CheckSymbolStatus( - url, - key, - timeout_ms, - debug_file, - debug_id); - if (symbolStatus == SymbolStatus::Found) { - wprintf(L"Symbol file already exists, upload aborted." - L" Use \"-f\" to overwrite.\n"); - return true; - } - else if (symbolStatus == SymbolStatus::Unknown) { - wprintf(L"Failed to get check for existing symbol.\n"); - return false; - } - } - - UploadUrlResponse uploadUrlResponse; - if (!SymbolCollectorClient::CreateUploadUrl( - url, - key, - timeout_ms, - &uploadUrlResponse)) { - wprintf(L"Failed to create upload URL.\n"); - return false; - } - - wstring signed_url = uploadUrlResponse.upload_url; - wstring upload_key = uploadUrlResponse.upload_key; - wstring response; - int response_code; - bool success = HTTPUpload::SendPutRequest( - signed_url, - symbol_file, - timeout_ms, - &response, - &response_code); - if (!success) { - wprintf(L"Failed to send symbol file.\n"); - wprintf(L"Response code: %ld\n", response_code); - wprintf(L"Response:\n"); - wprintf(L"%s\n", response.c_str()); - return false; - } - else if (response_code == 0) { - wprintf(L"Failed to send symbol file: No response code\n"); - return false; - } - else if (response_code != 200) { - wprintf(L"Failed to send symbol file: Response code %ld\n", response_code); - wprintf(L"Response:\n"); - wprintf(L"%s\n", response.c_str()); - return false; - } - - CompleteUploadResult completeUploadResult = - SymbolCollectorClient::CompleteUpload( - url, - key, - timeout_ms, - upload_key, - debug_file, - debug_id); - if (completeUploadResult == CompleteUploadResult::Error) { - wprintf(L"Failed to complete upload.\n"); - return false; - } - else if (completeUploadResult == CompleteUploadResult::DuplicateData) { - wprintf(L"Uploaded file checksum matched existing file checksum," - L" no change necessary.\n"); - } - else { - wprintf(L"Successfully sent the symbol file.\n"); - } - - return true; -} - __declspec(noreturn) void printUsageAndExit() { wprintf(L"Usage:\n\n" L" symupload [--i] [--timeout NN] [--product product_name] ^\n" @@ -342,7 +249,7 @@ int wmain(int argc, wchar_t* argv[]) { api_url = argv[currentarg++]; api_key = argv[currentarg++]; - success = DoSymUploadV2( + success = google_breakpad::SymUploadV2ProtocolSend( api_url, api_key, timeout == -1 ? nullptr : &timeout, pdb_info.debug_file, pdb_info.debug_identifier, symbol_file, force); } else {