From 114336881a21459d2c7fab2de5e010b5faf55e55 Mon Sep 17 00:00:00 2001 From: Nelson Billing Date: Wed, 22 Jul 2020 14:44:06 -0700 Subject: Port new symbol API to symupload on Mac. - See documentation in Linux implementation commit: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/1422400. Change-Id: If3ff256e63f2db3ac9c0be78cfc17754d532cb88 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/1497653 Reviewed-by: Ivan Penkov --- src/common/mac/HTTPMultipartUpload.h | 34 ++++---- src/common/mac/HTTPMultipartUpload.m | 156 +++++++---------------------------- 2 files changed, 49 insertions(+), 141 deletions(-) (limited to 'src/common') diff --git a/src/common/mac/HTTPMultipartUpload.h b/src/common/mac/HTTPMultipartUpload.h index 42e8fed3..5eaaa91b 100644 --- a/src/common/mac/HTTPMultipartUpload.h +++ b/src/common/mac/HTTPMultipartUpload.h @@ -27,35 +27,39 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// HTTPMultipartUpload: A multipart/form-data HTTP uploader. -// Each parameter pair is sent as a boundary -// Each file is sent with a name field in addition to the filename and data -// The data will be sent synchronously. + #import -@interface HTTPMultipartUpload : NSObject { +#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. + */ +@interface HTTPMultipartUpload : HTTPRequest { @protected - NSURL *url_; // The destination URL (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) - NSHTTPURLResponse *response_; // The response from the send (STRONG) } -- (id)initWithURL:(NSURL *)url; - -- (NSURL *)URL; - +/** + Sets the parameters that will be sent in the multipart POST request. + */ - (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; + +/** + 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; -// Set the data and return the response -- (NSData *)send:(NSError **)error; -- (NSHTTPURLResponse *)response; - @end diff --git a/src/common/mac/HTTPMultipartUpload.m b/src/common/mac/HTTPMultipartUpload.m index a3677f25..7fc474b8 100644 --- a/src/common/mac/HTTPMultipartUpload.m +++ b/src/common/mac/HTTPMultipartUpload.m @@ -28,67 +28,10 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #import "HTTPMultipartUpload.h" -#import "GTMDefines.h" -// 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 -} +#import "GTMDefines.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 **out_response, - NSError **out_error) { -#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 wait_semaphone = dispatch_semaphore_create(0); - [[[NSURLSession sharedSession] - dataTaskWithRequest:req - completionHandler:^(NSData *data, - NSURLResponse *resp, - NSError *err) { - if (out_error) - error = [err retain]; - if (out_response) - response = [resp retain]; - if (err == nil) - result = [data retain]; - dispatch_semaphore_signal(wait_semaphone); - }] resume]; - dispatch_semaphore_wait(wait_semaphone, DISPATCH_TIME_FOREVER); - dispatch_release(wait_semaphone); - if (out_error) - *out_error = [error autorelease]; - if (out_response) - *out_response = [response autorelease]; - return [result autorelease]; -#else - return [NSURLConnection sendSynchronousRequest:req - returningResponse:out_response - error:out_error]; -#endif -} @interface HTTPMultipartUpload(PrivateMethods) - (NSString *)multipartBoundary; // Each of the following methods will append the starting multipart boundary, @@ -111,33 +54,24 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req, //============================================================================= - (NSData *)formDataForKey:(NSString *)key value:(NSString *)value { + NSMutableData* data = [NSMutableData data]; + [self appendBoundaryData:data]; + NSString *escaped = PercentEncodeNSString(key); NSString *fmt = - @"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n"; + @"Content-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n"; NSString *form = [NSString stringWithFormat:fmt, boundary_, escaped, value]; - return [form dataUsingEncoding:NSUTF8StringEncoding]; -} - -//============================================================================= -- (NSData *)formDataForFileContents:(NSData *)contents name:(NSString *)name { - NSMutableData *data = [NSMutableData data]; - NSString *escaped = PercentEncodeNSString(name); - NSString *fmt = @"--%@\r\nContent-Disposition: form-data; name=\"%@\"; " - "filename=\"minidump.dmp\"\r\nContent-Type: application/octet-stream\r\n\r\n"; - NSString *pre = [NSString stringWithFormat:fmt, boundary_, escaped]; - - [data appendData:[pre dataUsingEncoding:NSUTF8StringEncoding]]; - [data appendData:contents]; - + [data appendData:[form dataUsingEncoding:NSUTF8StringEncoding]]; return data; } //============================================================================= -- (NSData *)formDataForFile:(NSString *)file name:(NSString *)name { - NSData *contents = [NSData dataWithContentsOfFile:file]; +- (void)appendBoundaryData: (NSMutableData*)data { + NSString *fmt = @"--%@\r\n"; + NSString *pre = [NSString stringWithFormat:fmt, boundary_]; - return [self formDataForFileContents:contents name:name]; + [data appendData:[pre dataUsingEncoding:NSUTF8StringEncoding]]; } //============================================================================= @@ -145,8 +79,7 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req, #pragma mark || Public || //============================================================================= - (id)initWithURL:(NSURL *)url { - if ((self = [super init])) { - url_ = [url copy]; + if ((self = [super initWithURL:url])) { boundary_ = [[self multipartBoundary] retain]; files_ = [[NSMutableDictionary alloc] init]; } @@ -156,20 +89,13 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req, //============================================================================= - (void)dealloc { - [url_ release]; [parameters_ release]; [files_ release]; [boundary_ release]; - [response_ release]; [super dealloc]; } -//============================================================================= -- (NSURL *)URL { - return url_; -} - //============================================================================= - (void)setParameters:(NSDictionary *)parameters { if (parameters != parameters_) { @@ -199,17 +125,20 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req, } //============================================================================= -- (NSData *)send:(NSError **)error { - NSMutableURLRequest *req = - [[NSMutableURLRequest alloc] - initWithURL:url_ cachePolicy:NSURLRequestUseProtocolCachePolicy - timeoutInterval:60.0]; +- (NSString*)HTTPMethod { + return @"POST"; +} + +//============================================================================= +- (NSString*)contentType { + return [NSString stringWithFormat:@"multipart/form-data; boundary=%@", + boundary_]; +} +//============================================================================= +- (NSData*)bodyData { NSMutableData *postBody = [NSMutableData data]; - [req setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", - boundary_] forHTTPHeaderField:@"Content-type"]; - // Add any parameters to the message NSArray *parameterKeys = [parameters_ allKeys]; NSString *key; @@ -224,44 +153,19 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req, // Add any files to the message NSArray *fileNames = [files_ allKeys]; for (NSString *name in fileNames) { + // First append boundary + [self appendBoundaryData:postBody]; + // Then the formdata id fileOrData = [files_ objectForKey:name]; - 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 name:name]; - else - fileData = [self formDataForFile:fileOrData name:name]; - - [postBody appendData:fileData]; + [HTTPRequest appendFileToBodyData:postBody + withName:name + withFileOrData:fileOrData]; } NSString *epilogue = [NSString stringWithFormat:@"\r\n--%@--\r\n", boundary_]; [postBody appendData:[epilogue dataUsingEncoding:NSUTF8StringEncoding]]; - [req setHTTPBody:postBody]; - [req setHTTPMethod:@"POST"]; - - [response_ release]; - response_ = nil; - - NSData *data = nil; - if ([[req URL] isFileURL]) { - [[req HTTPBody] writeToURL:[req URL] options:0 error:error]; - } else { - NSURLResponse *response = nil; - data = SendSynchronousNSURLRequest(req, &response, error); - response_ = (NSHTTPURLResponse *)[response retain]; - } - [req release]; - - return data; -} - -//============================================================================= -- (NSHTTPURLResponse *)response { - return response_; + return postBody; } @end -- cgit v1.2.1