mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-03-10 02:42:55 +00:00
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 <ivanpe@chromium.org>
This commit is contained in:
@@ -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 <Foundation/Foundation.h>
|
||||
|
||||
@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
|
||||
|
||||
@@ -28,67 +28,10 @@
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#import "HTTPMultipartUpload.h"
|
||||
|
||||
#import "GTMDefines.h"
|
||||
#import "util.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
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user