OSSUtil.m 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342
  1. //
  2. // OSSUtil.m
  3. // oss_ios_sdk
  4. //
  5. // Created by zhouzhuo on 8/16/15.
  6. // Copyright (c) 2015 aliyun.com. All rights reserved.
  7. //
  8. #import "OSSUtil.h"
  9. #import <mach/mach.h>
  10. #import "CommonCrypto/CommonDigest.h"
  11. #import "CommonCrypto/CommonHMAC.h"
  12. #import "OSSModel.h"
  13. #import "OSSLog.h"
  14. #import "OSSHttpdns.h"
  15. #import "OSSDefine.h"
  16. #import "OSSIPv6Adapter.h"
  17. #import "OSSReachability.h"
  18. #import <CoreTelephony/CTCarrier.h>
  19. #import <CoreTelephony/CTTelephonyNetworkInfo.h>
  20. #import "aos_crc64.h"
  21. NSString * const ALIYUN_HOST_SUFFIX = @".aliyuncs.com";
  22. NSString * const ALIYUN_OSS_TEST_ENDPOINT = @".aliyun-inc.com";
  23. int32_t const CHUNK_SIZE = 8 * 1024;
  24. @implementation OSSUtil
  25. + (BOOL)isIncludeCnameExcludeList:(NSArray *)cnameExcludeList host:(NSString *)host {
  26. for (NSString *cnameExclude in cnameExcludeList) {
  27. if ([host hasSuffix:cnameExclude]) {
  28. return YES;
  29. }
  30. }
  31. return NO;
  32. }
  33. + (NSString *)calBase64Sha1WithData:(NSString *)data withSecret:(NSString *)key {
  34. NSData *secretData = [key dataUsingEncoding:NSUTF8StringEncoding];
  35. NSData *clearTextData = [data dataUsingEncoding:NSUTF8StringEncoding];
  36. uint8_t input[20];
  37. CCHmac(kCCHmacAlgSHA1, [secretData bytes], [secretData length], [clearTextData bytes], [clearTextData length], input);
  38. return [self calBase64WithData:input];
  39. }
  40. + (NSString*)calBase64WithData:(uint8_t *)data {
  41. static char b[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  42. NSInteger a = 20;
  43. NSMutableData* c = [NSMutableData dataWithLength:((a + 2) / 3) * 4];
  44. uint8_t* d = (uint8_t*)c.mutableBytes;
  45. NSInteger i;
  46. for (i=0; i < a; i += 3) {
  47. NSInteger e = 0;
  48. NSInteger j;
  49. for (j = i; j < (i + 3); j++) {
  50. e <<= 8;
  51. if (j < a) {
  52. e |= (0xFF & data[j]);
  53. }
  54. }
  55. NSInteger index = (i / 3) * 4;
  56. d[index + 0] = b[(e >> 18) & 0x3F];
  57. d[index + 1] = b[(e >> 12) & 0x3F];
  58. if ((i + 1) < a) {
  59. d[index + 2] = b[(e >> 6) & 0x3F];
  60. } else {
  61. d[index + 2] = '=';
  62. }
  63. if ((i + 2) < a) {
  64. d[index + 3] = b[(e >> 0) & 0x3F];
  65. } else {
  66. d[index + 3] = '=';
  67. }
  68. }
  69. NSString *result = [[NSString alloc] initWithData:c encoding:NSASCIIStringEncoding];
  70. return result;
  71. }
  72. + (NSString *)encodeURL:(NSString *)url {
  73. //保持和android处理方式一致,添加+ -> %20,* -> %2A,%7E -> ~, "%2F" -> /
  74. NSMutableString *output = [NSMutableString string];
  75. const unsigned char *source = (const unsigned char *)[url UTF8String];
  76. NSUInteger sourceLen = strlen((const char *)source);
  77. for (int i = 0; i < sourceLen; ++i) {
  78. const unsigned char thisChar = source[i];
  79. if (thisChar == ' ') {
  80. [output appendString:@"%20"];
  81. } else if (thisChar == '*') {
  82. [output appendString:@"%2A"];
  83. } else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||
  84. (thisChar >= 'a' && thisChar <= 'z') ||
  85. (thisChar >= 'A' && thisChar <= 'Z') ||
  86. (thisChar >= '0' && thisChar <= '9')) {
  87. [output appendFormat:@"%c", thisChar];
  88. } else {
  89. [output appendFormat:@"%%%02X", thisChar];
  90. }
  91. }
  92. NSString *encodeUrl = [output stringByReplacingOccurrencesOfString:@"%2F" withString:@"/"];
  93. encodeUrl = [encodeUrl stringByReplacingOccurrencesOfString:@"%7E" withString:@"~"];
  94. return encodeUrl;
  95. // 不要用系统urlencode 的方式,很多特殊字符都没有转化;
  96. // 详见:https://stackoverflow.com/questions/8088473/how-do-i-url-encode-a-string
  97. }
  98. + (NSData *)constructHttpBodyFromPartInfos:(NSArray *)partInfos {
  99. NSMutableString * body = [NSMutableString stringWithString:@"<CompleteMultipartUpload>\n"];
  100. [partInfos enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  101. if ([obj isKindOfClass:[OSSPartInfo class]]) {
  102. OSSPartInfo * thePart = obj;
  103. [body appendFormat:@"<Part>\n<PartNumber>%d</PartNumber>\n<ETag>%@</ETag>\n</Part>\n", thePart.partNum, thePart.eTag];
  104. }
  105. }];
  106. [body appendString:@"</CompleteMultipartUpload>\n"];
  107. OSSLogVerbose(@"constucted complete multipart upload body:\n%@", body);
  108. return [body dataUsingEncoding:NSUTF8StringEncoding];
  109. }
  110. + (NSData *)constructHttpBodyForDeleteMultipleObjects:(NSArray<NSString *> *)keys quiet:(BOOL)quiet {
  111. NSMutableString * body = [NSMutableString stringWithString:@"<Delete>\n"];
  112. [body appendFormat:@"<Quiet>%@</Quiet>\n",quiet?@"true":@"false"];
  113. [keys enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) {
  114. [body appendFormat:@"<Object>\n<Key>%@</Key>\n</Object>\n", key];
  115. }];
  116. [body appendString:@"</Delete>\n"];
  117. OSSLogVerbose(@"constucted delete multiple objects body:\n%@", body);
  118. return [body dataUsingEncoding:NSUTF8StringEncoding];
  119. }
  120. + (NSData *)constructHttpBodyForCreateBucketWithLocation:(NSString *)location {
  121. NSString * body = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  122. @"<CreateBucketConfiguration>\n"
  123. @"<LocationConstraint>%@</LocationConstraint>\n"
  124. @"</CreateBucketConfiguration>\n",
  125. location];
  126. OSSLogVerbose(@"constucted create bucket body:\n%@", body);
  127. return [body dataUsingEncoding:NSUTF8StringEncoding];
  128. }
  129. + (BOOL)validateBucketName:(NSString *)bucketName {
  130. if (bucketName == nil) {
  131. return false;
  132. }
  133. static NSRegularExpression *regEx;
  134. static dispatch_once_t onceToken;
  135. dispatch_once(&onceToken, ^{
  136. regEx = [[NSRegularExpression alloc] initWithPattern:@"^[a-z0-9][a-z0-9\\-]{1,61}[a-z0-9]$" options:NSRegularExpressionCaseInsensitive error:nil];
  137. });
  138. NSUInteger regExMatches = [regEx numberOfMatchesInString:bucketName options:0 range:NSMakeRange(0, [bucketName length])];
  139. return regExMatches != 0;
  140. }
  141. + (BOOL)validateObjectKey:(NSString *)objectKey {
  142. if (objectKey == nil) {
  143. return false;
  144. }
  145. if (objectKey.length <= 0 || objectKey.length > 1023) {
  146. return false;
  147. }
  148. if (![objectKey canBeConvertedToEncoding:NSUTF8StringEncoding]) {
  149. return false;
  150. }
  151. unichar firstChar = [objectKey characterAtIndex:0];
  152. if (firstChar == '/' || firstChar == '\\') {
  153. return false;
  154. }
  155. return true;
  156. }
  157. + (NSString *)getIpByHost:(NSString *)host {
  158. if ([self isNetworkDelegateState]) {
  159. OSSLogDebug(@"current network is delegate state");
  160. return host;
  161. }
  162. NSString * ip = [[OSSHttpdns sharedInstance] asynGetIpByHost:host];
  163. OSSLogDebug(@"resolved host %@ and get ip: %@", host, ip);
  164. return ip ? [[OSSIPv6Adapter getInstance] handleIpv4Address:ip] : host;
  165. }
  166. + (BOOL)isNetworkDelegateState {
  167. NSURL* URL = [[NSURL alloc] initWithString:@"https://m.aliyun.com"];
  168. NSDictionary *proxySettings = CFBridgingRelease(CFNetworkCopySystemProxySettings());
  169. NSArray *proxies = nil;
  170. proxies = CFBridgingRelease(CFNetworkCopyProxiesForURL((__bridge CFURLRef)URL,
  171. (__bridge CFDictionaryRef)proxySettings));
  172. if (proxies.count) {
  173. NSDictionary *settings = [proxies objectAtIndex:0];
  174. NSString* host = [settings objectForKey:(NSString *)kCFProxyHostNameKey];
  175. NSNumber* port = [settings objectForKey:(NSString *)kCFProxyPortNumberKey];
  176. if (host && port) {
  177. return YES;
  178. }
  179. }
  180. return NO;
  181. }
  182. + (BOOL)isOssOriginBucketHost:(NSString *)host {
  183. return [[host lowercaseString] hasSuffix:ALIYUN_HOST_SUFFIX] || [[host lowercaseString] hasSuffix:ALIYUN_OSS_TEST_ENDPOINT];
  184. }
  185. + (NSString *)base64Md5ForData:(NSData *)data {
  186. uint8_t * bytes = (uint8_t *)[[self dataMD5:data] bytes];
  187. return [self base64ForData:bytes length:CC_MD5_DIGEST_LENGTH];
  188. }
  189. + (NSString *)base64Md5ForFilePath:(NSString *)filePath {
  190. uint8_t * bytes = (uint8_t *)[[self fileMD5:filePath] bytes];
  191. return [self base64ForData:bytes length:CC_MD5_DIGEST_LENGTH];
  192. }
  193. + (NSString *)base64Md5ForFileURL:(NSURL *)fileURL {
  194. return [self base64Md5ForFilePath:[fileURL path]];
  195. }
  196. + (NSData *)dataMD5:(NSData *)data {
  197. if(data == nil) {
  198. return nil;
  199. }
  200. CC_MD5_CTX md5;
  201. CC_MD5_Init(&md5);
  202. for (int i = 0; i < data.length; i += CHUNK_SIZE) {
  203. NSData *subdata = nil;
  204. if (i <= ((long)data.length - CHUNK_SIZE)) {
  205. subdata = [data subdataWithRange:NSMakeRange(i, CHUNK_SIZE)];
  206. CC_MD5_Update(&md5, [subdata bytes], (CC_LONG)[subdata length]);
  207. } else {
  208. subdata = [data subdataWithRange:NSMakeRange(i, data.length - i)];
  209. CC_MD5_Update(&md5, [subdata bytes], (CC_LONG)[subdata length]);
  210. }
  211. }
  212. unsigned char digestResult[CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
  213. CC_MD5_Final(digestResult, &md5);
  214. return [NSData dataWithBytes:(const void *)digestResult length:CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
  215. }
  216. + (NSData *)fileMD5:(NSString*)path {
  217. NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
  218. if(handle == nil) {
  219. return nil;
  220. }
  221. CC_MD5_CTX md5;
  222. CC_MD5_Init(&md5);
  223. BOOL done = NO;
  224. while(!done) {
  225. @autoreleasepool{
  226. NSData* fileData = [handle readDataOfLength: CHUNK_SIZE];
  227. CC_MD5_Update(&md5, [fileData bytes], (CC_LONG)[fileData length]);
  228. if([fileData length] == 0) {
  229. done = YES;
  230. }
  231. }
  232. }
  233. if (@available(iOS 13.0, *)) {
  234. [handle closeAndReturnError:nil];
  235. } else {
  236. [handle closeFile];
  237. }
  238. unsigned char digestResult[CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
  239. CC_MD5_Final(digestResult, &md5);
  240. return [NSData dataWithBytes:(const void *)digestResult length:CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
  241. }
  242. + (NSData *)fileMD5:(NSString*)path error:(NSError **)error {
  243. NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
  244. if(handle == nil) {
  245. return nil;
  246. }
  247. CC_MD5_CTX md5;
  248. CC_MD5_Init(&md5);
  249. BOOL done = NO;
  250. while(!done) {
  251. @autoreleasepool{
  252. NSData *fileData;
  253. if (@available(iOS 13.0, *)) {
  254. fileData = [handle readDataUpToLength:CHUNK_SIZE error:error];
  255. } else {
  256. @try {
  257. fileData = [handle readDataOfLength: CHUNK_SIZE];
  258. } @catch(NSException *exception) {
  259. *error = [NSError errorWithDomain:OSSClientErrorDomain
  260. code:OSSClientErrorCodeFileCantRead
  261. userInfo:@{OSSErrorMessageTOKEN: [exception description]}];
  262. }
  263. }
  264. CC_MD5_Update(&md5, [fileData bytes], (CC_LONG)[fileData length]);
  265. if([fileData length] == 0) {
  266. done = YES;
  267. }
  268. }
  269. }
  270. if (@available(iOS 13.0, *)) {
  271. [handle closeAndReturnError:error];
  272. } else {
  273. [handle closeFile];
  274. }
  275. unsigned char digestResult[CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
  276. CC_MD5_Final(digestResult, &md5);
  277. return [NSData dataWithBytes:(const void *)digestResult length:CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
  278. }
  279. + (NSString *)convertMd5Bytes2String:(unsigned char *)md5Bytes {
  280. return [NSString stringWithFormat:
  281. @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
  282. md5Bytes[0], md5Bytes[1], md5Bytes[2], md5Bytes[3],
  283. md5Bytes[4], md5Bytes[5], md5Bytes[6], md5Bytes[7],
  284. md5Bytes[8], md5Bytes[9], md5Bytes[10], md5Bytes[11],
  285. md5Bytes[12], md5Bytes[13], md5Bytes[14], md5Bytes[15]
  286. ];
  287. }
  288. + (NSString *)convertMd5Bytes2StringWithData:(NSData *)data error:(NSError **)error {
  289. if (!data || [data length] == 0) {
  290. *error = [NSError errorWithDomain:OSSClientErrorDomain
  291. code:OSSClientErrorCodeInvalidArgument
  292. userInfo:@{OSSErrorMessageTOKEN: @"data is null or data length is 0"}];
  293. return nil;
  294. }
  295. NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
  296. [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
  297. unsigned char *dataBytes = (unsigned char*)bytes;
  298. for (NSInteger i = 0; i < byteRange.length; i++) {
  299. NSString *hexStr = [NSString stringWithFormat:@"%02X", dataBytes[i]];
  300. [string appendString:hexStr];
  301. }
  302. }];
  303. return string;
  304. }
  305. + (NSString *)dataMD5String:(NSData *)data error:(NSError **)error {
  306. data = [self dataMD5:data];
  307. return [self convertMd5Bytes2StringWithData:data error:error];
  308. }
  309. + (NSString *)fileMD5String:(NSString *)path error:(NSError **)error {
  310. BOOL isDirectory = NO;
  311. BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory];
  312. if (isDirectory || !isExist) {
  313. OSSLogWarn(@"a file doesn't exists at a specified path(%@)", path);
  314. return nil;
  315. }
  316. NSData *data = [self fileMD5:path error:error];
  317. return [self convertMd5Bytes2StringWithData:data error:error];
  318. }
  319. + (NSString *)dataMD5String:(NSData *)data {
  320. unsigned char * md5Bytes = (unsigned char *)[[self dataMD5:data] bytes];
  321. return [self convertMd5Bytes2String:md5Bytes];
  322. }
  323. + (NSString *)fileMD5String:(NSString *)path {
  324. BOOL isDirectory = NO;
  325. BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory];
  326. if (isDirectory || !isExist) {
  327. OSSLogWarn(@"a file doesn't exists at a specified path(%@)", path);
  328. return nil;
  329. }
  330. unsigned char * md5Bytes = (unsigned char *)[[self fileMD5:path] bytes];
  331. return [self convertMd5Bytes2String:md5Bytes];
  332. }
  333. + (NSString*)base64ForData:(uint8_t *)input length:(int32_t)length {
  334. if (input == nil) {
  335. return nil;
  336. }
  337. NSData * data = [NSData dataWithBytes:input length:length];
  338. return [data base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];
  339. }
  340. + (BOOL)isSubresource:(NSString *)param {
  341. /****************************************************************
  342. * define a constant array to contain all specified subresource */
  343. static NSArray * OSSSubResourceARRAY = nil;
  344. static dispatch_once_t onceToken;
  345. dispatch_once(&onceToken, ^{
  346. OSSSubResourceARRAY = @[
  347. @"acl", @"uploads", @"location", @"cors", @"logging", @"website", @"referer", @"lifecycle", @"delete", @"append",
  348. @"tagging", @"objectMeta", @"uploadId", @"partNumber", @"security-token", @"position", @"img", @"style",
  349. @"styleName", @"replication", @"replicationProgress", @"replicationLocation", @"cname", @"bucketInfo", @"comp",
  350. @"qos", @"live", @"status", @"vod", @"startTime", @"endTime", @"symlink", @"x-oss-process", @"response-content-type",
  351. @"response-content-language", @"response-expires", @"response-cache-control", @"response-content-disposition", @"response-content-encoding",@"restore"
  352. ];
  353. });
  354. /****************************************************************/
  355. return [OSSSubResourceARRAY containsObject:param];
  356. }
  357. + (NSString *)populateSubresourceStringFromParameter:(NSDictionary *)parameters {
  358. NSMutableArray * subresource = [NSMutableArray new];
  359. [parameters enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
  360. NSString * keyStr = [key oss_trim];
  361. NSString * valueStr = [obj oss_trim];
  362. if (![OSSUtil isSubresource:keyStr]) {
  363. return;
  364. }
  365. if ([valueStr length] == 0) {
  366. [subresource addObject:keyStr];
  367. } else {
  368. [subresource addObject:[NSString stringWithFormat:@"%@=%@", keyStr, valueStr]];
  369. }
  370. }];
  371. NSArray * sortedSubResource = [subresource sortedArrayUsingSelector:@selector(compare:)]; // 升序
  372. return [sortedSubResource componentsJoinedByString:@"&"];
  373. }
  374. + (NSString *)populateQueryStringFromParameter:(NSDictionary *)parameters {
  375. NSMutableArray * subresource = [NSMutableArray new];
  376. [parameters enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
  377. NSString * keyStr = [OSSUtil encodeURL:[key oss_trim]];
  378. NSString * valueStr = [OSSUtil encodeURL:[obj oss_trim]];
  379. if ([valueStr length] == 0) {
  380. [subresource addObject:keyStr];
  381. } else {
  382. [subresource addObject:[NSString stringWithFormat:@"%@=%@", keyStr, valueStr]];
  383. }
  384. }];
  385. return [subresource componentsJoinedByString:@"&"];
  386. }
  387. + (NSString *)sign:(NSString *)content withToken:(OSSFederationToken *)token {
  388. NSString * sign = [OSSUtil calBase64Sha1WithData:content withSecret:token.tSecretKey];
  389. return [NSString stringWithFormat:@"OSS %@:%@", token.tAccessKey, sign];
  390. }
  391. + (NSString *)getRelativePath:(NSString *)fullPath {
  392. NSString * rootPath = NSHomeDirectory();
  393. return [fullPath stringByReplacingOccurrencesOfString:rootPath withString:@""];
  394. }
  395. + (NSString *)detemineMimeTypeForFilePath:(NSString *)filePath uploadName:(NSString *)uploadName {
  396. static dispatch_once_t onceToken;
  397. static NSDictionary * mimeMap;
  398. dispatch_once(&onceToken, ^{
  399. mimeMap = @{
  400. @"aw": @"application/applixware",
  401. @"atom": @"application/atom+xml",
  402. @"atomcat": @"application/atomcat+xml",
  403. @"atomsvc": @"application/atomsvc+xml",
  404. @"ccxml": @"application/ccxml+xml",
  405. @"cdmia": @"application/cdmi-capability",
  406. @"cdmic": @"application/cdmi-container",
  407. @"cdmid": @"application/cdmi-domain",
  408. @"cdmio": @"application/cdmi-object",
  409. @"cdmiq": @"application/cdmi-queue",
  410. @"cu": @"application/cu-seeme",
  411. @"davmount": @"application/davmount+xml",
  412. @"dssc": @"application/dssc+der",
  413. @"xdssc": @"application/dssc+xml",
  414. @"es": @"application/ecmascript",
  415. @"emma": @"application/emma+xml",
  416. @"epub": @"application/epub+zip",
  417. @"exi": @"application/exi",
  418. @"pfr": @"application/font-tdpfr",
  419. @"stk": @"application/hyperstudio",
  420. @"ipfix": @"application/ipfix",
  421. @"jar": @"application/java-archive",
  422. @"ser": @"application/java-serialized-object",
  423. @"class": @"application/java-vm",
  424. @"js": @"application/javascript",
  425. @"json": @"application/json",
  426. @"hqx": @"application/mac-binhex40",
  427. @"cpt": @"application/mac-compactpro",
  428. @"mads": @"application/mads+xml",
  429. @"mrc": @"application/marc",
  430. @"mrcx": @"application/marcxml+xml",
  431. @"ma": @"application/mathematica",
  432. @"mathml": @"application/mathml+xml",
  433. @"mbox": @"application/mbox",
  434. @"mscml": @"application/mediaservercontrol+xml",
  435. @"meta4": @"application/metalink4+xml",
  436. @"mets": @"application/mets+xml",
  437. @"mods": @"application/mods+xml",
  438. @"m21": @"application/mp21",
  439. @"mp4": @"video/mp4",
  440. @"doc": @"application/msword",
  441. @"mxf": @"application/mxf",
  442. @"bin": @"application/octet-stream",
  443. @"oda": @"application/oda",
  444. @"opf": @"application/oebps-package+xml",
  445. @"ogx": @"application/ogg",
  446. @"onetoc": @"application/onenote",
  447. @"xer": @"application/patch-ops-error+xml",
  448. @"pdf": @"application/pdf",
  449. @"pgp": @"application/pgp-signature",
  450. @"prf": @"application/pics-rules",
  451. @"p10": @"application/pkcs10",
  452. @"p7m": @"application/pkcs7-mime",
  453. @"p7s": @"application/pkcs7-signature",
  454. @"p8": @"application/pkcs8",
  455. @"ac": @"application/pkix-attr-cert",
  456. @"cer": @"application/pkix-cert",
  457. @"crl": @"application/pkix-crl",
  458. @"pkipath": @"application/pkix-pkipath",
  459. @"pki": @"application/pkixcmp",
  460. @"pls": @"application/pls+xml",
  461. @"ai": @"application/postscript",
  462. @"cww": @"application/prs.cww",
  463. @"pskcxml": @"application/pskc+xml",
  464. @"rdf": @"application/rdf+xml",
  465. @"rif": @"application/reginfo+xml",
  466. @"rnc": @"application/relax-ng-compact-syntax",
  467. @"rl": @"application/resource-lists+xml",
  468. @"rld": @"application/resource-lists-diff+xml",
  469. @"rs": @"application/rls-services+xml",
  470. @"rsd": @"application/rsd+xml",
  471. @"rss": @"application/rss+xml",
  472. @"rtf": @"application/rtf",
  473. @"sbml": @"application/sbml+xml",
  474. @"scq": @"application/scvp-cv-request",
  475. @"scs": @"application/scvp-cv-response",
  476. @"spq": @"application/scvp-vp-request",
  477. @"spp": @"application/scvp-vp-response",
  478. @"sdp": @"application/sdp",
  479. @"setpay": @"application/set-payment-initiation",
  480. @"setreg": @"application/set-registration-initiation",
  481. @"shf": @"application/shf+xml",
  482. @"smi": @"application/smil+xml",
  483. @"rq": @"application/sparql-query",
  484. @"srx": @"application/sparql-results+xml",
  485. @"gram": @"application/srgs",
  486. @"grxml": @"application/srgs+xml",
  487. @"sru": @"application/sru+xml",
  488. @"ssml": @"application/ssml+xml",
  489. @"tei": @"application/tei+xml",
  490. @"tfi": @"application/thraud+xml",
  491. @"tsd": @"application/timestamped-data",
  492. @"plb": @"application/vnd.3gpp.pic-bw-large",
  493. @"psb": @"application/vnd.3gpp.pic-bw-small",
  494. @"pvb": @"application/vnd.3gpp.pic-bw-var",
  495. @"tcap": @"application/vnd.3gpp2.tcap",
  496. @"pwn": @"application/vnd.3m.post-it-notes",
  497. @"aso": @"application/vnd.accpac.simply.aso",
  498. @"imp": @"application/vnd.accpac.simply.imp",
  499. @"acu": @"application/vnd.acucobol",
  500. @"atc": @"application/vnd.acucorp",
  501. @"air": @"application/vnd.adobe.air-application-installer-package+zip",
  502. @"fxp": @"application/vnd.adobe.fxp",
  503. @"xdp": @"application/vnd.adobe.xdp+xml",
  504. @"xfdf": @"application/vnd.adobe.xfdf",
  505. @"ahead": @"application/vnd.ahead.space",
  506. @"azf": @"application/vnd.airzip.filesecure.azf",
  507. @"azs": @"application/vnd.airzip.filesecure.azs",
  508. @"azw": @"application/vnd.amazon.ebook",
  509. @"acc": @"application/vnd.americandynamics.acc",
  510. @"ami": @"application/vnd.amiga.ami",
  511. @"apk": @"application/vnd.android.package-archive",
  512. @"cii": @"application/vnd.anser-web-certificate-issue-initiation",
  513. @"fti": @"application/vnd.anser-web-funds-transfer-initiation",
  514. @"atx": @"application/vnd.antix.game-component",
  515. @"mpkg": @"application/vnd.apple.installer+xml",
  516. @"m3u8": @"application/vnd.apple.mpegurl",
  517. @"swi": @"application/vnd.aristanetworks.swi",
  518. @"aep": @"application/vnd.audiograph",
  519. @"mpm": @"application/vnd.blueice.multipass",
  520. @"bmi": @"application/vnd.bmi",
  521. @"rep": @"application/vnd.businessobjects",
  522. @"cdxml": @"application/vnd.chemdraw+xml",
  523. @"mmd": @"application/vnd.chipnuts.karaoke-mmd",
  524. @"cdy": @"application/vnd.cinderella",
  525. @"cla": @"application/vnd.claymore",
  526. @"rp9": @"application/vnd.cloanto.rp9",
  527. @"c4g": @"application/vnd.clonk.c4group",
  528. @"c11amc": @"application/vnd.cluetrust.cartomobile-config",
  529. @"c11amz": @"application/vnd.cluetrust.cartomobile-config-pkg",
  530. @"csp": @"application/vnd.commonspace",
  531. @"cdbcmsg": @"application/vnd.contact.cmsg",
  532. @"cmc": @"application/vnd.cosmocaller",
  533. @"clkx": @"application/vnd.crick.clicker",
  534. @"clkk": @"application/vnd.crick.clicker.keyboard",
  535. @"clkp": @"application/vnd.crick.clicker.palette",
  536. @"clkt": @"application/vnd.crick.clicker.template",
  537. @"clkw": @"application/vnd.crick.clicker.wordbank",
  538. @"wbs": @"application/vnd.criticaltools.wbs+xml",
  539. @"pml": @"application/vnd.ctc-posml",
  540. @"ppd": @"application/vnd.cups-ppd",
  541. @"car": @"application/vnd.curl.car",
  542. @"pcurl": @"application/vnd.curl.pcurl",
  543. @"rdz": @"application/vnd.data-vision.rdz",
  544. @"fe_launch": @"application/vnd.denovo.fcselayout-link",
  545. @"dna": @"application/vnd.dna",
  546. @"mlp": @"application/vnd.dolby.mlp",
  547. @"dpg": @"application/vnd.dpgraph",
  548. @"dfac": @"application/vnd.dreamfactory",
  549. @"ait": @"application/vnd.dvb.ait",
  550. @"svc": @"application/vnd.dvb.service",
  551. @"geo": @"application/vnd.dynageo",
  552. @"mag": @"application/vnd.ecowin.chart",
  553. @"nml": @"application/vnd.enliven",
  554. @"esf": @"application/vnd.epson.esf",
  555. @"msf": @"application/vnd.epson.msf",
  556. @"qam": @"application/vnd.epson.quickanime",
  557. @"slt": @"application/vnd.epson.salt",
  558. @"ssf": @"application/vnd.epson.ssf",
  559. @"es3": @"application/vnd.eszigno3+xml",
  560. @"ez2": @"application/vnd.ezpix-album",
  561. @"ez3": @"application/vnd.ezpix-package",
  562. @"fdf": @"application/vnd.fdf",
  563. @"seed": @"application/vnd.fdsn.seed",
  564. @"gph": @"application/vnd.flographit",
  565. @"ftc": @"application/vnd.fluxtime.clip",
  566. @"fm": @"application/vnd.framemaker",
  567. @"fnc": @"application/vnd.frogans.fnc",
  568. @"ltf": @"application/vnd.frogans.ltf",
  569. @"fsc": @"application/vnd.fsc.weblaunch",
  570. @"oas": @"application/vnd.fujitsu.oasys",
  571. @"oa2": @"application/vnd.fujitsu.oasys2",
  572. @"oa3": @"application/vnd.fujitsu.oasys3",
  573. @"fg5": @"application/vnd.fujitsu.oasysgp",
  574. @"bh2": @"application/vnd.fujitsu.oasysprs",
  575. @"ddd": @"application/vnd.fujixerox.ddd",
  576. @"xdw": @"application/vnd.fujixerox.docuworks",
  577. @"xbd": @"application/vnd.fujixerox.docuworks.binder",
  578. @"fzs": @"application/vnd.fuzzysheet",
  579. @"txd": @"application/vnd.genomatix.tuxedo",
  580. @"ggb": @"application/vnd.geogebra.file",
  581. @"ggt": @"application/vnd.geogebra.tool",
  582. @"gex": @"application/vnd.geometry-explorer",
  583. @"gxt": @"application/vnd.geonext",
  584. @"g2w": @"application/vnd.geoplan",
  585. @"g3w": @"application/vnd.geospace",
  586. @"gmx": @"application/vnd.gmx",
  587. @"kml": @"application/vnd.google-earth.kml+xml",
  588. @"kmz": @"application/vnd.google-earth.kmz",
  589. @"gqf": @"application/vnd.grafeq",
  590. @"gac": @"application/vnd.groove-account",
  591. @"ghf": @"application/vnd.groove-help",
  592. @"gim": @"application/vnd.groove-identity-message",
  593. @"grv": @"application/vnd.groove-injector",
  594. @"gtm": @"application/vnd.groove-tool-message",
  595. @"tpl": @"application/vnd.groove-tool-template",
  596. @"vcg": @"application/vnd.groove-vcard",
  597. @"hal": @"application/vnd.hal+xml",
  598. @"zmm": @"application/vnd.handheld-entertainment+xml",
  599. @"hbci": @"application/vnd.hbci",
  600. @"les": @"application/vnd.hhe.lesson-player",
  601. @"hpgl": @"application/vnd.hp-hpgl",
  602. @"hpid": @"application/vnd.hp-hpid",
  603. @"hps": @"application/vnd.hp-hps",
  604. @"jlt": @"application/vnd.hp-jlyt",
  605. @"pcl": @"application/vnd.hp-pcl",
  606. @"pclxl": @"application/vnd.hp-pclxl",
  607. @"sfd-hdstx": @"application/vnd.hydrostatix.sof-data",
  608. @"x3d": @"application/vnd.hzn-3d-crossword",
  609. @"mpy": @"application/vnd.ibm.minipay",
  610. @"afp": @"application/vnd.ibm.modcap",
  611. @"irm": @"application/vnd.ibm.rights-management",
  612. @"sc": @"application/vnd.ibm.secure-container",
  613. @"icc": @"application/vnd.iccprofile",
  614. @"igl": @"application/vnd.igloader",
  615. @"ivp": @"application/vnd.immervision-ivp",
  616. @"ivu": @"application/vnd.immervision-ivu",
  617. @"igm": @"application/vnd.insors.igm",
  618. @"xpw": @"application/vnd.intercon.formnet",
  619. @"i2g": @"application/vnd.intergeo",
  620. @"qbo": @"application/vnd.intu.qbo",
  621. @"qfx": @"application/vnd.intu.qfx",
  622. @"rcprofile": @"application/vnd.ipunplugged.rcprofile",
  623. @"irp": @"application/vnd.irepository.package+xml",
  624. @"xpr": @"application/vnd.is-xpr",
  625. @"fcs": @"application/vnd.isac.fcs",
  626. @"jam": @"application/vnd.jam",
  627. @"rms": @"application/vnd.jcp.javame.midlet-rms",
  628. @"jisp": @"application/vnd.jisp",
  629. @"joda": @"application/vnd.joost.joda-archive",
  630. @"ktz": @"application/vnd.kahootz",
  631. @"karbon": @"application/vnd.kde.karbon",
  632. @"chrt": @"application/vnd.kde.kchart",
  633. @"kfo": @"application/vnd.kde.kformula",
  634. @"flw": @"application/vnd.kde.kivio",
  635. @"kon": @"application/vnd.kde.kontour",
  636. @"kpr": @"application/vnd.kde.kpresenter",
  637. @"ksp": @"application/vnd.kde.kspread",
  638. @"kwd": @"application/vnd.kde.kword",
  639. @"htke": @"application/vnd.kenameaapp",
  640. @"kia": @"application/vnd.kidspiration",
  641. @"kne": @"application/vnd.kinar",
  642. @"skp": @"application/vnd.koan",
  643. @"sse": @"application/vnd.kodak-descriptor",
  644. @"lasxml": @"application/vnd.las.las+xml",
  645. @"lbd": @"application/vnd.llamagraphics.life-balance.desktop",
  646. @"lbe": @"application/vnd.llamagraphics.life-balance.exchange+xml",
  647. @"123": @"application/vnd.lotus-1-2-3",
  648. @"apr": @"application/vnd.lotus-approach",
  649. @"pre": @"application/vnd.lotus-freelance",
  650. @"nsf": @"application/vnd.lotus-notes",
  651. @"org": @"application/vnd.lotus-organizer",
  652. @"scm": @"application/vnd.lotus-screencam",
  653. @"lwp": @"application/vnd.lotus-wordpro",
  654. @"portpkg": @"application/vnd.macports.portpkg",
  655. @"mcd": @"application/vnd.mcd",
  656. @"mc1": @"application/vnd.medcalcdata",
  657. @"cdkey": @"application/vnd.mediastation.cdkey",
  658. @"mwf": @"application/vnd.mfer",
  659. @"mfm": @"application/vnd.mfmp",
  660. @"flo": @"application/vnd.micrografx.flo",
  661. @"igx": @"application/vnd.micrografx.igx",
  662. @"mif": @"application/vnd.mif",
  663. @"daf": @"application/vnd.mobius.daf",
  664. @"dis": @"application/vnd.mobius.dis",
  665. @"mbk": @"application/vnd.mobius.mbk",
  666. @"mqy": @"application/vnd.mobius.mqy",
  667. @"msl": @"application/vnd.mobius.msl",
  668. @"plc": @"application/vnd.mobius.plc",
  669. @"txf": @"application/vnd.mobius.txf",
  670. @"mpn": @"application/vnd.mophun.application",
  671. @"mpc": @"application/vnd.mophun.certificate",
  672. @"xul": @"application/vnd.mozilla.xul+xml",
  673. @"cil": @"application/vnd.ms-artgalry",
  674. @"cab": @"application/vnd.ms-cab-compressed",
  675. @"xls": @"application/vnd.ms-excel",
  676. @"xlam": @"application/vnd.ms-excel.addin.macroenabled.12",
  677. @"xlsb": @"application/vnd.ms-excel.sheet.binary.macroenabled.12",
  678. @"xlsm": @"application/vnd.ms-excel.sheet.macroenabled.12",
  679. @"xltm": @"application/vnd.ms-excel.template.macroenabled.12",
  680. @"eot": @"application/vnd.ms-fontobject",
  681. @"chm": @"application/vnd.ms-htmlhelp",
  682. @"ims": @"application/vnd.ms-ims",
  683. @"lrm": @"application/vnd.ms-lrm",
  684. @"thmx": @"application/vnd.ms-officetheme",
  685. @"cat": @"application/vnd.ms-pki.seccat",
  686. @"stl": @"application/vnd.ms-pki.stl",
  687. @"ppt": @"application/vnd.ms-powerpoint",
  688. @"ppam": @"application/vnd.ms-powerpoint.addin.macroenabled.12",
  689. @"pptm": @"application/vnd.ms-powerpoint.presentation.macroenabled.12",
  690. @"sldm": @"application/vnd.ms-powerpoint.slide.macroenabled.12",
  691. @"ppsm": @"application/vnd.ms-powerpoint.slideshow.macroenabled.12",
  692. @"potm": @"application/vnd.ms-powerpoint.template.macroenabled.12",
  693. @"mpp": @"application/vnd.ms-project",
  694. @"docm": @"application/vnd.ms-word.document.macroenabled.12",
  695. @"dotm": @"application/vnd.ms-word.template.macroenabled.12",
  696. @"wps": @"application/vnd.ms-works",
  697. @"wpl": @"application/vnd.ms-wpl",
  698. @"xps": @"application/vnd.ms-xpsdocument",
  699. @"mseq": @"application/vnd.mseq",
  700. @"mus": @"application/vnd.musician",
  701. @"msty": @"application/vnd.muvee.style",
  702. @"nlu": @"application/vnd.neurolanguage.nlu",
  703. @"nnd": @"application/vnd.noblenet-directory",
  704. @"nns": @"application/vnd.noblenet-sealer",
  705. @"nnw": @"application/vnd.noblenet-web",
  706. @"ngdat": @"application/vnd.nokia.n-gage.data",
  707. @"n-gage": @"application/vnd.nokia.n-gage.symbian.install",
  708. @"rpst": @"application/vnd.nokia.radio-preset",
  709. @"rpss": @"application/vnd.nokia.radio-presets",
  710. @"edm": @"application/vnd.novadigm.edm",
  711. @"edx": @"application/vnd.novadigm.edx",
  712. @"ext": @"application/vnd.novadigm.ext",
  713. @"odc": @"application/vnd.oasis.opendocument.chart",
  714. @"otc": @"application/vnd.oasis.opendocument.chart-template",
  715. @"odb": @"application/vnd.oasis.opendocument.database",
  716. @"odf": @"application/vnd.oasis.opendocument.formula",
  717. @"odft": @"application/vnd.oasis.opendocument.formula-template",
  718. @"odg": @"application/vnd.oasis.opendocument.graphics",
  719. @"otg": @"application/vnd.oasis.opendocument.graphics-template",
  720. @"odi": @"application/vnd.oasis.opendocument.image",
  721. @"oti": @"application/vnd.oasis.opendocument.image-template",
  722. @"odp": @"application/vnd.oasis.opendocument.presentation",
  723. @"otp": @"application/vnd.oasis.opendocument.presentation-template",
  724. @"ods": @"application/vnd.oasis.opendocument.spreadsheet",
  725. @"ots": @"application/vnd.oasis.opendocument.spreadsheet-template",
  726. @"odt": @"application/vnd.oasis.opendocument.text",
  727. @"odm": @"application/vnd.oasis.opendocument.text-master",
  728. @"ott": @"application/vnd.oasis.opendocument.text-template",
  729. @"oth": @"application/vnd.oasis.opendocument.text-web",
  730. @"xo": @"application/vnd.olpc-sugar",
  731. @"dd2": @"application/vnd.oma.dd2+xml",
  732. @"oxt": @"application/vnd.openofficeorg.extension",
  733. @"pptx": @"application/vnd.openxmlformats-officedocument.presentationml.presentation",
  734. @"sldx": @"application/vnd.openxmlformats-officedocument.presentationml.slide",
  735. @"ppsx": @"application/vnd.openxmlformats-officedocument.presentationml.slideshow",
  736. @"potx": @"application/vnd.openxmlformats-officedocument.presentationml.template",
  737. @"xlsx": @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  738. @"xltx": @"application/vnd.openxmlformats-officedocument.spreadsheetml.template",
  739. @"docx": @"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  740. @"dotx": @"application/vnd.openxmlformats-officedocument.wordprocessingml.template",
  741. @"mgp": @"application/vnd.osgeo.mapguide.package",
  742. @"dp": @"application/vnd.osgi.dp",
  743. @"pdb": @"application/vnd.palm",
  744. @"paw": @"application/vnd.pawaafile",
  745. @"str": @"application/vnd.pg.format",
  746. @"ei6": @"application/vnd.pg.osasli",
  747. @"efif": @"application/vnd.picsel",
  748. @"wg": @"application/vnd.pmi.widget",
  749. @"plf": @"application/vnd.pocketlearn",
  750. @"pbd": @"application/vnd.powerbuilder6",
  751. @"box": @"application/vnd.previewsystems.box",
  752. @"mgz": @"application/vnd.proteus.magazine",
  753. @"qps": @"application/vnd.publishare-delta-tree",
  754. @"ptid": @"application/vnd.pvi.ptid1",
  755. @"qxd": @"application/vnd.quark.quarkxpress",
  756. @"bed": @"application/vnd.realvnc.bed",
  757. @"mxl": @"application/vnd.recordare.musicxml",
  758. @"musicxml": @"application/vnd.recordare.musicxml+xml",
  759. @"cryptonote": @"application/vnd.rig.cryptonote",
  760. @"cod": @"application/vnd.rim.cod",
  761. @"rm": @"application/vnd.rn-realmedia",
  762. @"link66": @"application/vnd.route66.link66+xml",
  763. @"st": @"application/vnd.sailingtracker.track",
  764. @"see": @"application/vnd.seemail",
  765. @"sema": @"application/vnd.sema",
  766. @"semd": @"application/vnd.semd",
  767. @"semf": @"application/vnd.semf",
  768. @"ifm": @"application/vnd.shana.informed.formdata",
  769. @"itp": @"application/vnd.shana.informed.formtemplate",
  770. @"iif": @"application/vnd.shana.informed.interchange",
  771. @"ipk": @"application/vnd.shana.informed.package",
  772. @"twd": @"application/vnd.simtech-mindmapper",
  773. @"mmf": @"application/vnd.smaf",
  774. @"teacher": @"application/vnd.smart.teacher",
  775. @"sdkm": @"application/vnd.solent.sdkm+xml",
  776. @"dxp": @"application/vnd.spotfire.dxp",
  777. @"sfs": @"application/vnd.spotfire.sfs",
  778. @"sdc": @"application/vnd.stardivision.calc",
  779. @"sda": @"application/vnd.stardivision.draw",
  780. @"sdd": @"application/vnd.stardivision.impress",
  781. @"smf": @"application/vnd.stardivision.math",
  782. @"sdw": @"application/vnd.stardivision.writer",
  783. @"sgl": @"application/vnd.stardivision.writer-global",
  784. @"sm": @"application/vnd.stepmania.stepchart",
  785. @"sxc": @"application/vnd.sun.xml.calc",
  786. @"stc": @"application/vnd.sun.xml.calc.template",
  787. @"sxd": @"application/vnd.sun.xml.draw",
  788. @"std": @"application/vnd.sun.xml.draw.template",
  789. @"sxi": @"application/vnd.sun.xml.impress",
  790. @"sti": @"application/vnd.sun.xml.impress.template",
  791. @"sxm": @"application/vnd.sun.xml.math",
  792. @"sxw": @"application/vnd.sun.xml.writer",
  793. @"sxg": @"application/vnd.sun.xml.writer.global",
  794. @"stw": @"application/vnd.sun.xml.writer.template",
  795. @"sus": @"application/vnd.sus-calendar",
  796. @"svd": @"application/vnd.svd",
  797. @"sis": @"application/vnd.symbian.install",
  798. @"xsm": @"application/vnd.syncml+xml",
  799. @"bdm": @"application/vnd.syncml.dm+wbxml",
  800. @"xdm": @"application/vnd.syncml.dm+xml",
  801. @"tao": @"application/vnd.tao.intent-module-archive",
  802. @"tmo": @"application/vnd.tmobile-livetv",
  803. @"tpt": @"application/vnd.trid.tpt",
  804. @"mxs": @"application/vnd.triscape.mxs",
  805. @"tra": @"application/vnd.trueapp",
  806. @"ufd": @"application/vnd.ufdl",
  807. @"utz": @"application/vnd.uiq.theme",
  808. @"umj": @"application/vnd.umajin",
  809. @"unityweb": @"application/vnd.unity",
  810. @"uoml": @"application/vnd.uoml+xml",
  811. @"vcx": @"application/vnd.vcx",
  812. @"vsd": @"application/vnd.visio",
  813. @"vis": @"application/vnd.visionary",
  814. @"vsf": @"application/vnd.vsf",
  815. @"wbxml": @"application/vnd.wap.wbxml",
  816. @"wmlc": @"application/vnd.wap.wmlc",
  817. @"wmlsc": @"application/vnd.wap.wmlscriptc",
  818. @"wtb": @"application/vnd.webturbo",
  819. @"nbp": @"application/vnd.wolfram.player",
  820. @"wpd": @"application/vnd.wordperfect",
  821. @"wqd": @"application/vnd.wqd",
  822. @"stf": @"application/vnd.wt.stf",
  823. @"xar": @"application/vnd.xara",
  824. @"xfdl": @"application/vnd.xfdl",
  825. @"hvd": @"application/vnd.yamaha.hv-dic",
  826. @"hvs": @"application/vnd.yamaha.hv-script",
  827. @"hvp": @"application/vnd.yamaha.hv-voice",
  828. @"osf": @"application/vnd.yamaha.openscoreformat",
  829. @"osfpvg": @"application/vnd.yamaha.openscoreformat.osfpvg+xml",
  830. @"saf": @"application/vnd.yamaha.smaf-audio",
  831. @"spf": @"application/vnd.yamaha.smaf-phrase",
  832. @"cmp": @"application/vnd.yellowriver-custom-menu",
  833. @"zir": @"application/vnd.zul",
  834. @"zaz": @"application/vnd.zzazz.deck+xml",
  835. @"vxml": @"application/voicexml+xml",
  836. @"wgt": @"application/widget",
  837. @"hlp": @"application/winhlp",
  838. @"wsdl": @"application/wsdl+xml",
  839. @"wspolicy": @"application/wspolicy+xml",
  840. @"7z": @"application/x-7z-compressed",
  841. @"abw": @"application/x-abiword",
  842. @"ace": @"application/x-ace-compressed",
  843. @"aab": @"application/x-authorware-bin",
  844. @"aam": @"application/x-authorware-map",
  845. @"aas": @"application/x-authorware-seg",
  846. @"bcpio": @"application/x-bcpio",
  847. @"torrent": @"application/x-bittorrent",
  848. @"bz": @"application/x-bzip",
  849. @"bz2": @"application/x-bzip2",
  850. @"vcd": @"application/x-cdlink",
  851. @"chat": @"application/x-chat",
  852. @"pgn": @"application/x-chess-pgn",
  853. @"cpio": @"application/x-cpio",
  854. @"csh": @"application/x-csh",
  855. @"deb": @"application/x-debian-package",
  856. @"dir": @"application/x-director",
  857. @"wad": @"application/x-doom",
  858. @"ncx": @"application/x-dtbncx+xml",
  859. @"dtb": @"application/x-dtbook+xml",
  860. @"res": @"application/x-dtbresource+xml",
  861. @"dvi": @"application/x-dvi",
  862. @"bdf": @"application/x-font-bdf",
  863. @"gsf": @"application/x-font-ghostscript",
  864. @"psf": @"application/x-font-linux-psf",
  865. @"otf": @"application/x-font-otf",
  866. @"pcf": @"application/x-font-pcf",
  867. @"snf": @"application/x-font-snf",
  868. @"ttf": @"application/x-font-ttf",
  869. @"pfa": @"application/x-font-type1",
  870. @"woff": @"application/x-font-woff",
  871. @"spl": @"application/x-futuresplash",
  872. @"gnumeric": @"application/x-gnumeric",
  873. @"gtar": @"application/x-gtar",
  874. @"hdf": @"application/x-hdf",
  875. @"jnlp": @"application/x-java-jnlp-file",
  876. @"latex": @"application/x-latex",
  877. @"prc": @"application/x-mobipocket-ebook",
  878. @"application": @"application/x-ms-application",
  879. @"wmd": @"application/x-ms-wmd",
  880. @"wmz": @"application/x-ms-wmz",
  881. @"xbap": @"application/x-ms-xbap",
  882. @"mdb": @"application/x-msaccess",
  883. @"obd": @"application/x-msbinder",
  884. @"crd": @"application/x-mscardfile",
  885. @"clp": @"application/x-msclip",
  886. @"exe": @"application/x-msdownload",
  887. @"mvb": @"application/x-msmediaview",
  888. @"wmf": @"application/x-msmetafile",
  889. @"mny": @"application/x-msmoney",
  890. @"pub": @"application/x-mspublisher",
  891. @"scd": @"application/x-msschedule",
  892. @"trm": @"application/x-msterminal",
  893. @"wri": @"application/x-mswrite",
  894. @"nc": @"application/x-netcdf",
  895. @"p12": @"application/x-pkcs12",
  896. @"p7b": @"application/x-pkcs7-certificates",
  897. @"p7r": @"application/x-pkcs7-certreqresp",
  898. @"rar": @"application/x-rar-compressed",
  899. @"sh": @"application/x-sh",
  900. @"shar": @"application/x-shar",
  901. @"swf": @"application/x-shockwave-flash",
  902. @"xap": @"application/x-silverlight-app",
  903. @"sit": @"application/x-stuffit",
  904. @"sitx": @"application/x-stuffitx",
  905. @"sv4cpio": @"application/x-sv4cpio",
  906. @"sv4crc": @"application/x-sv4crc",
  907. @"tar": @"application/x-tar",
  908. @"tcl": @"application/x-tcl",
  909. @"tex": @"application/x-tex",
  910. @"tfm": @"application/x-tex-tfm",
  911. @"texinfo": @"application/x-texinfo",
  912. @"ustar": @"application/x-ustar",
  913. @"src": @"application/x-wais-source",
  914. @"der": @"application/x-x509-ca-cert",
  915. @"fig": @"application/x-xfig",
  916. @"xpi": @"application/x-xpinstall",
  917. @"xdf": @"application/xcap-diff+xml",
  918. @"xenc": @"application/xenc+xml",
  919. @"xhtml": @"application/xhtml+xml",
  920. @"xml": @"application/xml",
  921. @"dtd": @"application/xml-dtd",
  922. @"xop": @"application/xop+xml",
  923. @"xslt": @"application/xslt+xml",
  924. @"xspf": @"application/xspf+xml",
  925. @"mxml": @"application/xv+xml",
  926. @"yang": @"application/yang",
  927. @"yin": @"application/yin+xml",
  928. @"zip": @"application/zip",
  929. @"adp": @"audio/adpcm",
  930. @"au": @"audio/basic",
  931. @"mid": @"audio/midi",
  932. @"mp4a": @"audio/mp4",
  933. @"mpga": @"audio/mpeg",
  934. @"oga": @"audio/ogg",
  935. @"uva": @"audio/vnd.dece.audio",
  936. @"eol": @"audio/vnd.digital-winds",
  937. @"dra": @"audio/vnd.dra",
  938. @"dts": @"audio/vnd.dts",
  939. @"dtshd": @"audio/vnd.dts.hd",
  940. @"lvp": @"audio/vnd.lucent.voice",
  941. @"pya": @"audio/vnd.ms-playready.media.pya",
  942. @"ecelp4800": @"audio/vnd.nuera.ecelp4800",
  943. @"ecelp7470": @"audio/vnd.nuera.ecelp7470",
  944. @"ecelp9600": @"audio/vnd.nuera.ecelp9600",
  945. @"rip": @"audio/vnd.rip",
  946. @"weba": @"audio/webm",
  947. @"aac": @"audio/x-aac",
  948. @"aif": @"audio/x-aiff",
  949. @"m3u": @"audio/x-mpegurl",
  950. @"wax": @"audio/x-ms-wax",
  951. @"wma": @"audio/x-ms-wma",
  952. @"ram": @"audio/x-pn-realaudio",
  953. @"rmp": @"audio/x-pn-realaudio-plugin",
  954. @"wav": @"audio/x-wav",
  955. @"cdx": @"chemical/x-cdx",
  956. @"cif": @"chemical/x-cif",
  957. @"cmdf": @"chemical/x-cmdf",
  958. @"cml": @"chemical/x-cml",
  959. @"csml": @"chemical/x-csml",
  960. @"xyz": @"chemical/x-xyz",
  961. @"bmp": @"image/bmp",
  962. @"cgm": @"image/cgm",
  963. @"g3": @"image/g3fax",
  964. @"gif": @"image/gif",
  965. @"ief": @"image/ief",
  966. @"jpeg": @"image/jpeg",
  967. @"jpg" : @"image/jpeg",
  968. @"ktx": @"image/ktx",
  969. @"png": @"image/png",
  970. @"btif": @"image/prs.btif",
  971. @"svg": @"image/svg+xml",
  972. @"tiff": @"image/tiff",
  973. @"psd": @"image/vnd.adobe.photoshop",
  974. @"uvi": @"image/vnd.dece.graphic",
  975. @"sub": @"image/vnd.dvb.subtitle",
  976. @"djvu": @"image/vnd.djvu",
  977. @"dwg": @"image/vnd.dwg",
  978. @"dxf": @"image/vnd.dxf",
  979. @"fbs": @"image/vnd.fastbidsheet",
  980. @"fpx": @"image/vnd.fpx",
  981. @"fst": @"image/vnd.fst",
  982. @"mmr": @"image/vnd.fujixerox.edmics-mmr",
  983. @"rlc": @"image/vnd.fujixerox.edmics-rlc",
  984. @"mdi": @"image/vnd.ms-modi",
  985. @"npx": @"image/vnd.net-fpx",
  986. @"wbmp": @"image/vnd.wap.wbmp",
  987. @"xif": @"image/vnd.xiff",
  988. @"webp": @"image/webp",
  989. @"ras": @"image/x-cmu-raster",
  990. @"cmx": @"image/x-cmx",
  991. @"fh": @"image/x-freehand",
  992. @"ico": @"image/x-icon",
  993. @"pcx": @"image/x-pcx",
  994. @"pic": @"image/x-pict",
  995. @"pnm": @"image/x-portable-anymap",
  996. @"pbm": @"image/x-portable-bitmap",
  997. @"pgm": @"image/x-portable-graymap",
  998. @"ppm": @"image/x-portable-pixmap",
  999. @"rgb": @"image/x-rgb",
  1000. @"xbm": @"image/x-xbitmap",
  1001. @"xpm": @"image/x-xpixmap",
  1002. @"xwd": @"image/x-xwindowdump",
  1003. @"eml": @"message/rfc822",
  1004. @"igs": @"model/iges",
  1005. @"msh": @"model/mesh",
  1006. @"dae": @"model/vnd.collada+xml",
  1007. @"dwf": @"model/vnd.dwf",
  1008. @"gdl": @"model/vnd.gdl",
  1009. @"gtw": @"model/vnd.gtw",
  1010. @"mts": @"model/vnd.mts",
  1011. @"vtu": @"model/vnd.vtu",
  1012. @"wrl": @"model/vrml",
  1013. @"ics": @"text/calendar",
  1014. @"css": @"text/css",
  1015. @"csv": @"text/csv",
  1016. @"html": @"text/html",
  1017. @"n3": @"text/n3",
  1018. @"txt": @"text/plain",
  1019. @"dsc": @"text/prs.lines.tag",
  1020. @"rtx": @"text/richtext",
  1021. @"sgml": @"text/sgml",
  1022. @"tsv": @"text/tab-separated-values",
  1023. @"t": @"text/troff",
  1024. @"ttl": @"text/turtle",
  1025. @"uri": @"text/uri-list",
  1026. @"curl": @"text/vnd.curl",
  1027. @"dcurl": @"text/vnd.curl.dcurl",
  1028. @"scurl": @"text/vnd.curl.scurl",
  1029. @"mcurl": @"text/vnd.curl.mcurl",
  1030. @"fly": @"text/vnd.fly",
  1031. @"flx": @"text/vnd.fmi.flexstor",
  1032. @"gv": @"text/vnd.graphviz",
  1033. @"3dml": @"text/vnd.in3d.3dml",
  1034. @"spot": @"text/vnd.in3d.spot",
  1035. @"jad": @"text/vnd.sun.j2me.app-descriptor",
  1036. @"wml": @"text/vnd.wap.wml",
  1037. @"wmls": @"text/vnd.wap.wmlscript",
  1038. @"s": @"text/x-asm",
  1039. @"c": @"text/x-c",
  1040. @"f": @"text/x-fortran",
  1041. @"p": @"text/x-pascal",
  1042. @"java": @"text/x-java-source",
  1043. @"etx": @"text/x-setext",
  1044. @"uu": @"text/x-uuencode",
  1045. @"vcs": @"text/x-vcalendar",
  1046. @"vcf": @"text/x-vcard",
  1047. @"3gp": @"video/3gpp",
  1048. @"3g2": @"video/3gpp2",
  1049. @"h261": @"video/h261",
  1050. @"h263": @"video/h263",
  1051. @"h264": @"video/h264",
  1052. @"jpgv": @"video/jpeg",
  1053. @"jpm": @"video/jpm",
  1054. @"mj2": @"video/mj2",
  1055. @"mp4": @"video/mp4",
  1056. @"mpeg": @"video/mpeg",
  1057. @"ogv": @"video/ogg",
  1058. @"qt": @"video/quicktime",
  1059. @"uvh": @"video/vnd.dece.hd",
  1060. @"uvm": @"video/vnd.dece.mobile",
  1061. @"uvp": @"video/vnd.dece.pd",
  1062. @"uvs": @"video/vnd.dece.sd",
  1063. @"uvv": @"video/vnd.dece.video",
  1064. @"fvt": @"video/vnd.fvt",
  1065. @"mxu": @"video/vnd.mpegurl",
  1066. @"pyv": @"video/vnd.ms-playready.media.pyv",
  1067. @"uvu": @"video/vnd.uvvu.mp4",
  1068. @"viv": @"video/vnd.vivo",
  1069. @"webm": @"video/webm",
  1070. @"f4v": @"video/x-f4v",
  1071. @"fli": @"video/x-fli",
  1072. @"flv": @"video/x-flv",
  1073. @"m4v": @"video/x-m4v",
  1074. @"asf": @"video/x-ms-asf",
  1075. @"wm": @"video/x-ms-wm",
  1076. @"wmv": @"video/x-ms-wmv",
  1077. @"wmx": @"video/x-ms-wmx",
  1078. @"wvx": @"video/x-ms-wvx",
  1079. @"avi": @"video/x-msvideo",
  1080. @"movie": @"video/x-sgi-movie",
  1081. @"mov": @"video/quicktime",
  1082. @"ice": @"x-conference/x-cooltalk",
  1083. @"par ": @"text/plain-bas",
  1084. @"yaml": @"text/yaml"
  1085. };
  1086. });
  1087. NSString * extention = nil;
  1088. if (filePath) {
  1089. extention = [filePath pathExtension];
  1090. }
  1091. if (![extention oss_isNotEmpty] && uploadName) {
  1092. extention = [uploadName pathExtension];
  1093. }
  1094. if (![extention oss_isNotEmpty]) {
  1095. return @"application/octet-stream";
  1096. }
  1097. NSString * mimeType = [mimeMap objectForKey:extention.lowercaseString];
  1098. return mimeType ? mimeType : @"application/octet-stream";
  1099. }
  1100. + (BOOL)hasPhoneFreeSpace{
  1101. NSError *error;
  1102. NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
  1103. if(error) return NO;
  1104. long long space = [[attrs objectForKey:NSFileSystemFreeSize] longLongValue];
  1105. if(space < 0) return NO;
  1106. if(space < osskDDDefaultLogMaxFileSize) return NO;
  1107. return YES;
  1108. }
  1109. + (uint64_t)crc64ecma:(uint64_t)crc1 buffer:(void *)buffer length:(size_t)len
  1110. {
  1111. return aos_crc64(crc1, buffer, len);
  1112. }
  1113. + (uint64_t)crc64ForCombineCRC1:(uint64_t)crc1 CRC2:(uint64_t)crc2 length:(size_t)len2
  1114. {
  1115. return aos_crc64_combine(crc1, crc2, len2);
  1116. }
  1117. + (NSString *)sha1WithString:(NSString *)string
  1118. {
  1119. NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
  1120. return [self sha1WithData:data];
  1121. }
  1122. + (NSString *)sha1WithData:(NSData *)data
  1123. {
  1124. unsigned char *digest = NULL;
  1125. // Malloc a buffer to hold hash.
  1126. digest = malloc(CC_SHA1_DIGEST_LENGTH * sizeof(unsigned char));
  1127. memset(digest, 0x0, CC_SHA1_DIGEST_LENGTH);
  1128. CC_SHA1(data.bytes, (CC_LONG)data.length, digest);
  1129. NSString *result = [self sha1WithDigest:digest];
  1130. if (digest) {
  1131. free(digest);
  1132. }
  1133. return result;
  1134. }
  1135. + (NSString *)sha1WithDigest:(const unsigned char *)digest
  1136. {
  1137. if (!digest) {
  1138. return nil;
  1139. }
  1140. NSMutableString *result = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * sizeof(unsigned char)];
  1141. for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) {
  1142. [result appendFormat:@"%02x",digest[i]];
  1143. }
  1144. return result;
  1145. }
  1146. + (NSString *)sha1WithFilePath:(NSString *)filePath
  1147. {
  1148. NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:filePath];
  1149. if(!handle) {
  1150. return nil;
  1151. }
  1152. CC_SHA1_CTX sha1;
  1153. CC_SHA1_Init(&sha1);
  1154. BOOL done = NO;
  1155. unsigned char *digest = NULL;
  1156. while(!done) {
  1157. @autoreleasepool{
  1158. NSData* fileData = [handle readDataOfLength: CHUNK_SIZE];
  1159. if(fileData.length == 0) {
  1160. break;
  1161. }
  1162. CC_SHA1_Update(&sha1, fileData.bytes, (CC_LONG)[fileData length]);
  1163. }
  1164. }
  1165. if (@available(iOS 13.0, *)) {
  1166. [handle closeAndReturnError:nil];
  1167. } else {
  1168. [handle closeFile];
  1169. }
  1170. // Malloc a buffer to hold hash.
  1171. digest = malloc(CC_SHA1_DIGEST_LENGTH * sizeof(unsigned char));
  1172. memset(digest, 0x0, CC_SHA1_DIGEST_LENGTH);
  1173. CC_SHA1_Final(digest, &sha1);
  1174. NSString *result = [self sha1WithDigest:digest];
  1175. if (digest) {
  1176. free(digest);
  1177. }
  1178. return result;
  1179. }
  1180. + (NSData *)constructHttpBodyForTriggerCallback:(NSString *)callbackParams callbackVaribles:(NSString *)callbackVaribles
  1181. {
  1182. NSMutableString *bodyString = [NSMutableString string];
  1183. [bodyString appendString:@"x-oss-process=trigger/callback,callback_"];
  1184. if ([callbackParams oss_isNotEmpty])
  1185. {
  1186. [bodyString appendString:callbackParams];
  1187. }
  1188. [bodyString appendString:@",callback-var_"];
  1189. if ([callbackVaribles oss_isNotEmpty])
  1190. {
  1191. [bodyString appendString:callbackVaribles];
  1192. }
  1193. return [bodyString dataUsingEncoding:NSUTF8StringEncoding];
  1194. }
  1195. + (NSData *)constructHttpBodyForImagePersist:(NSString *)action toBucket:(NSString *)toBucket toObjectKey:(NSString *)toObjectKey
  1196. {
  1197. /*
  1198. * parameter has checked before
  1199. */
  1200. NSMutableString *bodyString = [NSMutableString string];
  1201. [bodyString appendString:@"x-oss-process="];
  1202. if ([action rangeOfString:@"image/"].location == NSNotFound)
  1203. {
  1204. [bodyString appendString:@"image/"];
  1205. }
  1206. [bodyString appendString:action];
  1207. [bodyString appendString:@"|sys/"];
  1208. NSString * bucket_base64 = [[toBucket dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
  1209. NSString * objectkey_base64 = [[toObjectKey dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
  1210. [bodyString appendString:@"saveas,o_"];
  1211. [bodyString appendString:objectkey_base64];
  1212. [bodyString appendString:@",b_"];
  1213. [bodyString appendString:bucket_base64];
  1214. return [bodyString dataUsingEncoding:NSUTF8StringEncoding];
  1215. }
  1216. @end
  1217. @implementation NSString (OSS)
  1218. - (NSString *)oss_trim {
  1219. return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
  1220. }
  1221. - (BOOL)oss_isNotEmpty
  1222. {
  1223. return ![[self oss_trim] isEqualToString:@""];
  1224. }
  1225. - (NSString *)oss_stringByAppendingPathComponentForURL:(NSString *)aString
  1226. {
  1227. if ([self hasSuffix:@"/"]) {
  1228. return [NSString stringWithFormat:@"%@%@", self, aString];
  1229. } else {
  1230. return [NSString stringWithFormat:@"%@/%@", self, aString];
  1231. }
  1232. }
  1233. + (NSString *)oss_documentDirectory
  1234. {
  1235. static NSString *documentDirectory = nil;
  1236. static dispatch_once_t onceToken;
  1237. dispatch_once(&onceToken, ^{
  1238. documentDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
  1239. });
  1240. return documentDirectory;
  1241. }
  1242. - (NSString *)oss_urlEncodedString {
  1243. static NSCharacterSet *allowCharacterSet = nil;
  1244. static dispatch_once_t onceToken;
  1245. dispatch_once(&onceToken, ^{
  1246. allowCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"!*'();:@&=+$,/?#[]"] invertedSet];
  1247. });
  1248. return [self stringByAddingPercentEncodingWithAllowedCharacters:allowCharacterSet];
  1249. }
  1250. @end