aboutsummaryrefslogtreecommitdiff
path: root/src/tools/mac/symupload/SymbolCollectorClient.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/mac/symupload/SymbolCollectorClient.m')
-rw-r--r--src/tools/mac/symupload/SymbolCollectorClient.m247
1 files changed, 247 insertions, 0 deletions
diff --git a/src/tools/mac/symupload/SymbolCollectorClient.m b/src/tools/mac/symupload/SymbolCollectorClient.m
new file mode 100644
index 00000000..38103ccb
--- /dev/null
+++ b/src/tools/mac/symupload/SymbolCollectorClient.m
@@ -0,0 +1,247 @@
+// 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