From a740aa2625df2c0ed21ed7118bd8ab5faec375b8 Mon Sep 17 00:00:00 2001 From: Nelson Billing Date: Wed, 29 Jul 2020 16:28:25 -0700 Subject: Fix Mac symupload non-XCode builds. Change-Id: Ic4924032faba83fc14f62feaac9a97bbfd0971ed Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2324311 Reviewed-by: Mark Mentovai --- src/common/mac/HTTPGetRequest.h | 42 ++++ src/common/mac/HTTPGetRequest.m | 39 ++++ src/common/mac/HTTPMultipartUpload.h | 28 ++- src/common/mac/HTTPMultipartUpload.m | 63 +++--- src/common/mac/HTTPPutRequest.h | 51 +++++ src/common/mac/HTTPPutRequest.m | 62 ++++++ src/common/mac/HTTPRequest.h | 73 ++++++ src/common/mac/HTTPRequest.m | 213 ++++++++++++++++++ src/common/mac/HTTPSimplePostRequest.h | 57 +++++ src/common/mac/HTTPSimplePostRequest.m | 69 ++++++ src/common/mac/SymbolCollectorClient.h | 102 +++++++++ src/common/mac/SymbolCollectorClient.m | 235 ++++++++++++++++++++ src/common/mac/encoding_util.h | 41 ++++ src/common/mac/encoding_util.m | 47 ++++ src/common/mac/minidump_upload.m | 135 +++++++++++ src/tools/mac/symupload/HTTPGetRequest.h | 42 ---- src/tools/mac/symupload/HTTPGetRequest.m | 39 ---- src/tools/mac/symupload/HTTPPutRequest.h | 51 ----- src/tools/mac/symupload/HTTPPutRequest.m | 62 ------ src/tools/mac/symupload/HTTPRequest.h | 73 ------ src/tools/mac/symupload/HTTPRequest.m | 214 ------------------ src/tools/mac/symupload/HTTPSimplePostRequest.h | 57 ----- src/tools/mac/symupload/HTTPSimplePostRequest.m | 69 ------ src/tools/mac/symupload/SymbolCollectorClient.h | 100 --------- src/tools/mac/symupload/SymbolCollectorClient.m | 247 --------------------- src/tools/mac/symupload/minidump_upload.m | 135 ----------- src/tools/mac/symupload/symupload.m | 144 ++++++------ .../symupload/symupload.xcodeproj/project.pbxproj | 30 +-- src/tools/mac/symupload/util.h | 52 ----- 29 files changed, 1297 insertions(+), 1275 deletions(-) create mode 100644 src/common/mac/HTTPGetRequest.h create mode 100644 src/common/mac/HTTPGetRequest.m create mode 100644 src/common/mac/HTTPPutRequest.h create mode 100644 src/common/mac/HTTPPutRequest.m create mode 100644 src/common/mac/HTTPRequest.h create mode 100644 src/common/mac/HTTPRequest.m create mode 100644 src/common/mac/HTTPSimplePostRequest.h create mode 100644 src/common/mac/HTTPSimplePostRequest.m create mode 100644 src/common/mac/SymbolCollectorClient.h create mode 100644 src/common/mac/SymbolCollectorClient.m create mode 100644 src/common/mac/encoding_util.h create mode 100644 src/common/mac/encoding_util.m create mode 100644 src/common/mac/minidump_upload.m delete mode 100644 src/tools/mac/symupload/HTTPGetRequest.h delete mode 100644 src/tools/mac/symupload/HTTPGetRequest.m delete mode 100644 src/tools/mac/symupload/HTTPPutRequest.h delete mode 100644 src/tools/mac/symupload/HTTPPutRequest.m delete mode 100644 src/tools/mac/symupload/HTTPRequest.h delete mode 100644 src/tools/mac/symupload/HTTPRequest.m delete mode 100644 src/tools/mac/symupload/HTTPSimplePostRequest.h delete mode 100644 src/tools/mac/symupload/HTTPSimplePostRequest.m delete mode 100644 src/tools/mac/symupload/SymbolCollectorClient.h delete mode 100644 src/tools/mac/symupload/SymbolCollectorClient.m delete mode 100644 src/tools/mac/symupload/minidump_upload.m delete mode 100644 src/tools/mac/symupload/util.h (limited to 'src') diff --git a/src/common/mac/HTTPGetRequest.h b/src/common/mac/HTTPGetRequest.h new file mode 100644 index 00000000..3aa316b5 --- /dev/null +++ b/src/common/mac/HTTPGetRequest.h @@ -0,0 +1,42 @@ +// Copyright (c) 2020, 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. + +#import + +#import "HTTPRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Represents a HTTP GET request + */ +@interface HTTPGetRequest : HTTPRequest +@end + +NS_ASSUME_NONNULL_END diff --git a/src/common/mac/HTTPGetRequest.m b/src/common/mac/HTTPGetRequest.m new file mode 100644 index 00000000..f9b7bf0e --- /dev/null +++ b/src/common/mac/HTTPGetRequest.m @@ -0,0 +1,39 @@ +// Copyright (c) 2020, 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. + +#import "HTTPGetRequest.h" + +@implementation HTTPGetRequest + +//============================================================================= +- (NSString*)HTTPMethod { + return @"GET"; +} + +@end diff --git a/src/common/mac/HTTPMultipartUpload.h b/src/common/mac/HTTPMultipartUpload.h index 5eaaa91b..56d5394d 100644 --- a/src/common/mac/HTTPMultipartUpload.h +++ b/src/common/mac/HTTPMultipartUpload.h @@ -27,39 +27,37 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - #import #import "HTTPRequest.h" - /** - Represents a multipart/form-data HTTP upload (POST request). - Each parameter pair is sent as a boundary. - Each file is sent with a name field in addition to the filename and data. - */ +/** + Represents a multipart/form-data HTTP upload (POST request). + Each parameter pair is sent as a boundary. + Each file is sent with a name field in addition to the filename and data. + */ @interface HTTPMultipartUpload : HTTPRequest { @protected - NSDictionary *parameters_; // The key/value pairs for sending data (STRONG) - NSMutableDictionary *files_; // Dictionary of name/file-path (STRONG) - NSString *boundary_; // The boundary string (STRONG) + NSDictionary* parameters_; // The key/value pairs for sending data (STRONG) + NSMutableDictionary* files_; // Dictionary of name/file-path (STRONG) + NSString* boundary_; // The boundary string (STRONG) } /** Sets the parameters that will be sent in the multipart POST request. */ -- (void)setParameters:(NSDictionary *)parameters; -- (NSDictionary *)parameters; +- (void)setParameters:(NSDictionary*)parameters; +- (NSDictionary*)parameters; /** Adds a file to be uploaded in the multipart POST request, by its file path. */ -- (void)addFileAtPath:(NSString *)path name:(NSString *)name; +- (void)addFileAtPath:(NSString*)path name:(NSString*)name; /** Adds a file to be uploaded in the multipart POST request, by its name and contents. */ -- (void)addFileContents:(NSData *)data name:(NSString *)name; -- (NSDictionary *)files; +- (void)addFileContents:(NSData*)data name:(NSString*)name; +- (NSDictionary*)files; @end diff --git a/src/common/mac/HTTPMultipartUpload.m b/src/common/mac/HTTPMultipartUpload.m index 7fc474b8..48af299d 100644 --- a/src/common/mac/HTTPMultipartUpload.m +++ b/src/common/mac/HTTPMultipartUpload.m @@ -30,15 +30,15 @@ #import "HTTPMultipartUpload.h" #import "GTMDefines.h" -#import "util.h" +#import "encoding_util.h" -@interface HTTPMultipartUpload(PrivateMethods) -- (NSString *)multipartBoundary; +@interface HTTPMultipartUpload (PrivateMethods) +- (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 *)formDataForFileContents:(NSData *)contents name:(NSString *)name; -- (NSData *)formDataForFile:(NSString *)file name:(NSString *)name; +- (NSData*)formDataForKey:(NSString*)key value:(NSString*)value; +- (NSData*)formDataForFileContents:(NSData*)contents name:(NSString*)name; +- (NSData*)formDataForFile:(NSString*)file name:(NSString*)name; @end @implementation HTTPMultipartUpload @@ -46,30 +46,29 @@ #pragma mark - #pragma mark || Private || //============================================================================= -- (NSString *)multipartBoundary { +- (NSString*)multipartBoundary { // The boundary has 27 '-' characters followed by 16 hex digits - return [NSString stringWithFormat:@"---------------------------%08X%08X", - rand(), rand()]; + return [NSString + stringWithFormat:@"---------------------------%08X%08X", rand(), rand()]; } //============================================================================= -- (NSData *)formDataForKey:(NSString *)key value:(NSString *)value { +- (NSData*)formDataForKey:(NSString*)key value:(NSString*)value { NSMutableData* data = [NSMutableData data]; [self appendBoundaryData:data]; - - NSString *escaped = PercentEncodeNSString(key); - NSString *fmt = - @"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n"; - NSString *form = [NSString stringWithFormat:fmt, boundary_, escaped, value]; + + NSString* escaped = PercentEncodeNSString(key); + NSString* fmt = @"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n"; + NSString* form = [NSString stringWithFormat:fmt, boundary_, escaped, value]; [data appendData:[form dataUsingEncoding:NSUTF8StringEncoding]]; return data; } //============================================================================= -- (void)appendBoundaryData: (NSMutableData*)data { - NSString *fmt = @"--%@\r\n"; - NSString *pre = [NSString stringWithFormat:fmt, boundary_]; +- (void)appendBoundaryData:(NSMutableData*)data { + NSString* fmt = @"--%@\r\n"; + NSString* pre = [NSString stringWithFormat:fmt, boundary_]; [data appendData:[pre dataUsingEncoding:NSUTF8StringEncoding]]; } @@ -78,7 +77,7 @@ #pragma mark - #pragma mark || Public || //============================================================================= -- (id)initWithURL:(NSURL *)url { +- (id)initWithURL:(NSURL*)url { if ((self = [super initWithURL:url])) { boundary_ = [[self multipartBoundary] retain]; files_ = [[NSMutableDictionary alloc] init]; @@ -97,7 +96,7 @@ } //============================================================================= -- (void)setParameters:(NSDictionary *)parameters { +- (void)setParameters:(NSDictionary*)parameters { if (parameters != parameters_) { [parameters_ release]; parameters_ = [parameters copy]; @@ -105,22 +104,22 @@ } //============================================================================= -- (NSDictionary *)parameters { +- (NSDictionary*)parameters { return parameters_; } //============================================================================= -- (void)addFileAtPath:(NSString *)path name:(NSString *)name { +- (void)addFileAtPath:(NSString*)path name:(NSString*)name { [files_ setObject:path forKey:name]; } //============================================================================= -- (void)addFileContents:(NSData *)data name:(NSString *)name { +- (void)addFileContents:(NSData*)data name:(NSString*)name { [files_ setObject:data forKey:name]; } //============================================================================= -- (NSDictionary *)files { +- (NSDictionary*)files { return files_; } @@ -131,17 +130,17 @@ //============================================================================= - (NSString*)contentType { - return [NSString stringWithFormat:@"multipart/form-data; boundary=%@", - boundary_]; + return [NSString + stringWithFormat:@"multipart/form-data; boundary=%@", boundary_]; } //============================================================================= - (NSData*)bodyData { - NSMutableData *postBody = [NSMutableData data]; + NSMutableData* postBody = [NSMutableData data]; // Add any parameters to the message - NSArray *parameterKeys = [parameters_ allKeys]; - NSString *key; + NSArray* parameterKeys = [parameters_ allKeys]; + NSString* key; NSInteger count = [parameterKeys count]; for (NSInteger i = 0; i < count; ++i) { @@ -151,8 +150,8 @@ } // Add any files to the message - NSArray *fileNames = [files_ allKeys]; - for (NSString *name in fileNames) { + NSArray* fileNames = [files_ allKeys]; + for (NSString* name in fileNames) { // First append boundary [self appendBoundaryData:postBody]; // Then the formdata @@ -162,7 +161,7 @@ withFileOrData:fileOrData]; } - NSString *epilogue = [NSString stringWithFormat:@"\r\n--%@--\r\n", boundary_]; + NSString* epilogue = [NSString stringWithFormat:@"\r\n--%@--\r\n", boundary_]; [postBody appendData:[epilogue dataUsingEncoding:NSUTF8StringEncoding]]; return postBody; diff --git a/src/common/mac/HTTPPutRequest.h b/src/common/mac/HTTPPutRequest.h new file mode 100644 index 00000000..431ea610 --- /dev/null +++ b/src/common/mac/HTTPPutRequest.h @@ -0,0 +1,51 @@ +// Copyright (c) 2020, 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. + +#import + +#import "HTTPRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Represents an HTTP PUT request. + */ +@interface HTTPPutRequest : HTTPRequest { + @protected + NSString* file_; +} + +/** + Sets the path of the file that will be sent in the PUT request. + */ +- (void)setFile:(NSString*)file; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/common/mac/HTTPPutRequest.m b/src/common/mac/HTTPPutRequest.m new file mode 100644 index 00000000..ec67376b --- /dev/null +++ b/src/common/mac/HTTPPutRequest.m @@ -0,0 +1,62 @@ +// Copyright (c) 2020, 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. + +#import "HTTPPutRequest.h" + +@implementation HTTPPutRequest + +//============================================================================= +- (void)dealloc { + [file_ release]; + + [super dealloc]; +} + +//============================================================================= +- (void)setFile:(NSString*)file { + file_ = [file copy]; +} + +//============================================================================= +- (NSString*)HTTPMethod { + return @"PUT"; +} + +//============================================================================= +- (NSData*)bodyData { + NSMutableData* postBody = [NSMutableData data]; + + [HTTPRequest appendFileToBodyData:postBody + withName:@"symbol_file" + withFileOrData:file_]; + + return postBody; +} + +@end diff --git a/src/common/mac/HTTPRequest.h b/src/common/mac/HTTPRequest.h new file mode 100644 index 00000000..b78fad6b --- /dev/null +++ b/src/common/mac/HTTPRequest.h @@ -0,0 +1,73 @@ +// Copyright (c) 2020, 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. + +#import + +NS_ASSUME_NONNULL_BEGIN +/** + Represents a single HTTP request. Sending the request is synchronous. + Once the send is complete, the response will be set. + + This is a base interface that specific HTTP requests derive from. + It is not intended to be instantiated directly. + */ +@interface HTTPRequest : NSObject { + @protected + NSURL* URL_; // The destination URL (STRONG) + NSHTTPURLResponse* response_; // The response from the send (STRONG) +} + +/** + Initializes the HTTPRequest and sets its URL. + */ +- (id)initWithURL:(NSURL*)URL; + +- (NSURL*)URL; + +- (NSHTTPURLResponse*)response; + +- (NSString*)HTTPMethod; // Internal, don't call outside class hierarchy. + +- (NSString*)contentType; // Internal, don't call outside class hierarchy. + +- (NSData*)bodyData; // Internal, don't call outside class hierarchy. + +- (NSData*)send:(NSError**)error; + +/** + Appends a file to the HTTP request, either by filename or by file content + (in the form of NSData). + */ ++ (void)appendFileToBodyData:(NSMutableData*)data + withName:(NSString*)name + withFileOrData:(id)fileOrData; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/common/mac/HTTPRequest.m b/src/common/mac/HTTPRequest.m new file mode 100644 index 00000000..ee7de3af --- /dev/null +++ b/src/common/mac/HTTPRequest.m @@ -0,0 +1,213 @@ +// Copyright (c) 2020, 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. + +#import "HTTPRequest.h" + +#include +#include + +#import "encoding_util.h" + +// As -[NSURLConnection sendSynchronousRequest:returningResponse:error:] has +// been deprecated with iOS 9.0 / OS X 10.11 SDKs, this function re-implements +// it using -[NSURLSession dataTaskWithRequest:completionHandler:] which is +// available on iOS 7+. +static NSData* SendSynchronousNSURLRequest(NSURLRequest* req, + NSURLResponse** outResponse, + NSError** outError) { +#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_7_0) && \ + __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0) || \ + (defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ + defined(MAC_OS_X_VERSION_10_11) && \ + MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11) + __block NSData* result = nil; + __block NSError* error = nil; + __block NSURLResponse* response = nil; + dispatch_semaphore_t waitSemaphone = dispatch_semaphore_create(0); + NSURLSessionConfiguration* config = + [NSURLSessionConfiguration defaultSessionConfiguration]; + [config setTimeoutIntervalForRequest:240.0]; + NSURLSession* session = [NSURLSession sessionWithConfiguration:config]; + [[session + dataTaskWithRequest:req + completionHandler:^(NSData* data, NSURLResponse* resp, NSError* err) { + if (outError) + error = [err retain]; + if (outResponse) + response = [resp retain]; + if (err == nil) + result = [data retain]; + dispatch_semaphore_signal(waitSemaphone); + }] resume]; + dispatch_semaphore_wait(waitSemaphone, DISPATCH_TIME_FOREVER); + dispatch_release(waitSemaphone); + if (outError) + *outError = [error autorelease]; + if (outResponse) + *outResponse = [response autorelease]; + return [result autorelease]; +#else + return [NSURLConnection sendSynchronousRequest:req + returningResponse:outResponse + error:outError]; +#endif +} + +@implementation HTTPRequest + +//============================================================================= +- (id)initWithURL:(NSURL*)URL { + if ((self = [super init])) { + URL_ = [URL copy]; + } + + return self; +} + +//============================================================================= +- (void)dealloc { + [URL_ release]; + [response_ release]; + + [super dealloc]; +} + +//============================================================================= +- (NSURL*)URL { + return URL_; +} + +//============================================================================= +- (NSHTTPURLResponse*)response { + return response_; +} + +//============================================================================= +- (NSString*)HTTPMethod { + @throw [NSException + exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"You must" + "override %@ in a subclass", + NSStringFromSelector(_cmd)] + userInfo:nil]; +} + +//============================================================================= +- (NSString*)contentType { + return nil; +} + +//============================================================================= +- (NSData*)bodyData { + return nil; +} + +//============================================================================= +- (NSData*)send:(NSError**)withError { + NSMutableURLRequest* req = [[NSMutableURLRequest alloc] + initWithURL:URL_ + cachePolicy:NSURLRequestUseProtocolCachePolicy + timeoutInterval:60.0]; + + NSString* contentType = [self contentType]; + if ([contentType length] > 0) { + [req setValue:contentType forHTTPHeaderField:@"Content-type"]; + } + + NSData* bodyData = [self bodyData]; + if ([bodyData length] > 0) { + [req setHTTPBody:bodyData]; + } + + [req setHTTPMethod:[self HTTPMethod]]; + + [response_ release]; + response_ = nil; + + NSData* data = nil; + if ([[req URL] isFileURL]) { + [[req HTTPBody] writeToURL:[req URL] options:0 error:withError]; + } else { + NSURLResponse* response = nil; + data = SendSynchronousNSURLRequest(req, &response, withError); + response_ = (NSHTTPURLResponse*)[response retain]; + } + [req release]; + + return data; +} + +//============================================================================= ++ (NSData*)formDataForFileContents:(NSData*)contents withName:(NSString*)name { + NSMutableData* data = [NSMutableData data]; + NSString* escaped = PercentEncodeNSString(name); + NSString* fmt = @"Content-Disposition: form-data; name=\"%@\"; " + "filename=\"minidump.dmp\"\r\nContent-Type: " + "application/octet-stream\r\n\r\n"; + NSString* pre = [NSString stringWithFormat:fmt, escaped]; + + [data appendData:[pre dataUsingEncoding:NSUTF8StringEncoding]]; + [data appendData:contents]; + + return data; +} + +//============================================================================= ++ (NSData*)formDataForFile:(NSString*)file withName:(NSString*)name { + NSData* contents = [NSData dataWithContentsOfFile:file]; + + return [HTTPRequest formDataForFileContents:contents withName:name]; +} + +//============================================================================= ++ (NSData*)formDataForKey:(NSString*)key value:(NSString*)value { + NSString* escaped = PercentEncodeNSString(key); + NSString* fmt = @"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n"; + NSString* form = [NSString stringWithFormat:fmt, escaped, value]; + + return [form dataUsingEncoding:NSUTF8StringEncoding]; +} + +//============================================================================= ++ (void)appendFileToBodyData:(NSMutableData*)data + withName:(NSString*)name + withFileOrData:(id)fileOrData { + NSData* fileData; + + // The object can be either the path to a file (NSString) or the contents + // of the file (NSData). + if ([fileOrData isKindOfClass:[NSData class]]) + fileData = [self formDataForFileContents:fileOrData withName:name]; + else + fileData = [HTTPRequest formDataForFile:fileOrData withName:name]; + + [data appendData:fileData]; +} + +@end diff --git a/src/common/mac/HTTPSimplePostRequest.h b/src/common/mac/HTTPSimplePostRequest.h new file mode 100644 index 00000000..bfabfead --- /dev/null +++ b/src/common/mac/HTTPSimplePostRequest.h @@ -0,0 +1,57 @@ +// Copyright (c) 2020, 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. + +#import + +#import "HTTPRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Represents a simple (non-multipart) HTTP POST request. + */ +@interface HTTPSimplePostRequest : HTTPRequest { + @protected + NSString* contentType_; + NSString* body_; +} + +/** + Sets the content type of the POST request. + */ +- (void)setContentType:(NSString*)contentType; + +/** + Sets the contents of the POST request's body. + */ +- (void)setBody:(NSString*)body; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/common/mac/HTTPSimplePostRequest.m b/src/common/mac/HTTPSimplePostRequest.m new file mode 100644 index 00000000..4cb3ef15 --- /dev/null +++ b/src/common/mac/HTTPSimplePostRequest.m @@ -0,0 +1,69 @@ +// Copyright (c) 2020, 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. + +#import "HTTPSimplePostRequest.h" + +@implementation HTTPSimplePostRequest + +//============================================================================= +- (void)dealloc { + [contentType_ release]; + [body_ release]; + + [super dealloc]; +} + +//============================================================================= +- (void)setContentType:(NSString*)contentType { + contentType_ = [contentType copy]; +} + +//============================================================================= +- (void)setBody:(NSString*)body { + body_ = [body copy]; +} + +//============================================================================= +- (NSString*)HTTPMethod { + return @"POST"; +} + +//============================================================================= +- (NSString*)contentType { + return contentType_; +} + +//============================================================================= +- (NSData*)bodyData { + NSMutableData* data = [NSMutableData data]; + [data appendData:[body_ dataUsingEncoding:NSUTF8StringEncoding]]; + return data; +} + +@end diff --git a/src/common/mac/SymbolCollectorClient.h b/src/common/mac/SymbolCollectorClient.h new file mode 100644 index 00000000..1f27f23f --- /dev/null +++ b/src/common/mac/SymbolCollectorClient.h @@ -0,0 +1,102 @@ +// Copyright (c) 2020, 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. + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + Represents a response from a sym-upload-v2 server to a createUploadURLOnServer + call. + */ +@interface UploadURLResponse : NSObject { + @protected + NSString* uploadURL_; + NSString* uploadKey_; +} + +- (id)initWithUploadURL:(NSString*)uploadURL withUploadKey:(NSString*)uploadKey; + +- (NSString*)uploadURL; +- (NSString*)uploadKey; +@end + +/** + Possible return statuses from a sym-upload-v2 server to a + completeUploadOnServer call. + */ +typedef NS_ENUM(NSInteger, CompleteUploadResult) { + CompleteUploadResultOk, + CompleteUploadResultDuplicateData, + CompleteUploadResultError +}; + +/** + Possible return statuses from a sym-upload-v2 server to a + checkSymbolStatusOnServer call. + */ +typedef NS_ENUM(NSInteger, SymbolStatus) { + SymbolStatusFound, + SymbolStatusMissing, + SymbolStatusUnknown +}; + +/** + Interface to help a client interact with a sym-upload-v2 server, over HTTP. + For details of the API and protocol, see :/docs/sym_upload_v2_protocol.md. + */ +@interface SymbolCollectorClient : NSObject +; + +/** + Calls the /v1/symbols/{debug_file}/{debug_id}:checkStatus API on the server. + */ ++ (SymbolStatus)checkSymbolStatusOnServer:(NSString*)APIURL + withAPIKey:(NSString*)APIKey + withDebugFile:(NSString*)debugFile + withDebugID:(NSString*)debugID; + +/** + Calls the /v1/uploads:create API on the server. + */ ++ (UploadURLResponse*)createUploadURLOnServer:(NSString*)APIURL + withAPIKey:(NSString*)APIKey; + +/** + Calls the /v1/uploads/{key}:complete API on the server. + */ ++ (CompleteUploadResult)completeUploadOnServer:(NSString*)APIURL + withAPIKey:(NSString*)APIKey + withUploadKey:(NSString*)uploadKey + withDebugFile:(NSString*)debugFile + withDebugID:(NSString*)debugID; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/common/mac/SymbolCollectorClient.m b/src/common/mac/SymbolCollectorClient.m new file mode 100644 index 00000000..b997607f --- /dev/null +++ b/src/common/mac/SymbolCollectorClient.m @@ -0,0 +1,235 @@ +// Copyright (c) 2020, 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. + +#import "SymbolCollectorClient.h" + +#import "HTTPGetRequest.h" +#import "HTTPSimplePostRequest.h" + +@implementation UploadURLResponse + +//============================================================================= +- (id)initWithUploadURL:(NSString*)uploadURL + withUploadKey:(NSString*)uploadKey { + if (self = [super init]) { + uploadURL_ = [uploadURL copy]; + uploadKey_ = [uploadKey copy]; + } + return self; +} + +//============================================================================= +- (void)dealloc { + [uploadURL_ release]; + [uploadKey_ release]; + + [super dealloc]; +} + +//============================================================================= +- (NSString*)uploadURL { + return uploadURL_; +} + +//============================================================================= +- (NSString*)uploadKey { + return uploadKey_; +} +@end + +@implementation SymbolCollectorClient + +//============================================================================= ++ (SymbolStatus)checkSymbolStatusOnServer:(NSString*)APIURL + withAPIKey:(NSString*)APIKey + withDebugFile:(NSString*)debugFile + withDebugID:(NSString*)debugID { + NSURL* URL = [NSURL + URLWithString:[NSString + stringWithFormat:@"%@/v1/symbols/%@/%@:checkStatus" + @"?key=%@", + APIURL, debugFile, debugID, APIKey]]; + + HTTPGetRequest* getRequest = [[HTTPGetRequest alloc] initWithURL:URL]; + NSError* error = nil; + NSData* data = [getRequest send:&error]; + NSString* result = [[NSString alloc] initWithData:data + encoding:NSUTF8StringEncoding]; + int responseCode = [[getRequest response] statusCode]; + [getRequest release]; + + if (error || responseCode != 200) { + fprintf(stdout, "Failed to check symbol status.\n"); + fprintf(stdout, "Response code: %d\n", responseCode); + fprintf(stdout, "Response:\n"); + fprintf(stdout, "%s\n", [result UTF8String]); + return SymbolStatusUnknown; + } + + error = nil; + NSRegularExpression* statusRegex = [NSRegularExpression + regularExpressionWithPattern:@"\"status\": \"([^\"]+)\"" + options:0 + error:&error]; + NSArray* matches = + [statusRegex matchesInString:result + options:0 + range:NSMakeRange(0, [result length])]; + if ([matches count] != 1) { + fprintf(stdout, "Failed to parse check symbol status response."); + fprintf(stdout, "Response:\n"); + fprintf(stdout, "%s\n", [result UTF8String]); + return SymbolStatusUnknown; + } + + NSString* status = [result substringWithRange:[matches[0] rangeAtIndex:1]]; + [result release]; + + return [status isEqualToString:@"FOUND"] ? SymbolStatusFound + : SymbolStatusMissing; +} + +//============================================================================= ++ (UploadURLResponse*)createUploadURLOnServer:(NSString*)APIURL + withAPIKey:(NSString*)APIKey { + NSURL* URL = [NSURL + URLWithString:[NSString stringWithFormat:@"%@/v1/uploads:create?key=%@", + APIURL, APIKey]]; + + HTTPSimplePostRequest* postRequest = + [[HTTPSimplePostRequest alloc] initWithURL:URL]; + NSError* error = nil; + NSData* data = [postRequest send:&error]; + NSString* result = [[NSString alloc] initWithData:data + encoding:NSUTF8StringEncoding]; + int responseCode = [[postRequest response] statusCode]; + [postRequest release]; + + if (error || responseCode != 200) { + fprintf(stdout, "Failed to create upload URL.\n"); + fprintf(stdout, "Response code: %d\n", responseCode); + fprintf(stdout, "Response:\n"); + fprintf(stdout, "%s\n", [result UTF8String]); + return nil; + } + + // Note camel-case rather than underscores. + NSRegularExpression* uploadURLRegex = [NSRegularExpression + regularExpressionWithPattern:@"\"uploadUrl\": \"([^\"]+)\"" + options:0 + error:&error]; + NSRegularExpression* uploadKeyRegex = [NSRegularExpression + regularExpressionWithPattern:@"\"uploadKey\": \"([^\"]+)\"" + options:0 + error:&error]; + + NSArray* uploadURLMatches = + [uploadURLRegex matchesInString:result + options:0 + range:NSMakeRange(0, [result length])]; + NSArray* uploadKeyMatches = + [uploadKeyRegex matchesInString:result + options:0 + range:NSMakeRange(0, [result length])]; + if ([uploadURLMatches count] != 1 || [uploadKeyMatches count] != 1) { + fprintf(stdout, "Failed to parse create url response."); + fprintf(stdout, "Response:\n"); + fprintf(stdout, "%s\n", [result UTF8String]); + return nil; + } + NSString* uploadURL = + [result substringWithRange:[uploadURLMatches[0] rangeAtIndex:1]]; + NSString* uploadKey = + [result substringWithRange:[uploadKeyMatches[0] rangeAtIndex:1]]; + + return [[UploadURLResponse alloc] initWithUploadURL:uploadURL + withUploadKey:uploadKey]; +} + +//============================================================================= ++ (CompleteUploadResult)completeUploadOnServer:(NSString*)APIURL + withAPIKey:(NSString*)APIKey + withUploadKey:(NSString*)uploadKey + withDebugFile:(NSString*)debugFile + withDebugID:(NSString*)debugID { + NSURL* URL = [NSURL + URLWithString:[NSString + stringWithFormat:@"%@/v1/uploads/%@:complete?key=%@", + APIURL, uploadKey, APIKey]]; + NSString* body = + [NSString stringWithFormat: + @"{ symbol_id: { debug_file: \"%@\", debug_id: \"%@\" } }", + debugFile, debugID]; + + HTTPSimplePostRequest* postRequest = + [[HTTPSimplePostRequest alloc] initWithURL:URL]; + [postRequest setBody:body]; + [postRequest setContentType:@"application/json"]; + + NSError* error = nil; + NSData* data = [postRequest send:&error]; + NSString* result = [[NSString alloc] initWithData:data + encoding:NSUTF8StringEncoding]; + int responseCode = [[postRequest response] statusCode]; + [postRequest release]; + + if (error || responseCode != 200) { + fprintf(stdout, "Failed to complete upload URL.\n"); + fprintf(stdout, "Response code: %d\n", responseCode); + fprintf(stdout, "Response:\n"); + fprintf(stdout, "%s\n", [result UTF8String]); + return CompleteUploadResultError; + } + + // Note camel-case rather than underscores. + NSRegularExpression* completeResultRegex = [NSRegularExpression + regularExpressionWithPattern:@"\"result\": \"([^\"]+)\"" + options:0 + error:&error]; + + NSArray* completeResultMatches = + [completeResultRegex matchesInString:result + options:0 + range:NSMakeRange(0, [result length])]; + + if ([completeResultMatches count] != 1) { + fprintf(stdout, "Failed to parse complete upload response."); + fprintf(stdout, "Response:\n"); + fprintf(stdout, "%s\n", [result UTF8String]); + return CompleteUploadResultError; + } + NSString* completeResult = + [result substringWithRange:[completeResultMatches[0] rangeAtIndex:1]]; + [result release]; + + return ([completeResult isEqualToString:@"DUPLICATE_DATA"]) + ? CompleteUploadResultDuplicateData + : CompleteUploadResultOk; +} +@end diff --git a/src/common/mac/encoding_util.h b/src/common/mac/encoding_util.h new file mode 100644 index 00000000..6495a742 --- /dev/null +++ b/src/common/mac/encoding_util.h @@ -0,0 +1,41 @@ +// Copyright (c) 2020, 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 GOOGLE_BREAKPAD_COMMON_MAC_ENCODING_UTIL_H +#define GOOGLE_BREAKPAD_COMMON_MAC_ENCODING_UTIL_H + +#import + +// As -[NSString stringByAddingPercentEscapesUsingEncoding:] has been +// deprecated with iOS 9.0 / OS X 10.11 SDKs, this function re-implements it +// using -[NSString stringByAddingPercentEncodingWithAllowedCharacters:] when +// using those SDKs. +NSString* PercentEncodeNSString(NSString* key); + +#endif // GOOGLE_BREAKPAD_COMMON_MAC_ENCODING_UTIL_H diff --git a/src/common/mac/encoding_util.m b/src/common/mac/encoding_util.m new file mode 100644 index 00000000..86d70fb6 --- /dev/null +++ b/src/common/mac/encoding_util.m @@ -0,0 +1,47 @@ +// Copyright (c) 2020, 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. + +#include "encoding_util.h" + +#include +#include +#import + +NSString* PercentEncodeNSString(NSString* key) { +#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_9_0) && \ + __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0) || \ + (defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ + defined(MAC_OS_X_VERSION_10_11) && \ + MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11) + return [key stringByAddingPercentEncodingWithAllowedCharacters: + [NSCharacterSet URLQueryAllowedCharacterSet]]; +#else + return [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; +#endif +} diff --git a/src/common/mac/minidump_upload.m b/src/common/mac/minidump_upload.m new file mode 100644 index 00000000..1fe4f213 --- /dev/null +++ b/src/common/mac/minidump_upload.m @@ -0,0 +1,135 @@ +// Copyright (c) 2006, 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. + +// minidump_upload.m: Upload a minidump to a HTTP server. The upload is sent as +// a multipart/form-data POST request with the following parameters: +// prod: the product name +// ver: the product version +// symbol_file: the breakpad format symbol file + +#import + +#import + +#import "common/mac/HTTPMultipartUpload.h" + +typedef struct { + NSString* minidumpPath; + NSString* uploadURLStr; + NSString* product; + NSString* version; + BOOL success; +} Options; + +//============================================================================= +static void Start(Options* options) { + NSURL* url = [NSURL URLWithString:options->uploadURLStr]; + HTTPMultipartUpload* ul = [[HTTPMultipartUpload alloc] initWithURL:url]; + NSMutableDictionary* parameters = [NSMutableDictionary dictionary]; + + // Add parameters + [parameters setObject:options->product forKey:@"prod"]; + [parameters setObject:options->version forKey:@"ver"]; + [ul setParameters:parameters]; + + // Add file + [ul addFileAtPath:options->minidumpPath name:@"upload_file_minidump"]; + + // Send it + NSError* error = nil; + NSData* data = [ul send:&error]; + NSString* result = [[NSString alloc] initWithData:data + encoding:NSUTF8StringEncoding]; + + NSLog(@"Send: %@", error ? [error description] : @"No Error"); + NSLog(@"Response: %ld", (long)[[ul response] statusCode]); + NSLog(@"Result: %lu bytes\n%@", (unsigned long)[data length], result); + + [result release]; + [ul release]; + options->success = !error; +} + +//============================================================================= +static void Usage(int argc, const char* argv[]) { + fprintf(stderr, "Submit minidump information.\n"); + fprintf(stderr, + "Usage: %s -p -v " + "\n", + argv[0]); + fprintf(stderr, " should be a minidump.\n"); + fprintf(stderr, " is the destination for the upload\n"); + + fprintf(stderr, "\t-h: Usage\n"); + fprintf(stderr, "\t-?: Usage\n"); +} + +//============================================================================= +static void SetupOptions(int argc, const char* argv[], Options* options) { + extern int optind; + char ch; + + while ((ch = getopt(argc, (char* const*)argv, "p:v:h?")) != -1) { + switch (ch) { + case 'p': + options->product = [NSString stringWithUTF8String:optarg]; + break; + case 'v': + options->version = [NSString stringWithUTF8String:optarg]; + break; + + default: + Usage(argc, argv); + exit(0); + break; + } + } + + if ((argc - optind) != 2) { + fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]); + Usage(argc, argv); + exit(1); + } + + options->minidumpPath = [NSString stringWithUTF8String:argv[optind]]; + options->uploadURLStr = [NSString stringWithUTF8String:argv[optind + 1]]; +} + +//============================================================================= +int main(int argc, const char* argv[]) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + Options options; + + bzero(&options, sizeof(Options)); + SetupOptions(argc, argv, &options); + Start(&options); + + [pool release]; + return options.success ? 0 : 1; +} diff --git a/src/tools/mac/symupload/HTTPGetRequest.h b/src/tools/mac/symupload/HTTPGetRequest.h deleted file mode 100644 index 0da08474..00000000 --- a/src/tools/mac/symupload/HTTPGetRequest.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2019, 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. - -#import - -#import "HTTPRequest.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - Represents a HTTP GET request - */ -@interface HTTPGetRequest : HTTPRequest -@end - -NS_ASSUME_NONNULL_END diff --git a/src/tools/mac/symupload/HTTPGetRequest.m b/src/tools/mac/symupload/HTTPGetRequest.m deleted file mode 100644 index a3a252ab..00000000 --- a/src/tools/mac/symupload/HTTPGetRequest.m +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2019, 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. - -#import "HTTPGetRequest.h" - -@implementation HTTPGetRequest - -//============================================================================= -- (NSString*)HTTPMethod { - return @"GET"; -} - -@end diff --git a/src/tools/mac/symupload/HTTPPutRequest.h b/src/tools/mac/symupload/HTTPPutRequest.h deleted file mode 100644 index f316212b..00000000 --- a/src/tools/mac/symupload/HTTPPutRequest.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2019, 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. - -#import - -#import "HTTPRequest.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - Represents an HTTP PUT request. - */ -@interface HTTPPutRequest : HTTPRequest { -@protected - NSString* file_; -} - -/** - Sets the path of the file that will be sent in the PUT request. - */ -- (void)setFile:(NSString*)file; - -@end - -NS_ASSUME_NONNULL_END diff --git a/src/tools/mac/symupload/HTTPPutRequest.m b/src/tools/mac/symupload/HTTPPutRequest.m deleted file mode 100644 index b64caae5..00000000 --- a/src/tools/mac/symupload/HTTPPutRequest.m +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2019, 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. - -#import "HTTPPutRequest.h" - -@implementation HTTPPutRequest - -//============================================================================= -- (void)dealloc { - [file_ release]; - - [super dealloc]; -} - -//============================================================================= -- (void)setFile:(NSString *)file { - file_ = [file copy]; -} - -//============================================================================= -- (NSString*)HTTPMethod { - return @"PUT"; -} - -//============================================================================= -- (NSData*)bodyData { - NSMutableData *postBody = [NSMutableData data]; - - [HTTPRequest appendFileToBodyData:postBody - withName:@"symbol_file" - withFileOrData:file_]; - - return postBody; -} - -@end diff --git a/src/tools/mac/symupload/HTTPRequest.h b/src/tools/mac/symupload/HTTPRequest.h deleted file mode 100644 index ef2f86bc..00000000 --- a/src/tools/mac/symupload/HTTPRequest.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2019, 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. - -#import - -NS_ASSUME_NONNULL_BEGIN -/** - Represents a single HTTP request. Sending the request is synchronous. - Once the send is complete, the response will be set. - - This is a base interface that specific HTTP requests derive from. - It is not intended to be instantiated directly. - */ -@interface HTTPRequest : NSObject { - @protected - NSURL *URL_; // The destination URL (STRONG) - NSHTTPURLResponse *response_; // The response from the send (STRONG) -} - -/** - Initializes the HTTPRequest and sets its URL. - */ -- (id)initWithURL:(NSURL *)URL; - -- (NSURL *)URL; - -- (NSHTTPURLResponse*) response; - -- (NSString*)HTTPMethod; // Internal, don't call outside class hierarchy. - -- (NSString*)contentType; // Internal, don't call outside class hierarchy. - -- (NSData*)bodyData; // Internal, don't call outside class hierarchy. - -- (NSData *)send:(NSError **)error; - -/** - Appends a file to the HTTP request, either by filename or by file content - (in the form of NSData). - */ -+ (void)appendFileToBodyData:(NSMutableData *)data - withName:(NSString*)name - withFileOrData:(id)fileOrData; - -@end - -NS_ASSUME_NONNULL_END diff --git a/src/tools/mac/symupload/HTTPRequest.m b/src/tools/mac/symupload/HTTPRequest.m deleted file mode 100644 index 9cafe13e..00000000 --- a/src/tools/mac/symupload/HTTPRequest.m +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright (c) 2019, 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. - -#import "HTTPRequest.h" - -#import "util.h" - -// As -[NSURLConnection sendSynchronousRequest:returningResponse:error:] has -// been deprecated with iOS 9.0 / OS X 10.11 SDKs, this function re-implements -// it using -[NSURLSession dataTaskWithRequest:completionHandler:] which is -// available on iOS 7+. -static NSData *SendSynchronousNSURLRequest(NSURLRequest *req, - NSURLResponse **outResponse, - NSError **outError) { -#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_7_0) && \ -__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0) || \ -(defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ -defined(MAC_OS_X_VERSION_10_11) && \ -MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11) - __block NSData* result = nil; - __block NSError* error = nil; - __block NSURLResponse* response = nil; - dispatch_semaphore_t waitSemaphone = dispatch_semaphore_create(0); - NSURLSessionConfiguration* config = [NSURLSessionConfiguration - defaultSessionConfiguration]; - [config setTimeoutIntervalForRequest:240.0]; - NSURLSession* session = [NSURLSession sessionWithConfiguration:config]; - [[session - dataTaskWithRequest:req - completionHandler:^(NSData *data, - NSURLResponse *resp, - NSError *err) { - if (outError) - error = [err retain]; - if (outResponse) - response = [resp retain]; - if (err == nil) - result = [data retain]; - dispatch_semaphore_signal(waitSemaphone); - }] resume]; - dispatch_semaphore_wait(waitSemaphone, DISPATCH_TIME_FOREVER); - dispatch_release(waitSemaphone); - if (outError) - *outError = [error autorelease]; - if (outResponse) - *outResponse = [response autorelease]; - return [result autorelease]; -#else - return [NSURLConnection sendSynchronousRequest:req - returningResponse:outResponse - error:outError]; -#endif -} - -@implementation HTTPRequest - -//============================================================================= -- (id)initWithURL:(NSURL *)URL { - if ((self = [super init])) { - URL_ = [URL copy]; - } - - return self; -} - -//============================================================================= -- (void)dealloc { - [URL_ release]; - [response_ release]; - - [super dealloc]; -} - -//============================================================================= -- (NSURL *)URL { - return URL_; -} - -//============================================================================= -- (NSHTTPURLResponse *)response { - return response_; -} - -//============================================================================= -- (NSString*)HTTPMethod { - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:[NSString stringWithFormat:@"You must" - "override %@ in a subclass", - NSStringFromSelector(_cmd)] - userInfo:nil]; -} - -//============================================================================= -- (NSString*)contentType { - return nil; -} - -//============================================================================= -- (NSData*)bodyData { - return nil; -} - -//============================================================================= -- (NSData *)send:(NSError **)withError { - NSMutableURLRequest *req = - [[NSMutableURLRequest alloc] - initWithURL:URL_ - cachePolicy:NSURLRequestUseProtocolCachePolicy - timeoutInterval:60.0]; - - NSString* contentType = [self contentType]; - if ([contentType length] > 0) { - [req setValue:contentType forHTTPHeaderField:@"Content-type"]; - } - - NSData* bodyData = [self bodyData]; - if ([bodyData length] > 0) { - [req setHTTPBody:bodyData]; - } - - [req setHTTPMethod:[self HTTPMethod]]; - - [response_ release]; - response_ = nil; - - NSData *data = nil; - if ([[req URL] isFileURL]) { - [[req HTTPBody] writeToURL:[req URL] options:0 error:withError]; - } else { - NSURLResponse *response = nil; - data = SendSynchronousNSURLRequest(req, &response, withError); - response_ = (NSHTTPURLResponse *)[response retain]; - } - [req release]; - - return data; -} - -//============================================================================= -+ (NSData *)formDataForFileContents:(NSData *)contents - withName:(NSString *)name { - NSMutableData *data = [NSMutableData data]; - NSString *escaped = PercentEncodeNSString(name); - NSString *fmt = @"Content-Disposition: form-data; name=\"%@\"; " - "filename=\"minidump.dmp\"\r\nContent-Type: " - "application/octet-stream\r\n\r\n"; - NSString *pre = [NSString stringWithFormat:fmt, escaped]; - - [data appendData:[pre dataUsingEncoding:NSUTF8StringEncoding]]; - [data appendData:contents]; - - return data; -} - -//============================================================================= -+ (NSData *)formDataForFile:(NSString *)file withName:(NSString *)name { - NSData *contents = [NSData dataWithContentsOfFile:file]; - - return [HTTPRequest formDataForFileContents:contents withName:name]; -} - -//============================================================================= -+ (NSData *)formDataForKey:(NSString *)key value:(NSString *)value { - NSString *escaped = PercentEncodeNSString(key); - NSString *fmt = - @"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n"; - NSString *form = [NSString stringWithFormat:fmt, escaped, value]; - - return [form dataUsingEncoding:NSUTF8StringEncoding]; -} - -//============================================================================= -+ (void)appendFileToBodyData:(NSMutableData *)data - withName:(NSString*)name - withFileOrData:(id)fileOrData { - NSData *fileData; - - // The object can be either the path to a file (NSString) or the contents - // of the file (NSData). - if ([fileOrData isKindOfClass:[NSData class]]) - fileData = [self formDataForFileContents:fileOrData withName:name]; - else - fileData = [HTTPRequest formDataForFile:fileOrData withName:name]; - - [data appendData:fileData]; -} - -@end diff --git a/src/tools/mac/symupload/HTTPSimplePostRequest.h b/src/tools/mac/symupload/HTTPSimplePostRequest.h deleted file mode 100644 index 4b542b45..00000000 --- a/src/tools/mac/symupload/HTTPSimplePostRequest.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2019, 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. - -#import - -#import "HTTPRequest.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - Represents a simple (non-multipart) HTTP POST request. - */ -@interface HTTPSimplePostRequest : HTTPRequest { -@protected - NSString* contentType_; - NSString* body_; -} - -/** - Sets the content type of the POST request. - */ -- (void)setContentType:(NSString*)contentType; - -/** - Sets the contents of the POST request's body. - */ -- (void)setBody:(NSString*)body; - -@end - -NS_ASSUME_NONNULL_END diff --git a/src/tools/mac/symupload/HTTPSimplePostRequest.m b/src/tools/mac/symupload/HTTPSimplePostRequest.m deleted file mode 100644 index ef5ef334..00000000 --- a/src/tools/mac/symupload/HTTPSimplePostRequest.m +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2019, 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. - -#import "HTTPSimplePostRequest.h" - -@implementation HTTPSimplePostRequest - -//============================================================================= -- (void)dealloc { - [contentType_ release]; - [body_ release]; - - [super dealloc]; -} - -//============================================================================= -- (void)setContentType:(NSString *)contentType { - contentType_ = [contentType copy]; -} - -//============================================================================= -- (void)setBody:(NSString *)body { - body_ = [body copy]; -} - -//============================================================================= -- (NSString*)HTTPMethod { - return @"POST"; -} - -//============================================================================= -- (NSString*)contentType { - return contentType_; -} - -//============================================================================= -- (NSData*)bodyData { - NSMutableData* data = [NSMutableData data]; - [data appendData:[body_ dataUsingEncoding:NSUTF8StringEncoding]]; - return data; -} - -@end diff --git a/src/tools/mac/symupload/SymbolCollectorClient.h b/src/tools/mac/symupload/SymbolCollectorClient.h deleted file mode 100644 index ef2029e4..00000000 --- a/src/tools/mac/symupload/SymbolCollectorClient.h +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2019, 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. - -#import - -NS_ASSUME_NONNULL_BEGIN - -/** - Represents a response from a sym-upload-v2 server to a CreateUploadURL call. - */ -@interface UploadURLResponse : NSObject { -@protected - NSString* uploadURL_; - NSString* uploadKey_; -} - -- (id)initWithUploadURL:(NSString*)uploadURL - withUploadKey:(NSString*)uploadKey; - -- (NSString*)uploadURL; -- (NSString*)uploadKey; -@end - -/** - Possible return statuses from a sym-upload-v2 server to a CompleteUpload call. - */ -typedef NS_ENUM(NSInteger, CompleteUploadResult) { - CompleteUploadResultOk, - CompleteUploadResultDuplicateData, - CompleteUploadResultError -}; - -/** - Possible return statuses from a sym-upload-v2 server to a CheckSymbolStatus - call. - */ -typedef NS_ENUM(NSInteger, SymbolStatus) { - SymbolStatusFound, - SymbolStatusMissing, - SymbolStatusUnknown -}; - -/** - Interface to help a client interact with a sym-upload-v2 server, over HTTP. - For details of the API and protocol, see :/docs/sym_upload_v2_protocol.md. - */ -@interface SymbolCollectorClient : NSObject; - -/** - Call the CheckSymbolstatus API on the server. - */ -+ (SymbolStatus)CheckSymbolStatus:(NSString*)APIURL - withAPIKey:(NSString*)APIKey - withDebugFile:(NSString*)debugFile - withDebugID:(NSString*)debugID; - -/** - Call the CreateUploadURL API on the server. - */ -+ (UploadURLResponse*)CreateUploadURL:(NSString*)APIURL - withAPIKey:(NSString*)APIKey; - -/** - Call the CompleteUpload API on the server. - */ -+ (CompleteUploadResult)CompleteUpload:(NSString*)APIURL - withAPIKey:(NSString*)APIKey - withUploadKey:(NSString*)uploadKey - withDebugFile:(NSString*)debugFile - withDebugID:(NSString*)debugID; - -@end - -NS_ASSUME_NONNULL_END diff --git a/src/tools/mac/symupload/SymbolCollectorClient.m b/src/tools/mac/symupload/SymbolCollectorClient.m deleted file mode 100644 index 38103ccb..00000000 --- a/src/tools/mac/symupload/SymbolCollectorClient.m +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright (c) 2019, 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. - -#import "SymbolCollectorClient.h" - -#import "HTTPGetRequest.h" -#import "HTTPSimplePostRequest.h" - -@implementation UploadURLResponse - -//============================================================================= -- (id)initWithUploadURL:(NSString *)uploadURL - withUploadKey:(NSString *)uploadKey { - if (self = [super init]) { - uploadURL_ = [uploadURL copy]; - uploadKey_ = [uploadKey copy]; - } - return self; -} - -//============================================================================= -- (void)dealloc { - [uploadURL_ release]; - [uploadKey_ release]; - - [super dealloc]; -} - -//============================================================================= -- (NSString*)uploadURL { - return uploadURL_; -} - -//============================================================================= -- (NSString*)uploadKey { - return uploadKey_; -} -@end - -@implementation SymbolCollectorClient - -//============================================================================= -+ (SymbolStatus)CheckSymbolStatus:(NSString *)APIURL - withAPIKey:(NSString *)APIKey - withDebugFile:(NSString *)debugFile - withDebugID:(NSString *)debugID { - NSURL* URL = [NSURL URLWithString:[NSString stringWithFormat: - @"%@/v1/symbols/%@/%@:checkStatus" - @"?key=%@", - APIURL, - debugFile, - debugID, - APIKey]]; - - HTTPGetRequest* getRequest = [[HTTPGetRequest alloc] initWithURL:URL]; - NSError *error = nil; - NSData *data = [getRequest send:&error]; - NSString *result = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - int responseCode = [[getRequest response] statusCode]; - [getRequest release]; - - if (error || responseCode != 200) { - fprintf(stdout, "Failed to check symbol status.\n"); - fprintf(stdout, "Response code: %d\n", responseCode); - fprintf(stdout, "Response:\n"); - fprintf(stdout, "%s\n", [result UTF8String]); - return SymbolStatusUnknown; - } - - error = nil; - NSRegularExpression* statusRegex = [NSRegularExpression - regularExpressionWithPattern: - @"\"status\": \"([^\"]+)\"" - options:0 - error:&error]; - NSArray* matches = [statusRegex - matchesInString:result - options:0 - range: NSMakeRange(0, [result length])]; - if ([matches count] != 1) { - fprintf(stdout, "Failed to parse check symbol status response."); - fprintf(stdout, "Response:\n"); - fprintf(stdout, "%s\n", [result UTF8String]); - return SymbolStatusUnknown; - } - - NSString* status = [result substringWithRange:[matches[0] rangeAtIndex:1]]; - [result release]; - - return [status isEqualToString:@"FOUND"] ? - SymbolStatusFound : - SymbolStatusMissing; -} - -//============================================================================= -+ (UploadURLResponse *)CreateUploadURL:(NSString *)APIURL - withAPIKey:(NSString *)APIKey { - NSURL* URL = [NSURL URLWithString:[NSString stringWithFormat: - @"%@/v1/uploads:create?key=%@", - APIURL, - APIKey]]; - - HTTPSimplePostRequest* postRequest = [[HTTPSimplePostRequest alloc] - initWithURL:URL]; - NSError *error = nil; - NSData* data = [postRequest send:&error]; - NSString *result = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - int responseCode = [[postRequest response] statusCode]; - [postRequest release]; - - if (error || responseCode != 200) { - fprintf(stdout, "Failed to create upload URL.\n"); - fprintf(stdout, "Response code: %d\n", responseCode); - fprintf(stdout, "Response:\n"); - fprintf(stdout, "%s\n", [result UTF8String]); - return nil; - } - - // Note camel-case rather than underscores. - NSRegularExpression* uploadURLRegex = [NSRegularExpression - regularExpressionWithPattern: - @"\"uploadUrl\": \"([^\"]+)\"" - options:0 - error:&error]; - NSRegularExpression* uploadKeyRegex = [NSRegularExpression - regularExpressionWithPattern: - @"\"uploadKey\": \"([^\"]+)\"" - options:0 - error:&error]; - - NSArray* uploadURLMatches = [uploadURLRegex - matchesInString:result - options:0 - range: NSMakeRange(0, [result length])]; - NSArray* uploadKeyMatches = [uploadKeyRegex - matchesInString:result - options:0 - range: NSMakeRange(0, [result length])]; - if ([uploadURLMatches count] != 1 || [uploadKeyMatches count] != 1) { - fprintf(stdout, "Failed to parse create url response."); - fprintf(stdout, "Response:\n"); - fprintf(stdout, "%s\n", [result UTF8String]); - return nil; - } - NSString* uploadURL = [result - substringWithRange:[uploadURLMatches[0] - rangeAtIndex:1]]; - NSString* uploadKey = [result - substringWithRange:[uploadKeyMatches[0] - rangeAtIndex:1]]; - - return [[UploadURLResponse alloc] initWithUploadURL:uploadURL - withUploadKey:uploadKey]; -} - -//============================================================================= -+ (CompleteUploadResult)CompleteUpload:(NSString *)APIURL - withAPIKey:(NSString *)APIKey - withUploadKey:(NSString *)uploadKey - withDebugFile:(NSString *)debugFile - withDebugID:(NSString *)debugID { - NSURL* URL = [NSURL URLWithString:[NSString stringWithFormat: - @"%@/v1/uploads/%@:complete?key=%@", - APIURL, - uploadKey, - APIKey]]; - NSString* body = [NSString stringWithFormat: - @"{ symbol_id: { debug_file: \"%@\", debug_id: \"%@\" } }", - debugFile, - debugID]; - - HTTPSimplePostRequest* postRequest = [[HTTPSimplePostRequest alloc] - initWithURL:URL]; - [postRequest setBody:body]; - [postRequest setContentType:@"application/json"]; - - NSError *error = nil; - NSData* data = [postRequest send:&error]; - NSString *result = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - int responseCode = [[postRequest response] statusCode]; - [postRequest release]; - - if (error || responseCode != 200) { - fprintf(stdout, "Failed to complete upload URL.\n"); - fprintf(stdout, "Response code: %d\n", responseCode); - fprintf(stdout, "Response:\n"); - fprintf(stdout, "%s\n", [result UTF8String]); - return CompleteUploadResultError; - } - - // Note camel-case rather than underscores. - NSRegularExpression* completeResultRegex = [NSRegularExpression - regularExpressionWithPattern: - @"\"result\": \"([^\"]+)\"" - options:0 - error:&error]; - - NSArray* completeResultMatches = [completeResultRegex - matchesInString:result - options:0 - range: NSMakeRange(0, [result length])]; - - if ([completeResultMatches count] != 1) { - fprintf(stdout, "Failed to parse complete upload response."); - fprintf(stdout, "Response:\n"); - fprintf(stdout, "%s\n", [result UTF8String]); - return nil; - } - NSString* completeResult = [result - substringWithRange:[completeResultMatches[0] - rangeAtIndex:1]]; - [result release]; - - return ([completeResult isEqualToString:@"DUPLICATE_DATA"]) ? - CompleteUploadResultDuplicateData : - CompleteUploadResultOk; -} -@end diff --git a/src/tools/mac/symupload/minidump_upload.m b/src/tools/mac/symupload/minidump_upload.m deleted file mode 100644 index 741ad765..00000000 --- a/src/tools/mac/symupload/minidump_upload.m +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) 2006, 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. - -// minidump_upload.m: Upload a minidump to a HTTP server. The upload is sent as -// a multipart/form-data POST request with the following parameters: -// prod: the product name -// ver: the product version -// symbol_file: the breakpad format symbol file - -#import - -#import - -#import "common/mac/HTTPMultipartUpload.h" - -typedef struct { - NSString *minidumpPath; - NSString *uploadURLStr; - NSString *product; - NSString *version; - BOOL success; -} Options; - -//============================================================================= -static void Start(Options *options) { - NSURL *url = [NSURL URLWithString:options->uploadURLStr]; - HTTPMultipartUpload *ul = [[HTTPMultipartUpload alloc] initWithURL:url]; - NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; - - // Add parameters - [parameters setObject:options->product forKey:@"prod"]; - [parameters setObject:options->version forKey:@"ver"]; - [ul setParameters:parameters]; - - // Add file - [ul addFileAtPath:options->minidumpPath name:@"upload_file_minidump"]; - - // Send it - NSError *error = nil; - NSData *data = [ul send:&error]; - NSString *result = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - - NSLog(@"Send: %@", error ? [error description] : @"No Error"); - NSLog(@"Response: %ld", (long)[[ul response] statusCode]); - NSLog(@"Result: %lu bytes\n%@", (unsigned long)[data length], result); - - [result release]; - [ul release]; - options->success = !error; -} - -//============================================================================= -static void -Usage(int argc, const char *argv[]) { - fprintf(stderr, "Submit minidump information.\n"); - fprintf(stderr, "Usage: %s -p -v " - "\n", argv[0]); - fprintf(stderr, " should be a minidump.\n"); - fprintf(stderr, " is the destination for the upload\n"); - - fprintf(stderr, "\t-h: Usage\n"); - fprintf(stderr, "\t-?: Usage\n"); -} - -//============================================================================= -static void -SetupOptions(int argc, const char *argv[], Options *options) { - extern int optind; - char ch; - - while ((ch = getopt(argc, (char * const *)argv, "p:v:h?")) != -1) { - switch (ch) { - case 'p': - options->product = [NSString stringWithUTF8String:optarg]; - break; - case 'v': - options->version = [NSString stringWithUTF8String:optarg]; - break; - - default: - Usage(argc, argv); - exit(0); - break; - } - } - - if ((argc - optind) != 2) { - fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]); - Usage(argc, argv); - exit(1); - } - - options->minidumpPath = [NSString stringWithUTF8String:argv[optind]]; - options->uploadURLStr = [NSString stringWithUTF8String:argv[optind + 1]]; -} - -//============================================================================= -int main (int argc, const char * argv[]) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - Options options; - - bzero(&options, sizeof(Options)); - SetupOptions(argc, argv, &options); - Start(&options); - - [pool release]; - return options.success ? 0 : 1; -} diff --git a/src/tools/mac/symupload/symupload.m b/src/tools/mac/symupload/symupload.m index a87dd4ea..e280947b 100644 --- a/src/tools/mac/symupload/symupload.m +++ b/src/tools/mac/symupload/symupload.m @@ -48,14 +48,11 @@ #include "HTTPPutRequest.h" #include "SymbolCollectorClient.h" -typedef enum { - SymUploadProtocolV1, - SymUploadProtocolV2 -} SymUploadProtocol; +typedef enum { SymUploadProtocolV1, SymUploadProtocolV2 } SymUploadProtocol; typedef struct { - NSString *symbolsPath; - NSString *uploadURLStr; + NSString* symbolsPath; + NSString* uploadURLStr; SymUploadProtocol symUploadProtocol; NSString* apiKey; BOOL force; @@ -63,19 +60,20 @@ typedef struct { } Options; //============================================================================= -static NSArray *ModuleDataForSymbolFile(NSString *file) { - NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:file]; - NSData *data = [fh readDataOfLength:1024]; - NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - NSScanner *scanner = [NSScanner scannerWithString:str]; - NSString *line; - NSMutableArray *parts = nil; +static NSArray* ModuleDataForSymbolFile(NSString* file) { + NSFileHandle* fh = [NSFileHandle fileHandleForReadingAtPath:file]; + NSData* data = [fh readDataOfLength:1024]; + NSString* str = [[NSString alloc] initWithData:data + encoding:NSUTF8StringEncoding]; + NSScanner* scanner = [NSScanner scannerWithString:str]; + NSString* line; + NSMutableArray* parts = nil; const int MODULE_ID_INDEX = 3; - + if ([scanner scanUpToString:@"\n" intoString:&line]) { parts = [[NSMutableArray alloc] init]; - NSScanner *moduleInfoScanner = [NSScanner scannerWithString:line]; - NSString *moduleInfo; + NSScanner* moduleInfoScanner = [NSScanner scannerWithString:line]; + NSString* moduleInfo; // Get everything BEFORE the module name. None of these properties // can have spaces. for (int i = 0; i <= MODULE_ID_INDEX; i++) { @@ -98,9 +96,9 @@ static NSArray *ModuleDataForSymbolFile(NSString *file) { static void StartSymUploadProtocolV1(Options* options, NSArray* moduleParts, NSString* compactedID) { - NSURL *url = [NSURL URLWithString:options->uploadURLStr]; - HTTPMultipartUpload *ul = [[HTTPMultipartUpload alloc] initWithURL:url]; - NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + NSURL* url = [NSURL URLWithString:options->uploadURLStr]; + HTTPMultipartUpload* ul = [[HTTPMultipartUpload alloc] initWithURL:url]; + NSMutableDictionary* parameters = [NSMutableDictionary dictionary]; // Add parameters [parameters setObject:compactedID forKey:@"debug_identifier"]; @@ -112,51 +110,52 @@ static void StartSymUploadProtocolV1(Options* options, [parameters setObject:[moduleParts objectAtIndex:4] forKey:@"debug_file"]; [parameters setObject:[moduleParts objectAtIndex:4] forKey:@"code_file"]; [ul setParameters:parameters]; - - NSArray *keys = [parameters allKeys]; + + NSArray* keys = [parameters allKeys]; int count = [keys count]; for (int i = 0; i < count; ++i) { - NSString *key = [keys objectAtIndex:i]; - NSString *value = [parameters objectForKey:key]; - fprintf(stdout, "'%s' = '%s'\n", [key UTF8String], - [value UTF8String]); + NSString* key = [keys objectAtIndex:i]; + NSString* value = [parameters objectForKey:key]; + fprintf(stdout, "'%s' = '%s'\n", [key UTF8String], [value UTF8String]); } // Add file [ul addFileAtPath:options->symbolsPath name:@"symbol_file"]; // Send it - NSError *error = nil; - NSData *data = [ul send:&error]; - NSString *result = [[NSString alloc] initWithData:data + NSError* error = nil; + NSData* data = [ul send:&error]; + NSString* result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; int status = [[ul response] statusCode]; - fprintf(stdout, "Send: %s\n", error ? [[error description] UTF8String] : - "No Error"); + fprintf(stdout, "Send: %s\n", + error ? [[error description] UTF8String] : "No Error"); fprintf(stdout, "Response: %d\n", status); - fprintf(stdout, "Result: %lu bytes\n%s\n", - (unsigned long)[data length], [result UTF8String]); + fprintf(stdout, "Result: %lu bytes\n%s\n", (unsigned long)[data length], + [result UTF8String]); [result release]; [ul release]; - options->success = !error && status==200; + options->success = !error && status == 200; } //============================================================================= static void StartSymUploadProtocolV2(Options* options, - NSString* debugFile, + NSArray* moduleParts, NSString* debugID) { + options->success = NO; + + NSString* debugFile = [moduleParts objectAtIndex:4]; if (!options->force) { - SymbolStatus symbolStatus = [SymbolCollectorClient - CheckSymbolStatus:options->uploadURLStr - withAPIKey:options->apiKey - withDebugFile:debugFile - withDebugID:debugID]; + SymbolStatus symbolStatus = + [SymbolCollectorClient checkSymbolStatusOnServer:options->uploadURLStr + withAPIKey:options->apiKey + withDebugFile:debugFile + withDebugID:debugID]; if (symbolStatus == SymbolStatusFound) { fprintf(stdout, "Symbol file already exists, upload aborted." - " Use \"-f\" to overwrite.\n"); - options->success = YES; + " Use \"-f\" to overwrite.\n"); return; } else if (symbolStatus == SymbolStatusUnknown) { fprintf(stdout, "Failed to get check for existing symbol.\n"); @@ -164,21 +163,20 @@ static void StartSymUploadProtocolV2(Options* options, } } - UploadURLResponse* URLResponse = [SymbolCollectorClient - CreateUploadURL:options->uploadURLStr - withAPIKey:options->apiKey]; + UploadURLResponse* URLResponse = + [SymbolCollectorClient createUploadURLOnServer:options->uploadURLStr + withAPIKey:options->apiKey]; if (URLResponse == nil) { return; } NSURL* uploadURL = [NSURL URLWithString:[URLResponse uploadURL]]; - HTTPPutRequest* putRequest = [[HTTPPutRequest alloc] - initWithURL:uploadURL]; + HTTPPutRequest* putRequest = [[HTTPPutRequest alloc] initWithURL:uploadURL]; [putRequest setFile:options->symbolsPath]; - NSError *error = nil; + NSError* error = nil; NSData* data = [putRequest send:&error]; - NSString *result = [[NSString alloc] initWithData:data + NSString* result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; int responseCode = [[putRequest response] statusCode]; [putRequest release]; @@ -191,19 +189,19 @@ static void StartSymUploadProtocolV2(Options* options, return; } - CompleteUploadResult completeUploadResult = [SymbolCollectorClient - CompleteUpload:options->uploadURLStr + CompleteUploadResult completeUploadResult = + [SymbolCollectorClient completeUploadOnServer:options->uploadURLStr withAPIKey:options->apiKey - withUploadKey:[URLResponse uploadKey] - withDebugFile:debugFile - withDebugID:debugID]; + withUploadKey:[URLResponse uploadKey] + withDebugFile:debugFile + withDebugID:debugID]; [URLResponse release]; if (completeUploadResult == CompleteUploadResultError) { fprintf(stdout, "Failed to complete upload.\n"); return; } else if (completeUploadResult == CompleteUploadResultDuplicateData) { fprintf(stdout, "Uploaded file checksum matched existing file checksum," - " no change necessary.\n"); + " no change necessary.\n"); } else { fprintf(stdout, "Successfully sent the symbol file.\n"); } @@ -211,52 +209,50 @@ static void StartSymUploadProtocolV2(Options* options, } //============================================================================= -static void Start(Options *options) { - NSArray *moduleParts = ModuleDataForSymbolFile(options->symbolsPath); - NSMutableString *compactedID = - [NSMutableString stringWithString:[moduleParts objectAtIndex:3]]; - [compactedID replaceOccurrencesOfString:@"-" withString:@"" options:0 +static void Start(Options* options) { + NSArray* moduleParts = ModuleDataForSymbolFile(options->symbolsPath); + NSMutableString* compactedID = + [NSMutableString stringWithString:[moduleParts objectAtIndex:3]]; + [compactedID replaceOccurrencesOfString:@"-" + withString:@"" + options:0 range:NSMakeRange(0, [compactedID length])]; if (options->symUploadProtocol == SymUploadProtocolV1) { StartSymUploadProtocolV1(options, moduleParts, compactedID); } else if (options->symUploadProtocol == SymUploadProtocolV2) { - StartSymUploadProtocolV2(options, - [moduleParts objectAtIndex:4], - compactedID); + StartSymUploadProtocolV2(options, moduleParts, compactedID); } } //============================================================================= -static void -Usage(int argc, const char *argv[]) { +static void Usage(int argc, const char* argv[]) { fprintf(stderr, "Submit symbol information.\n"); fprintf(stderr, "Usage: %s [options] \n", argv[0]); fprintf(stderr, " should be created by using the dump_syms " - "tool.\n"); + "tool.\n"); fprintf(stderr, " is the destination for the upload.\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, "\t-p : protocol to use for upload, accepts " - "[\"sym-upload-v1\", \"sym-upload-v2\"]. Default is " - "\"sym-upload-v1\".\n"); + "[\"sym-upload-v1\", \"sym-upload-v2\"]. Default is " + "\"sym-upload-v1\".\n"); fprintf(stderr, "\t-k : secret for authentication with upload " - "server. [Only in sym-upload-v2 protocol mode]\n"); + "server. [Only in sym-upload-v2 protocol mode]\n"); fprintf(stderr, "\t-f: Overwrite symbol file on server if already present. " - "[Only in sym-upload-v2 protocol mode]\n"); + "[Only in sym-upload-v2 protocol mode]\n"); fprintf(stderr, "\t-h: Usage\n"); fprintf(stderr, "\t-?: Usage\n"); } //============================================================================= -static void -SetupOptions(int argc, const char *argv[], Options *options) { +static void SetupOptions(int argc, const char* argv[], Options* options) { // Set default value of symUploadProtocol. options->symUploadProtocol = SymUploadProtocolV1; extern int optind; char ch; - while ((ch = getopt(argc, (char * const *)argv, "p:k:hf?")) != -1) { + while ((ch = getopt(argc, (char* const*)argv, "p:k:hf?")) != -1) { switch (ch) { case 'p': if (strcmp(optarg, "sym-upload-v2") == 0) { @@ -314,8 +310,8 @@ SetupOptions(int argc, const char *argv[], Options *options) { } //============================================================================= -int main (int argc, const char * argv[]) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; +int main(int argc, const char* argv[]) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; Options options; bzero(&options, sizeof(Options)); diff --git a/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj b/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj index edf7b1a0..1653b388 100644 --- a/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj +++ b/src/tools/mac/symupload/symupload.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 5B6060C7222735E50015F0A0 /* HTTPGetRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B6060C6222735E50015F0A0 /* HTTPGetRequest.m */; }; 5B6060CA2227374E0015F0A0 /* HTTPSimplePostRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B6060C92227374E0015F0A0 /* HTTPSimplePostRequest.m */; }; 5B6060D022273BDA0015F0A0 /* SymbolCollectorClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B6060CF22273BDA0015F0A0 /* SymbolCollectorClient.m */; }; + 5B97447524D0AA5F000C71F5 /* encoding_util.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B97447424D0AA5F000C71F5 /* encoding_util.m */; }; 8B31022C11F0CEBD00FCF3E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; 8DD76F9A0486AA7600D96B5E /* symupload.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* symupload.m */; settings = {ATTRIBUTES = (); }; }; 8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; }; @@ -37,17 +38,18 @@ /* Begin PBXFileReference section */ 08FB7796FE84155DC02AAC07 /* symupload.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = symupload.m; sourceTree = ""; tabWidth = 2; }; 08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 5B6060BB222716FC0015F0A0 /* HTTPRequest.h */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = HTTPRequest.h; sourceTree = ""; tabWidth = 2; }; - 5B6060BC222716FC0015F0A0 /* HTTPRequest.m */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = HTTPRequest.m; sourceTree = ""; tabWidth = 2; }; - 5B6060BE2227201B0015F0A0 /* HTTPPutRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTTPPutRequest.h; sourceTree = ""; }; - 5B6060BF2227201B0015F0A0 /* HTTPPutRequest.m */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = HTTPPutRequest.m; sourceTree = ""; tabWidth = 2; }; - 5B6060C22227303A0015F0A0 /* util.h */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; tabWidth = 2; }; - 5B6060C5222735E50015F0A0 /* HTTPGetRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTTPGetRequest.h; sourceTree = ""; }; - 5B6060C6222735E50015F0A0 /* HTTPGetRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HTTPGetRequest.m; sourceTree = ""; }; - 5B6060C82227374E0015F0A0 /* HTTPSimplePostRequest.h */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = HTTPSimplePostRequest.h; sourceTree = ""; tabWidth = 2; }; - 5B6060C92227374E0015F0A0 /* HTTPSimplePostRequest.m */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = HTTPSimplePostRequest.m; sourceTree = ""; tabWidth = 2; }; - 5B6060CE22273BDA0015F0A0 /* SymbolCollectorClient.h */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = SymbolCollectorClient.h; sourceTree = ""; tabWidth = 2; }; - 5B6060CF22273BDA0015F0A0 /* SymbolCollectorClient.m */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = SymbolCollectorClient.m; sourceTree = ""; tabWidth = 2; }; + 5B6060BB222716FC0015F0A0 /* HTTPRequest.h */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = HTTPRequest.h; path = ../../../common/mac/HTTPRequest.h; sourceTree = ""; tabWidth = 2; }; + 5B6060BC222716FC0015F0A0 /* HTTPRequest.m */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; name = HTTPRequest.m; path = ../../../common/mac/HTTPRequest.m; sourceTree = ""; tabWidth = 2; }; + 5B6060BE2227201B0015F0A0 /* HTTPPutRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = HTTPPutRequest.h; path = ../../../common/mac/HTTPPutRequest.h; sourceTree = ""; }; + 5B6060BF2227201B0015F0A0 /* HTTPPutRequest.m */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; name = HTTPPutRequest.m; path = ../../../common/mac/HTTPPutRequest.m; sourceTree = ""; tabWidth = 2; }; + 5B6060C22227303A0015F0A0 /* encoding_util.h */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = encoding_util.h; path = ../../../common/mac/encoding_util.h; sourceTree = ""; tabWidth = 2; }; + 5B6060C5222735E50015F0A0 /* HTTPGetRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = HTTPGetRequest.h; path = ../../../common/mac/HTTPGetRequest.h; sourceTree = ""; }; + 5B6060C6222735E50015F0A0 /* HTTPGetRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = HTTPGetRequest.m; path = ../../../common/mac/HTTPGetRequest.m; sourceTree = ""; }; + 5B6060C82227374E0015F0A0 /* HTTPSimplePostRequest.h */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = HTTPSimplePostRequest.h; path = ../../../common/mac/HTTPSimplePostRequest.h; sourceTree = ""; tabWidth = 2; }; + 5B6060C92227374E0015F0A0 /* HTTPSimplePostRequest.m */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; name = HTTPSimplePostRequest.m; path = ../../../common/mac/HTTPSimplePostRequest.m; sourceTree = ""; tabWidth = 2; }; + 5B6060CE22273BDA0015F0A0 /* SymbolCollectorClient.h */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = SymbolCollectorClient.h; path = ../../../common/mac/SymbolCollectorClient.h; sourceTree = ""; tabWidth = 2; }; + 5B6060CF22273BDA0015F0A0 /* SymbolCollectorClient.m */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; name = SymbolCollectorClient.m; path = ../../../common/mac/SymbolCollectorClient.m; sourceTree = ""; tabWidth = 2; }; + 5B97447424D0AA5F000C71F5 /* encoding_util.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = encoding_util.m; path = ../../../common/mac/encoding_util.m; sourceTree = ""; }; 8B31022B11F0CE6900FCF3E4 /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; }; 8B3102B611F0D5CE00FCF3E4 /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; }; 8B3102B711F0D5CE00FCF3E4 /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; }; @@ -55,7 +57,7 @@ 9BD833680B03E4080055103E /* HTTPMultipartUpload.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = HTTPMultipartUpload.h; path = ../../../common/mac/HTTPMultipartUpload.h; sourceTree = ""; tabWidth = 2; }; 9BD833690B03E4080055103E /* HTTPMultipartUpload.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; name = HTTPMultipartUpload.m; path = ../../../common/mac/HTTPMultipartUpload.m; sourceTree = ""; tabWidth = 2; }; 9BD835FB0B0544950055103E /* minidump_upload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = minidump_upload; sourceTree = BUILT_PRODUCTS_DIR; }; - 9BD836000B0544BA0055103E /* minidump_upload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = minidump_upload.m; sourceTree = ""; }; + 9BD836000B0544BA0055103E /* minidump_upload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = minidump_upload.m; path = ../../../common/mac/minidump_upload.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -87,7 +89,8 @@ 5B6060C92227374E0015F0A0 /* HTTPSimplePostRequest.m */, 5B6060C5222735E50015F0A0 /* HTTPGetRequest.h */, 5B6060C6222735E50015F0A0 /* HTTPGetRequest.m */, - 5B6060C22227303A0015F0A0 /* util.h */, + 5B6060C22227303A0015F0A0 /* encoding_util.h */, + 5B97447424D0AA5F000C71F5 /* encoding_util.m */, 5B6060BE2227201B0015F0A0 /* HTTPPutRequest.h */, 5B6060BF2227201B0015F0A0 /* HTTPPutRequest.m */, 5B6060BB222716FC0015F0A0 /* HTTPRequest.h */, @@ -194,6 +197,7 @@ 5B6060C7222735E50015F0A0 /* HTTPGetRequest.m in Sources */, 5B6060C02227201B0015F0A0 /* HTTPPutRequest.m in Sources */, 5B6060BD222716FC0015F0A0 /* HTTPRequest.m in Sources */, + 5B97447524D0AA5F000C71F5 /* encoding_util.m in Sources */, 9BD8336B0B03E4080055103E /* HTTPMultipartUpload.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/src/tools/mac/symupload/util.h b/src/tools/mac/symupload/util.h deleted file mode 100644 index 67112868..00000000 --- a/src/tools/mac/symupload/util.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2019, 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 util_h -#define util_h - -#import - -// As -[NSString stringByAddingPercentEscapesUsingEncoding:] has been -// deprecated with iOS 9.0 / OS X 10.11 SDKs, this function re-implements it -// using -[NSString stringByAddingPercentEncodingWithAllowedCharacters:] when -// using those SDKs. -static NSString *PercentEncodeNSString(NSString *key) { -#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_9_0) && \ -__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0) || \ -(defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ -defined(MAC_OS_X_VERSION_10_11) && \ -MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11) - return [key stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLQueryAllowedCharacterSet]]; -#else - return [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; -#endif -} - -#endif /* util_h */ -- cgit v1.2.1