OLD | NEW |
---|---|
1 // Copyright (c) 2006, Google Inc. | 1 // Copyright (c) 2006, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 12 matching lines...) Expand all Loading... | |
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 #import "HTTPMultipartUpload.h" | 30 #import "HTTPMultipartUpload.h" |
31 #import "GTMDefines.h" | 31 #import "GTMDefines.h" |
32 | 32 |
33 // As -[NSString stringByAddingPercentEscapesUsingEncoding:] has been | |
34 // deprecated with iOS 9.0 / OS X 10.11 SDKs, this function re-implement it | |
Mark Mentovai
2016/01/07 17:19:15
re-implements
sdefresne
2016/01/07 17:45:48
Done.
| |
35 // using -[NSString stringByAddingPercentEncodingWithAllowedCharacters:] when | |
36 // using those SDKs. | |
37 static NSString *EscapeStringByAddingPercent(NSString *key) { | |
Mark Mentovai
2016/01/07 17:19:15
Naming like PercentEncodeNSString()?
sdefresne
2016/01/07 17:45:49
Done.
| |
38 #if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ | |
Mark Mentovai
2016/01/07 17:19:15
#include <Availability.h> for this.
sdefresne
2016/01/07 17:45:48
Done.
| |
39 __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || \ | |
40 (defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ | |
Mark Mentovai
2016/01/07 17:19:16
#include <AvailabilityMacros.h> for this.
sdefresne
2016/01/07 17:45:48
Done.
| |
41 MAC_OS_X_VERSION_MIN_REQUIRED >= 1011) | |
Mark Mentovai
2016/01/07 17:19:16
MAC_OS_X_VERSION_10_11 instead of 1011. Because 10
sdefresne
2016/01/07 17:45:48
Done.
| |
42 return [key stringByAddingPercentEncodingWithAllowedCharacters: | |
Mark Mentovai
2016/01/07 17:19:15
Does this %-encode a literal % too?
sdefresne
2016/01/07 17:45:49
Yes according to my little testing in a swift play
| |
43 [NSCharacterSet alphanumericCharacterSet]]; | |
44 #else | |
45 return [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; | |
46 #endif | |
47 } | |
48 | |
49 // As -[NSURLConnection sendSynchronousRequest:returningResponse:error:] has | |
50 // been deprecated with iOS 9.0 / OS X 10.11 SDKs, this function re-implement | |
Mark Mentovai
2016/01/07 17:19:15
re-implements
sdefresne
2016/01/07 17:45:48
Done.
| |
51 // it using -[NSURLSession dataTaskWithRequest:completionHandler:] when using | |
52 // those SDKs. | |
53 static NSData *SendSynchronousRequest(NSURLRequest *req, | |
Mark Mentovai
2016/01/07 17:19:15
Something like SendSynchronousNSURLRequest()?
Giv
sdefresne
2016/01/07 17:45:49
Done.
| |
54 NSURLResponse **response, | |
55 NSError **error) { | |
56 #if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ | |
Mark Mentovai
2016/01/07 17:19:16
Same here.
sdefresne
2016/01/07 17:45:48
Done.
| |
57 __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || \ | |
58 (defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ | |
59 MAC_OS_X_VERSION_MIN_REQUIRED >= 1011) | |
60 __block NSData* result = nil; | |
61 dispatch_semaphore_t wait_semaphone = dispatch_semaphore_create(0); | |
62 [[[NSURLSession sharedSession] | |
63 dataTaskWithRequest:req | |
64 completionHandler:^(NSData *data, NSURLResponse *resp, NSError *err) { | |
65 if (error) | |
66 *error = err; | |
67 if (response) | |
68 *response = resp; | |
69 if (err == nil) | |
70 result = data; | |
71 dispatch_semaphore_signal(wait_semaphone); | |
72 }] resume]; | |
73 dispatch_semaphore_wait(wait_semaphone, DISPATCH_TIME_FOREVER); | |
Mark Mentovai
2016/01/07 17:19:15
Looks like it’s leaked, there’s no dispatch_releas
sdefresne
2016/01/07 17:45:48
Thanks, fixed.
| |
74 return result; | |
75 #else | |
76 return [NSURLConnection sendSynchronousRequest:req | |
77 returningResponse:response | |
78 error:error]; | |
79 #endif | |
80 } | |
81 | |
33 @interface HTTPMultipartUpload(PrivateMethods) | 82 @interface HTTPMultipartUpload(PrivateMethods) |
34 - (NSString *)multipartBoundary; | 83 - (NSString *)multipartBoundary; |
35 // Each of the following methods will append the starting multipart boundary, | 84 // Each of the following methods will append the starting multipart boundary, |
36 // but not the ending one. | 85 // but not the ending one. |
37 - (NSData *)formDataForKey:(NSString *)key value:(NSString *)value; | 86 - (NSData *)formDataForKey:(NSString *)key value:(NSString *)value; |
38 - (NSData *)formDataForFileContents:(NSData *)contents name:(NSString *)name; | 87 - (NSData *)formDataForFileContents:(NSData *)contents name:(NSString *)name; |
39 - (NSData *)formDataForFile:(NSString *)file name:(NSString *)name; | 88 - (NSData *)formDataForFile:(NSString *)file name:(NSString *)name; |
40 @end | 89 @end |
41 | 90 |
42 @implementation HTTPMultipartUpload | 91 @implementation HTTPMultipartUpload |
43 //============================================================================= | 92 //============================================================================= |
44 #pragma mark - | 93 #pragma mark - |
45 #pragma mark || Private || | 94 #pragma mark || Private || |
46 //============================================================================= | 95 //============================================================================= |
47 - (NSString *)multipartBoundary { | 96 - (NSString *)multipartBoundary { |
48 // The boundary has 27 '-' characters followed by 16 hex digits | 97 // The boundary has 27 '-' characters followed by 16 hex digits |
49 return [NSString stringWithFormat:@"---------------------------%08X%08X", | 98 return [NSString stringWithFormat:@"---------------------------%08X%08X", |
50 rand(), rand()]; | 99 rand(), rand()]; |
51 } | 100 } |
52 | 101 |
53 //============================================================================= | 102 //============================================================================= |
54 - (NSData *)formDataForKey:(NSString *)key value:(NSString *)value { | 103 - (NSData *)formDataForKey:(NSString *)key value:(NSString *)value { |
55 NSString *escaped = | 104 NSString *escaped = EscapeStringByAddingPercent(key); |
56 [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; | |
57 NSString *fmt = | 105 NSString *fmt = |
58 @"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n"; | 106 @"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n"; |
59 NSString *form = [NSString stringWithFormat:fmt, boundary_, escaped, value]; | 107 NSString *form = [NSString stringWithFormat:fmt, boundary_, escaped, value]; |
60 | 108 |
61 return [form dataUsingEncoding:NSUTF8StringEncoding]; | 109 return [form dataUsingEncoding:NSUTF8StringEncoding]; |
62 } | 110 } |
63 | 111 |
64 //============================================================================= | 112 //============================================================================= |
65 - (NSData *)formDataForFileContents:(NSData *)contents name:(NSString *)name { | 113 - (NSData *)formDataForFileContents:(NSData *)contents name:(NSString *)name { |
66 NSMutableData *data = [NSMutableData data]; | 114 NSMutableData *data = [NSMutableData data]; |
67 NSString *escaped = | 115 NSString *escaped = EscapeStringByAddingPercent(name); |
68 [name stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; | |
69 NSString *fmt = @"--%@\r\nContent-Disposition: form-data; name=\"%@\"; " | 116 NSString *fmt = @"--%@\r\nContent-Disposition: form-data; name=\"%@\"; " |
70 "filename=\"minidump.dmp\"\r\nContent-Type: application/octet-stream\r\n\r\n "; | 117 "filename=\"minidump.dmp\"\r\nContent-Type: application/octet-stream\r\n\r\n "; |
71 NSString *pre = [NSString stringWithFormat:fmt, boundary_, escaped]; | 118 NSString *pre = [NSString stringWithFormat:fmt, boundary_, escaped]; |
72 | 119 |
73 [data appendData:[pre dataUsingEncoding:NSUTF8StringEncoding]]; | 120 [data appendData:[pre dataUsingEncoding:NSUTF8StringEncoding]]; |
74 [data appendData:contents]; | 121 [data appendData:contents]; |
75 | 122 |
76 return data; | 123 return data; |
77 } | 124 } |
78 | 125 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
189 [req setHTTPMethod:@"POST"]; | 236 [req setHTTPMethod:@"POST"]; |
190 | 237 |
191 [response_ release]; | 238 [response_ release]; |
192 response_ = nil; | 239 response_ = nil; |
193 | 240 |
194 NSData *data = nil; | 241 NSData *data = nil; |
195 if ([[req URL] isFileURL]) { | 242 if ([[req URL] isFileURL]) { |
196 [[req HTTPBody] writeToURL:[req URL] options:0 error:error]; | 243 [[req HTTPBody] writeToURL:[req URL] options:0 error:error]; |
197 } else { | 244 } else { |
198 NSURLResponse *response = nil; | 245 NSURLResponse *response = nil; |
199 data = [NSURLConnection sendSynchronousRequest:req | 246 data = SendSynchronousRequest(req, &response, error); |
200 returningResponse:&response | |
201 error:error]; | |
202 response_ = (NSHTTPURLResponse *)[response retain]; | 247 response_ = (NSHTTPURLResponse *)[response retain]; |
203 } | 248 } |
204 [req release]; | 249 [req release]; |
205 | 250 |
206 return data; | 251 return data; |
207 } | 252 } |
208 | 253 |
209 //============================================================================= | 254 //============================================================================= |
210 - (NSHTTPURLResponse *)response { | 255 - (NSHTTPURLResponse *)response { |
211 return response_; | 256 return response_; |
212 } | 257 } |
213 | 258 |
214 @end | 259 @end |
OLD | NEW |