Files
2025-08-12 14:27:12 +08:00

1396 lines
59 KiB
Objective-C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// OSSUtil.m
// oss_ios_sdk
//
// Created by zhouzhuo on 8/16/15.
// Copyright (c) 2015 aliyun.com. All rights reserved.
//
#import "OSSUtil.h"
#import <mach/mach.h>
#import "CommonCrypto/CommonDigest.h"
#import "CommonCrypto/CommonHMAC.h"
#import "OSSModel.h"
#import "OSSLog.h"
#import "OSSHttpdns.h"
#import "OSSDefine.h"
#import "OSSIPv6Adapter.h"
#import "OSSReachability.h"
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import "aos_crc64.h"
NSString * const ALIYUN_HOST_SUFFIX = @".aliyuncs.com";
NSString * const ALIYUN_OSS_TEST_ENDPOINT = @".aliyun-inc.com";
int32_t const CHUNK_SIZE = 8 * 1024;
@implementation OSSUtil
+ (BOOL)isIncludeCnameExcludeList:(NSArray *)cnameExcludeList host:(NSString *)host {
for (NSString *cnameExclude in cnameExcludeList) {
if ([host hasSuffix:cnameExclude]) {
return YES;
}
}
return NO;
}
+ (NSString *)calBase64Sha1WithData:(NSString *)data withSecret:(NSString *)key {
NSData *secretData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSData *clearTextData = [data dataUsingEncoding:NSUTF8StringEncoding];
uint8_t input[20];
CCHmac(kCCHmacAlgSHA1, [secretData bytes], [secretData length], [clearTextData bytes], [clearTextData length], input);
return [self calBase64WithData:input];
}
+ (NSString*)calBase64WithData:(uint8_t *)data {
static char b[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSInteger a = 20;
NSMutableData* c = [NSMutableData dataWithLength:((a + 2) / 3) * 4];
uint8_t* d = (uint8_t*)c.mutableBytes;
NSInteger i;
for (i=0; i < a; i += 3) {
NSInteger e = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
e <<= 8;
if (j < a) {
e |= (0xFF & data[j]);
}
}
NSInteger index = (i / 3) * 4;
d[index + 0] = b[(e >> 18) & 0x3F];
d[index + 1] = b[(e >> 12) & 0x3F];
if ((i + 1) < a) {
d[index + 2] = b[(e >> 6) & 0x3F];
} else {
d[index + 2] = '=';
}
if ((i + 2) < a) {
d[index + 3] = b[(e >> 0) & 0x3F];
} else {
d[index + 3] = '=';
}
}
NSString *result = [[NSString alloc] initWithData:c encoding:NSASCIIStringEncoding];
return result;
}
+ (NSString *)encodeURL:(NSString *)url {
//保持和android处理方式一致添加+ -> %20* -> %2A%7E -> ~, "%2F" -> /
NSMutableString *output = [NSMutableString string];
const unsigned char *source = (const unsigned char *)[url UTF8String];
NSUInteger sourceLen = strlen((const char *)source);
for (int i = 0; i < sourceLen; ++i) {
const unsigned char thisChar = source[i];
if (thisChar == ' ') {
[output appendString:@"%20"];
} else if (thisChar == '*') {
[output appendString:@"%2A"];
} else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||
(thisChar >= 'a' && thisChar <= 'z') ||
(thisChar >= 'A' && thisChar <= 'Z') ||
(thisChar >= '0' && thisChar <= '9')) {
[output appendFormat:@"%c", thisChar];
} else {
[output appendFormat:@"%%%02X", thisChar];
}
}
NSString *encodeUrl = [output stringByReplacingOccurrencesOfString:@"%2F" withString:@"/"];
encodeUrl = [encodeUrl stringByReplacingOccurrencesOfString:@"%7E" withString:@"~"];
return encodeUrl;
// 不要用系统urlencode 的方式,很多特殊字符都没有转化;
// 详见https://stackoverflow.com/questions/8088473/how-do-i-url-encode-a-string
}
+ (NSString *)encodeResourcePath:(NSString *)resourcePath {
//保持和android处理方式一致添加+ -> %20* -> %2A%7E -> ~, "%2F" -> /
NSMutableString *output = [NSMutableString string];
const unsigned char *source = (const unsigned char *)[resourcePath UTF8String];
NSUInteger sourceLen = strlen((const char *)source);
for (int i = 0; i < sourceLen; ++i) {
const unsigned char thisChar = source[i];
if (thisChar == ' ') {
[output appendString:@"%20"];
} else if (thisChar == '*') {
[output appendString:@"%2A"];
} else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' || thisChar == '/' ||
(thisChar >= 'a' && thisChar <= 'z') ||
(thisChar >= 'A' && thisChar <= 'Z') ||
(thisChar >= '0' && thisChar <= '9')) {
[output appendFormat:@"%c", thisChar];
} else {
[output appendFormat:@"%%%02X", thisChar];
}
}
NSString *encodeUrl = [output stringByReplacingOccurrencesOfString:@"%2F" withString:@"/"];
encodeUrl = [encodeUrl stringByReplacingOccurrencesOfString:@"%7E" withString:@"~"];
return encodeUrl;
// 不要用系统urlencode 的方式,很多特殊字符都没有转化;
// 详见https://stackoverflow.com/questions/8088473/how-do-i-url-encode-a-string
}
+ (NSString *)encodeQuery:(NSString *)query {
NSMutableString *output = [NSMutableString string];
const unsigned char *source = (const unsigned char *)[query UTF8String];
NSUInteger sourceLen = strlen((const char *)source);
for (int i = 0; i < sourceLen; ++i) {
const unsigned char thisChar = source[i];
if (thisChar == ' ') {
[output appendString:@"%20"];
} else if (thisChar == '*') {
[output appendString:@"%2A"];
} else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||
(thisChar >= 'a' && thisChar <= 'z') ||
(thisChar >= 'A' && thisChar <= 'Z') ||
(thisChar >= '0' && thisChar <= '9')) {
[output appendFormat:@"%c", thisChar];
} else {
[output appendFormat:@"%%%02X", thisChar];
}
}
NSString *encodeUrl = [output stringByReplacingOccurrencesOfString:@"%7E" withString:@"~"];
return encodeUrl;
}
+ (NSData *)constructHttpBodyFromPartInfos:(NSArray *)partInfos {
NSMutableString * body = [NSMutableString stringWithString:@"<CompleteMultipartUpload>\n"];
[partInfos enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[OSSPartInfo class]]) {
OSSPartInfo * thePart = obj;
[body appendFormat:@"<Part>\n<PartNumber>%d</PartNumber>\n<ETag>%@</ETag>\n</Part>\n", thePart.partNum, thePart.eTag];
}
}];
[body appendString:@"</CompleteMultipartUpload>\n"];
OSSLogVerbose(@"constucted complete multipart upload body:\n%@", body);
return [body dataUsingEncoding:NSUTF8StringEncoding];
}
+ (NSData *)constructHttpBodyForDeleteMultipleObjects:(NSArray<NSString *> *)keys quiet:(BOOL)quiet {
NSMutableString * body = [NSMutableString stringWithString:@"<Delete>\n"];
[body appendFormat:@"<Quiet>%@</Quiet>\n",quiet?@"true":@"false"];
[keys enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) {
[body appendFormat:@"<Object>\n<Key>%@</Key>\n</Object>\n", key];
}];
[body appendString:@"</Delete>\n"];
OSSLogVerbose(@"constucted delete multiple objects body:\n%@", body);
return [body dataUsingEncoding:NSUTF8StringEncoding];
}
+ (NSData *)constructHttpBodyForCreateBucketWithLocation:(NSString *)location {
NSString * body = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
@"<CreateBucketConfiguration>\n"
@"<LocationConstraint>%@</LocationConstraint>\n"
@"</CreateBucketConfiguration>\n",
location];
OSSLogVerbose(@"constucted create bucket body:\n%@", body);
return [body dataUsingEncoding:NSUTF8StringEncoding];
}
+ (BOOL)validateBucketName:(NSString *)bucketName {
if (bucketName == nil) {
return false;
}
static NSRegularExpression *regEx;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
regEx = [[NSRegularExpression alloc] initWithPattern:@"^[a-z0-9][a-z0-9\\-]{1,61}[a-z0-9]$" options:NSRegularExpressionCaseInsensitive error:nil];
});
NSUInteger regExMatches = [regEx numberOfMatchesInString:bucketName options:0 range:NSMakeRange(0, [bucketName length])];
return regExMatches != 0;
}
+ (BOOL)validateObjectKey:(NSString *)objectKey {
if (objectKey == nil) {
return false;
}
if (objectKey.length <= 0 || objectKey.length > 1023) {
return false;
}
if (![objectKey canBeConvertedToEncoding:NSUTF8StringEncoding]) {
return false;
}
unichar firstChar = [objectKey characterAtIndex:0];
if (firstChar == '/' || firstChar == '\\') {
return false;
}
return true;
}
+ (NSString *)getIpByHost:(NSString *)host {
if ([self isNetworkDelegateState]) {
OSSLogDebug(@"current network is delegate state");
return host;
}
NSString * ip = [[OSSHttpdns sharedInstance] asynGetIpByHost:host];
OSSLogDebug(@"resolved host %@ and get ip: %@", host, ip);
return ip ? [[OSSIPv6Adapter getInstance] handleIpv4Address:ip] : host;
}
+ (BOOL)isNetworkDelegateState {
NSURL* URL = [[NSURL alloc] initWithString:@"https://m.aliyun.com"];
NSDictionary *proxySettings = CFBridgingRelease(CFNetworkCopySystemProxySettings());
NSArray *proxies = nil;
proxies = CFBridgingRelease(CFNetworkCopyProxiesForURL((__bridge CFURLRef)URL,
(__bridge CFDictionaryRef)proxySettings));
if (proxies.count) {
NSDictionary *settings = [proxies objectAtIndex:0];
NSString* host = [settings objectForKey:(NSString *)kCFProxyHostNameKey];
NSNumber* port = [settings objectForKey:(NSString *)kCFProxyPortNumberKey];
if (host && port) {
return YES;
}
}
return NO;
}
+ (BOOL)isOssOriginBucketHost:(NSString *)host {
return [[host lowercaseString] hasSuffix:ALIYUN_HOST_SUFFIX] || [[host lowercaseString] hasSuffix:ALIYUN_OSS_TEST_ENDPOINT];
}
+ (NSString *)base64Md5ForData:(NSData *)data {
uint8_t * bytes = (uint8_t *)[[self dataMD5:data] bytes];
return [self base64ForData:bytes length:CC_MD5_DIGEST_LENGTH];
}
+ (NSString *)base64Md5ForFilePath:(NSString *)filePath {
uint8_t * bytes = (uint8_t *)[[self fileMD5:filePath] bytes];
return [self base64ForData:bytes length:CC_MD5_DIGEST_LENGTH];
}
+ (NSString *)base64Md5ForFileURL:(NSURL *)fileURL {
return [self base64Md5ForFilePath:[fileURL path]];
}
+ (NSData *)dataMD5:(NSData *)data {
if(data == nil) {
return nil;
}
CC_MD5_CTX md5;
CC_MD5_Init(&md5);
for (int i = 0; i < data.length; i += CHUNK_SIZE) {
NSData *subdata = nil;
if (i <= ((long)data.length - CHUNK_SIZE)) {
subdata = [data subdataWithRange:NSMakeRange(i, CHUNK_SIZE)];
CC_MD5_Update(&md5, [subdata bytes], (CC_LONG)[subdata length]);
} else {
subdata = [data subdataWithRange:NSMakeRange(i, data.length - i)];
CC_MD5_Update(&md5, [subdata bytes], (CC_LONG)[subdata length]);
}
}
unsigned char digestResult[CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
CC_MD5_Final(digestResult, &md5);
return [NSData dataWithBytes:(const void *)digestResult length:CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
}
+ (NSData *)fileMD5:(NSString*)path {
NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
if(handle == nil) {
return nil;
}
CC_MD5_CTX md5;
CC_MD5_Init(&md5);
BOOL done = NO;
while(!done) {
@autoreleasepool{
NSData* fileData = [handle readDataOfLength: CHUNK_SIZE];
CC_MD5_Update(&md5, [fileData bytes], (CC_LONG)[fileData length]);
if([fileData length] == 0) {
done = YES;
}
}
}
if (@available(iOS 13.0, *)) {
[handle closeAndReturnError:nil];
} else {
[handle closeFile];
}
unsigned char digestResult[CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
CC_MD5_Final(digestResult, &md5);
return [NSData dataWithBytes:(const void *)digestResult length:CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
}
+ (NSData *)fileMD5:(NSString*)path error:(NSError **)error {
NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
if(handle == nil) {
return nil;
}
CC_MD5_CTX md5;
CC_MD5_Init(&md5);
BOOL done = NO;
while(!done) {
@autoreleasepool{
NSData *fileData;
if (@available(iOS 13.0, *)) {
fileData = [handle readDataUpToLength:CHUNK_SIZE error:error];
} else {
@try {
fileData = [handle readDataOfLength: CHUNK_SIZE];
} @catch(NSException *exception) {
*error = [NSError errorWithDomain:OSSClientErrorDomain
code:OSSClientErrorCodeFileCantRead
userInfo:@{OSSErrorMessageTOKEN: [exception description]}];
}
}
CC_MD5_Update(&md5, [fileData bytes], (CC_LONG)[fileData length]);
if([fileData length] == 0) {
done = YES;
}
}
}
if (@available(iOS 13.0, *)) {
[handle closeAndReturnError:error];
} else {
[handle closeFile];
}
unsigned char digestResult[CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
CC_MD5_Final(digestResult, &md5);
return [NSData dataWithBytes:(const void *)digestResult length:CC_MD5_DIGEST_LENGTH * sizeof(unsigned char)];
}
+ (NSString *)convertMd5Bytes2String:(unsigned char *)md5Bytes {
return [NSString stringWithFormat:
@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
md5Bytes[0], md5Bytes[1], md5Bytes[2], md5Bytes[3],
md5Bytes[4], md5Bytes[5], md5Bytes[6], md5Bytes[7],
md5Bytes[8], md5Bytes[9], md5Bytes[10], md5Bytes[11],
md5Bytes[12], md5Bytes[13], md5Bytes[14], md5Bytes[15]
];
}
+ (NSString *)convertMd5Bytes2StringWithData:(NSData *)data error:(NSError **)error {
if (!data || [data length] == 0) {
*error = [NSError errorWithDomain:OSSClientErrorDomain
code:OSSClientErrorCodeInvalidArgument
userInfo:@{OSSErrorMessageTOKEN: @"data is null or data length is 0"}];
return nil;
}
NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
[data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
unsigned char *dataBytes = (unsigned char*)bytes;
for (NSInteger i = 0; i < byteRange.length; i++) {
NSString *hexStr = [NSString stringWithFormat:@"%02X", dataBytes[i]];
[string appendString:hexStr];
}
}];
return string;
}
+ (NSString *)dataMD5String:(NSData *)data error:(NSError **)error {
data = [self dataMD5:data];
return [self convertMd5Bytes2StringWithData:data error:error];
}
+ (NSString *)fileMD5String:(NSString *)path error:(NSError **)error {
BOOL isDirectory = NO;
BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory];
if (isDirectory || !isExist) {
OSSLogWarn(@"a file doesn't exists at a specified path(%@)", path);
return nil;
}
NSData *data = [self fileMD5:path error:error];
return [self convertMd5Bytes2StringWithData:data error:error];
}
+ (NSString *)dataMD5String:(NSData *)data {
unsigned char * md5Bytes = (unsigned char *)[[self dataMD5:data] bytes];
return [self convertMd5Bytes2String:md5Bytes];
}
+ (NSString *)fileMD5String:(NSString *)path {
BOOL isDirectory = NO;
BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory];
if (isDirectory || !isExist) {
OSSLogWarn(@"a file doesn't exists at a specified path(%@)", path);
return nil;
}
unsigned char * md5Bytes = (unsigned char *)[[self fileMD5:path] bytes];
return [self convertMd5Bytes2String:md5Bytes];
}
+ (NSString*)base64ForData:(uint8_t *)input length:(int32_t)length {
if (input == nil) {
return nil;
}
NSData * data = [NSData dataWithBytes:input length:length];
return [data base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];
}
+ (BOOL)isSubresource:(NSString *)param {
/****************************************************************
* define a constant array to contain all specified subresource */
static NSArray * OSSSubResourceARRAY = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
OSSSubResourceARRAY = @[
@"acl", @"uploads", @"location", @"cors", @"logging", @"website", @"referer", @"lifecycle", @"delete", @"append",
@"tagging", @"objectMeta", @"uploadId", @"partNumber", @"security-token", @"position", @"img", @"style",
@"styleName", @"replication", @"replicationProgress", @"replicationLocation", @"cname", @"bucketInfo", @"comp",
@"qos", @"live", @"status", @"vod", @"startTime", @"endTime", @"symlink", @"x-oss-process", @"response-content-type",
@"response-content-language", @"response-expires", @"response-cache-control", @"response-content-disposition", @"response-content-encoding",@"restore", @"sequential"
];
});
/****************************************************************/
return [OSSSubResourceARRAY containsObject:param];
}
+ (NSString *)populateSubresourceStringFromParameter:(NSDictionary *)parameters {
NSMutableArray * subresource = [NSMutableArray new];
[parameters enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSString * keyStr = [key oss_trim];
NSString * valueStr = [obj oss_trim];
if (![OSSUtil isSubresource:keyStr]) {
return;
}
if ([valueStr length] == 0) {
[subresource addObject:keyStr];
} else {
[subresource addObject:[NSString stringWithFormat:@"%@=%@", keyStr, valueStr]];
}
}];
NSArray * sortedSubResource = [subresource sortedArrayUsingSelector:@selector(compare:)]; // 升序
return [sortedSubResource componentsJoinedByString:@"&"];
}
+ (NSString *)populateQueryStringFromParameter:(NSDictionary *)parameters {
NSMutableArray * subresource = [NSMutableArray new];
[parameters enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSString * keyStr = [OSSUtil encodeURL:[key oss_trim]];
NSString * valueStr = [OSSUtil encodeURL:[obj oss_trim]];
if ([valueStr length] == 0) {
[subresource addObject:keyStr];
} else {
[subresource addObject:[NSString stringWithFormat:@"%@=%@", keyStr, valueStr]];
}
}];
return [subresource componentsJoinedByString:@"&"];
}
+ (NSString *)sign:(NSString *)content withToken:(OSSFederationToken *)token {
NSString * sign = [OSSUtil calBase64Sha1WithData:content withSecret:token.tSecretKey];
return [NSString stringWithFormat:@"OSS %@:%@", token.tAccessKey, sign];
}
+ (NSString *)getRelativePath:(NSString *)fullPath {
NSString * rootPath = NSHomeDirectory();
return [fullPath stringByReplacingOccurrencesOfString:rootPath withString:@""];
}
+ (NSString *)detemineMimeTypeForFilePath:(NSString *)filePath uploadName:(NSString *)uploadName {
static dispatch_once_t onceToken;
static NSDictionary * mimeMap;
dispatch_once(&onceToken, ^{
mimeMap = @{
@"aw": @"application/applixware",
@"atom": @"application/atom+xml",
@"atomcat": @"application/atomcat+xml",
@"atomsvc": @"application/atomsvc+xml",
@"ccxml": @"application/ccxml+xml",
@"cdmia": @"application/cdmi-capability",
@"cdmic": @"application/cdmi-container",
@"cdmid": @"application/cdmi-domain",
@"cdmio": @"application/cdmi-object",
@"cdmiq": @"application/cdmi-queue",
@"cu": @"application/cu-seeme",
@"davmount": @"application/davmount+xml",
@"dssc": @"application/dssc+der",
@"xdssc": @"application/dssc+xml",
@"es": @"application/ecmascript",
@"emma": @"application/emma+xml",
@"epub": @"application/epub+zip",
@"exi": @"application/exi",
@"pfr": @"application/font-tdpfr",
@"stk": @"application/hyperstudio",
@"ipfix": @"application/ipfix",
@"jar": @"application/java-archive",
@"ser": @"application/java-serialized-object",
@"class": @"application/java-vm",
@"js": @"application/javascript",
@"json": @"application/json",
@"hqx": @"application/mac-binhex40",
@"cpt": @"application/mac-compactpro",
@"mads": @"application/mads+xml",
@"mrc": @"application/marc",
@"mrcx": @"application/marcxml+xml",
@"ma": @"application/mathematica",
@"mathml": @"application/mathml+xml",
@"mbox": @"application/mbox",
@"mscml": @"application/mediaservercontrol+xml",
@"meta4": @"application/metalink4+xml",
@"mets": @"application/mets+xml",
@"mods": @"application/mods+xml",
@"m21": @"application/mp21",
@"mp4": @"video/mp4",
@"doc": @"application/msword",
@"mxf": @"application/mxf",
@"bin": @"application/octet-stream",
@"oda": @"application/oda",
@"opf": @"application/oebps-package+xml",
@"ogx": @"application/ogg",
@"onetoc": @"application/onenote",
@"xer": @"application/patch-ops-error+xml",
@"pdf": @"application/pdf",
@"pgp": @"application/pgp-signature",
@"prf": @"application/pics-rules",
@"p10": @"application/pkcs10",
@"p7m": @"application/pkcs7-mime",
@"p7s": @"application/pkcs7-signature",
@"p8": @"application/pkcs8",
@"ac": @"application/pkix-attr-cert",
@"cer": @"application/pkix-cert",
@"crl": @"application/pkix-crl",
@"pkipath": @"application/pkix-pkipath",
@"pki": @"application/pkixcmp",
@"pls": @"application/pls+xml",
@"ai": @"application/postscript",
@"cww": @"application/prs.cww",
@"pskcxml": @"application/pskc+xml",
@"rdf": @"application/rdf+xml",
@"rif": @"application/reginfo+xml",
@"rnc": @"application/relax-ng-compact-syntax",
@"rl": @"application/resource-lists+xml",
@"rld": @"application/resource-lists-diff+xml",
@"rs": @"application/rls-services+xml",
@"rsd": @"application/rsd+xml",
@"rss": @"application/rss+xml",
@"rtf": @"application/rtf",
@"sbml": @"application/sbml+xml",
@"scq": @"application/scvp-cv-request",
@"scs": @"application/scvp-cv-response",
@"spq": @"application/scvp-vp-request",
@"spp": @"application/scvp-vp-response",
@"sdp": @"application/sdp",
@"setpay": @"application/set-payment-initiation",
@"setreg": @"application/set-registration-initiation",
@"shf": @"application/shf+xml",
@"smi": @"application/smil+xml",
@"rq": @"application/sparql-query",
@"srx": @"application/sparql-results+xml",
@"gram": @"application/srgs",
@"grxml": @"application/srgs+xml",
@"sru": @"application/sru+xml",
@"ssml": @"application/ssml+xml",
@"tei": @"application/tei+xml",
@"tfi": @"application/thraud+xml",
@"tsd": @"application/timestamped-data",
@"plb": @"application/vnd.3gpp.pic-bw-large",
@"psb": @"application/vnd.3gpp.pic-bw-small",
@"pvb": @"application/vnd.3gpp.pic-bw-var",
@"tcap": @"application/vnd.3gpp2.tcap",
@"pwn": @"application/vnd.3m.post-it-notes",
@"aso": @"application/vnd.accpac.simply.aso",
@"imp": @"application/vnd.accpac.simply.imp",
@"acu": @"application/vnd.acucobol",
@"atc": @"application/vnd.acucorp",
@"air": @"application/vnd.adobe.air-application-installer-package+zip",
@"fxp": @"application/vnd.adobe.fxp",
@"xdp": @"application/vnd.adobe.xdp+xml",
@"xfdf": @"application/vnd.adobe.xfdf",
@"ahead": @"application/vnd.ahead.space",
@"azf": @"application/vnd.airzip.filesecure.azf",
@"azs": @"application/vnd.airzip.filesecure.azs",
@"azw": @"application/vnd.amazon.ebook",
@"acc": @"application/vnd.americandynamics.acc",
@"ami": @"application/vnd.amiga.ami",
@"apk": @"application/vnd.android.package-archive",
@"cii": @"application/vnd.anser-web-certificate-issue-initiation",
@"fti": @"application/vnd.anser-web-funds-transfer-initiation",
@"atx": @"application/vnd.antix.game-component",
@"mpkg": @"application/vnd.apple.installer+xml",
@"m3u8": @"application/vnd.apple.mpegurl",
@"swi": @"application/vnd.aristanetworks.swi",
@"aep": @"application/vnd.audiograph",
@"mpm": @"application/vnd.blueice.multipass",
@"bmi": @"application/vnd.bmi",
@"rep": @"application/vnd.businessobjects",
@"cdxml": @"application/vnd.chemdraw+xml",
@"mmd": @"application/vnd.chipnuts.karaoke-mmd",
@"cdy": @"application/vnd.cinderella",
@"cla": @"application/vnd.claymore",
@"rp9": @"application/vnd.cloanto.rp9",
@"c4g": @"application/vnd.clonk.c4group",
@"c11amc": @"application/vnd.cluetrust.cartomobile-config",
@"c11amz": @"application/vnd.cluetrust.cartomobile-config-pkg",
@"csp": @"application/vnd.commonspace",
@"cdbcmsg": @"application/vnd.contact.cmsg",
@"cmc": @"application/vnd.cosmocaller",
@"clkx": @"application/vnd.crick.clicker",
@"clkk": @"application/vnd.crick.clicker.keyboard",
@"clkp": @"application/vnd.crick.clicker.palette",
@"clkt": @"application/vnd.crick.clicker.template",
@"clkw": @"application/vnd.crick.clicker.wordbank",
@"wbs": @"application/vnd.criticaltools.wbs+xml",
@"pml": @"application/vnd.ctc-posml",
@"ppd": @"application/vnd.cups-ppd",
@"car": @"application/vnd.curl.car",
@"pcurl": @"application/vnd.curl.pcurl",
@"rdz": @"application/vnd.data-vision.rdz",
@"fe_launch": @"application/vnd.denovo.fcselayout-link",
@"dna": @"application/vnd.dna",
@"mlp": @"application/vnd.dolby.mlp",
@"dpg": @"application/vnd.dpgraph",
@"dfac": @"application/vnd.dreamfactory",
@"ait": @"application/vnd.dvb.ait",
@"svc": @"application/vnd.dvb.service",
@"geo": @"application/vnd.dynageo",
@"mag": @"application/vnd.ecowin.chart",
@"nml": @"application/vnd.enliven",
@"esf": @"application/vnd.epson.esf",
@"msf": @"application/vnd.epson.msf",
@"qam": @"application/vnd.epson.quickanime",
@"slt": @"application/vnd.epson.salt",
@"ssf": @"application/vnd.epson.ssf",
@"es3": @"application/vnd.eszigno3+xml",
@"ez2": @"application/vnd.ezpix-album",
@"ez3": @"application/vnd.ezpix-package",
@"fdf": @"application/vnd.fdf",
@"seed": @"application/vnd.fdsn.seed",
@"gph": @"application/vnd.flographit",
@"ftc": @"application/vnd.fluxtime.clip",
@"fm": @"application/vnd.framemaker",
@"fnc": @"application/vnd.frogans.fnc",
@"ltf": @"application/vnd.frogans.ltf",
@"fsc": @"application/vnd.fsc.weblaunch",
@"oas": @"application/vnd.fujitsu.oasys",
@"oa2": @"application/vnd.fujitsu.oasys2",
@"oa3": @"application/vnd.fujitsu.oasys3",
@"fg5": @"application/vnd.fujitsu.oasysgp",
@"bh2": @"application/vnd.fujitsu.oasysprs",
@"ddd": @"application/vnd.fujixerox.ddd",
@"xdw": @"application/vnd.fujixerox.docuworks",
@"xbd": @"application/vnd.fujixerox.docuworks.binder",
@"fzs": @"application/vnd.fuzzysheet",
@"txd": @"application/vnd.genomatix.tuxedo",
@"ggb": @"application/vnd.geogebra.file",
@"ggt": @"application/vnd.geogebra.tool",
@"gex": @"application/vnd.geometry-explorer",
@"gxt": @"application/vnd.geonext",
@"g2w": @"application/vnd.geoplan",
@"g3w": @"application/vnd.geospace",
@"gmx": @"application/vnd.gmx",
@"kml": @"application/vnd.google-earth.kml+xml",
@"kmz": @"application/vnd.google-earth.kmz",
@"gqf": @"application/vnd.grafeq",
@"gac": @"application/vnd.groove-account",
@"ghf": @"application/vnd.groove-help",
@"gim": @"application/vnd.groove-identity-message",
@"grv": @"application/vnd.groove-injector",
@"gtm": @"application/vnd.groove-tool-message",
@"tpl": @"application/vnd.groove-tool-template",
@"vcg": @"application/vnd.groove-vcard",
@"hal": @"application/vnd.hal+xml",
@"zmm": @"application/vnd.handheld-entertainment+xml",
@"hbci": @"application/vnd.hbci",
@"les": @"application/vnd.hhe.lesson-player",
@"hpgl": @"application/vnd.hp-hpgl",
@"hpid": @"application/vnd.hp-hpid",
@"hps": @"application/vnd.hp-hps",
@"jlt": @"application/vnd.hp-jlyt",
@"pcl": @"application/vnd.hp-pcl",
@"pclxl": @"application/vnd.hp-pclxl",
@"sfd-hdstx": @"application/vnd.hydrostatix.sof-data",
@"x3d": @"application/vnd.hzn-3d-crossword",
@"mpy": @"application/vnd.ibm.minipay",
@"afp": @"application/vnd.ibm.modcap",
@"irm": @"application/vnd.ibm.rights-management",
@"sc": @"application/vnd.ibm.secure-container",
@"icc": @"application/vnd.iccprofile",
@"igl": @"application/vnd.igloader",
@"ivp": @"application/vnd.immervision-ivp",
@"ivu": @"application/vnd.immervision-ivu",
@"igm": @"application/vnd.insors.igm",
@"xpw": @"application/vnd.intercon.formnet",
@"i2g": @"application/vnd.intergeo",
@"qbo": @"application/vnd.intu.qbo",
@"qfx": @"application/vnd.intu.qfx",
@"rcprofile": @"application/vnd.ipunplugged.rcprofile",
@"irp": @"application/vnd.irepository.package+xml",
@"xpr": @"application/vnd.is-xpr",
@"fcs": @"application/vnd.isac.fcs",
@"jam": @"application/vnd.jam",
@"rms": @"application/vnd.jcp.javame.midlet-rms",
@"jisp": @"application/vnd.jisp",
@"joda": @"application/vnd.joost.joda-archive",
@"ktz": @"application/vnd.kahootz",
@"karbon": @"application/vnd.kde.karbon",
@"chrt": @"application/vnd.kde.kchart",
@"kfo": @"application/vnd.kde.kformula",
@"flw": @"application/vnd.kde.kivio",
@"kon": @"application/vnd.kde.kontour",
@"kpr": @"application/vnd.kde.kpresenter",
@"ksp": @"application/vnd.kde.kspread",
@"kwd": @"application/vnd.kde.kword",
@"htke": @"application/vnd.kenameaapp",
@"kia": @"application/vnd.kidspiration",
@"kne": @"application/vnd.kinar",
@"skp": @"application/vnd.koan",
@"sse": @"application/vnd.kodak-descriptor",
@"lasxml": @"application/vnd.las.las+xml",
@"lbd": @"application/vnd.llamagraphics.life-balance.desktop",
@"lbe": @"application/vnd.llamagraphics.life-balance.exchange+xml",
@"123": @"application/vnd.lotus-1-2-3",
@"apr": @"application/vnd.lotus-approach",
@"pre": @"application/vnd.lotus-freelance",
@"nsf": @"application/vnd.lotus-notes",
@"org": @"application/vnd.lotus-organizer",
@"scm": @"application/vnd.lotus-screencam",
@"lwp": @"application/vnd.lotus-wordpro",
@"portpkg": @"application/vnd.macports.portpkg",
@"mcd": @"application/vnd.mcd",
@"mc1": @"application/vnd.medcalcdata",
@"cdkey": @"application/vnd.mediastation.cdkey",
@"mwf": @"application/vnd.mfer",
@"mfm": @"application/vnd.mfmp",
@"flo": @"application/vnd.micrografx.flo",
@"igx": @"application/vnd.micrografx.igx",
@"mif": @"application/vnd.mif",
@"daf": @"application/vnd.mobius.daf",
@"dis": @"application/vnd.mobius.dis",
@"mbk": @"application/vnd.mobius.mbk",
@"mqy": @"application/vnd.mobius.mqy",
@"msl": @"application/vnd.mobius.msl",
@"plc": @"application/vnd.mobius.plc",
@"txf": @"application/vnd.mobius.txf",
@"mpn": @"application/vnd.mophun.application",
@"mpc": @"application/vnd.mophun.certificate",
@"xul": @"application/vnd.mozilla.xul+xml",
@"cil": @"application/vnd.ms-artgalry",
@"cab": @"application/vnd.ms-cab-compressed",
@"xls": @"application/vnd.ms-excel",
@"xlam": @"application/vnd.ms-excel.addin.macroenabled.12",
@"xlsb": @"application/vnd.ms-excel.sheet.binary.macroenabled.12",
@"xlsm": @"application/vnd.ms-excel.sheet.macroenabled.12",
@"xltm": @"application/vnd.ms-excel.template.macroenabled.12",
@"eot": @"application/vnd.ms-fontobject",
@"chm": @"application/vnd.ms-htmlhelp",
@"ims": @"application/vnd.ms-ims",
@"lrm": @"application/vnd.ms-lrm",
@"thmx": @"application/vnd.ms-officetheme",
@"cat": @"application/vnd.ms-pki.seccat",
@"stl": @"application/vnd.ms-pki.stl",
@"ppt": @"application/vnd.ms-powerpoint",
@"ppam": @"application/vnd.ms-powerpoint.addin.macroenabled.12",
@"pptm": @"application/vnd.ms-powerpoint.presentation.macroenabled.12",
@"sldm": @"application/vnd.ms-powerpoint.slide.macroenabled.12",
@"ppsm": @"application/vnd.ms-powerpoint.slideshow.macroenabled.12",
@"potm": @"application/vnd.ms-powerpoint.template.macroenabled.12",
@"mpp": @"application/vnd.ms-project",
@"docm": @"application/vnd.ms-word.document.macroenabled.12",
@"dotm": @"application/vnd.ms-word.template.macroenabled.12",
@"wps": @"application/vnd.ms-works",
@"wpl": @"application/vnd.ms-wpl",
@"xps": @"application/vnd.ms-xpsdocument",
@"mseq": @"application/vnd.mseq",
@"mus": @"application/vnd.musician",
@"msty": @"application/vnd.muvee.style",
@"nlu": @"application/vnd.neurolanguage.nlu",
@"nnd": @"application/vnd.noblenet-directory",
@"nns": @"application/vnd.noblenet-sealer",
@"nnw": @"application/vnd.noblenet-web",
@"ngdat": @"application/vnd.nokia.n-gage.data",
@"n-gage": @"application/vnd.nokia.n-gage.symbian.install",
@"rpst": @"application/vnd.nokia.radio-preset",
@"rpss": @"application/vnd.nokia.radio-presets",
@"edm": @"application/vnd.novadigm.edm",
@"edx": @"application/vnd.novadigm.edx",
@"ext": @"application/vnd.novadigm.ext",
@"odc": @"application/vnd.oasis.opendocument.chart",
@"otc": @"application/vnd.oasis.opendocument.chart-template",
@"odb": @"application/vnd.oasis.opendocument.database",
@"odf": @"application/vnd.oasis.opendocument.formula",
@"odft": @"application/vnd.oasis.opendocument.formula-template",
@"odg": @"application/vnd.oasis.opendocument.graphics",
@"otg": @"application/vnd.oasis.opendocument.graphics-template",
@"odi": @"application/vnd.oasis.opendocument.image",
@"oti": @"application/vnd.oasis.opendocument.image-template",
@"odp": @"application/vnd.oasis.opendocument.presentation",
@"otp": @"application/vnd.oasis.opendocument.presentation-template",
@"ods": @"application/vnd.oasis.opendocument.spreadsheet",
@"ots": @"application/vnd.oasis.opendocument.spreadsheet-template",
@"odt": @"application/vnd.oasis.opendocument.text",
@"odm": @"application/vnd.oasis.opendocument.text-master",
@"ott": @"application/vnd.oasis.opendocument.text-template",
@"oth": @"application/vnd.oasis.opendocument.text-web",
@"xo": @"application/vnd.olpc-sugar",
@"dd2": @"application/vnd.oma.dd2+xml",
@"oxt": @"application/vnd.openofficeorg.extension",
@"pptx": @"application/vnd.openxmlformats-officedocument.presentationml.presentation",
@"sldx": @"application/vnd.openxmlformats-officedocument.presentationml.slide",
@"ppsx": @"application/vnd.openxmlformats-officedocument.presentationml.slideshow",
@"potx": @"application/vnd.openxmlformats-officedocument.presentationml.template",
@"xlsx": @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
@"xltx": @"application/vnd.openxmlformats-officedocument.spreadsheetml.template",
@"docx": @"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
@"dotx": @"application/vnd.openxmlformats-officedocument.wordprocessingml.template",
@"mgp": @"application/vnd.osgeo.mapguide.package",
@"dp": @"application/vnd.osgi.dp",
@"pdb": @"application/vnd.palm",
@"paw": @"application/vnd.pawaafile",
@"str": @"application/vnd.pg.format",
@"ei6": @"application/vnd.pg.osasli",
@"efif": @"application/vnd.picsel",
@"wg": @"application/vnd.pmi.widget",
@"plf": @"application/vnd.pocketlearn",
@"pbd": @"application/vnd.powerbuilder6",
@"box": @"application/vnd.previewsystems.box",
@"mgz": @"application/vnd.proteus.magazine",
@"qps": @"application/vnd.publishare-delta-tree",
@"ptid": @"application/vnd.pvi.ptid1",
@"qxd": @"application/vnd.quark.quarkxpress",
@"bed": @"application/vnd.realvnc.bed",
@"mxl": @"application/vnd.recordare.musicxml",
@"musicxml": @"application/vnd.recordare.musicxml+xml",
@"cryptonote": @"application/vnd.rig.cryptonote",
@"cod": @"application/vnd.rim.cod",
@"rm": @"application/vnd.rn-realmedia",
@"link66": @"application/vnd.route66.link66+xml",
@"st": @"application/vnd.sailingtracker.track",
@"see": @"application/vnd.seemail",
@"sema": @"application/vnd.sema",
@"semd": @"application/vnd.semd",
@"semf": @"application/vnd.semf",
@"ifm": @"application/vnd.shana.informed.formdata",
@"itp": @"application/vnd.shana.informed.formtemplate",
@"iif": @"application/vnd.shana.informed.interchange",
@"ipk": @"application/vnd.shana.informed.package",
@"twd": @"application/vnd.simtech-mindmapper",
@"mmf": @"application/vnd.smaf",
@"teacher": @"application/vnd.smart.teacher",
@"sdkm": @"application/vnd.solent.sdkm+xml",
@"dxp": @"application/vnd.spotfire.dxp",
@"sfs": @"application/vnd.spotfire.sfs",
@"sdc": @"application/vnd.stardivision.calc",
@"sda": @"application/vnd.stardivision.draw",
@"sdd": @"application/vnd.stardivision.impress",
@"smf": @"application/vnd.stardivision.math",
@"sdw": @"application/vnd.stardivision.writer",
@"sgl": @"application/vnd.stardivision.writer-global",
@"sm": @"application/vnd.stepmania.stepchart",
@"sxc": @"application/vnd.sun.xml.calc",
@"stc": @"application/vnd.sun.xml.calc.template",
@"sxd": @"application/vnd.sun.xml.draw",
@"std": @"application/vnd.sun.xml.draw.template",
@"sxi": @"application/vnd.sun.xml.impress",
@"sti": @"application/vnd.sun.xml.impress.template",
@"sxm": @"application/vnd.sun.xml.math",
@"sxw": @"application/vnd.sun.xml.writer",
@"sxg": @"application/vnd.sun.xml.writer.global",
@"stw": @"application/vnd.sun.xml.writer.template",
@"sus": @"application/vnd.sus-calendar",
@"svd": @"application/vnd.svd",
@"sis": @"application/vnd.symbian.install",
@"xsm": @"application/vnd.syncml+xml",
@"bdm": @"application/vnd.syncml.dm+wbxml",
@"xdm": @"application/vnd.syncml.dm+xml",
@"tao": @"application/vnd.tao.intent-module-archive",
@"tmo": @"application/vnd.tmobile-livetv",
@"tpt": @"application/vnd.trid.tpt",
@"mxs": @"application/vnd.triscape.mxs",
@"tra": @"application/vnd.trueapp",
@"ufd": @"application/vnd.ufdl",
@"utz": @"application/vnd.uiq.theme",
@"umj": @"application/vnd.umajin",
@"unityweb": @"application/vnd.unity",
@"uoml": @"application/vnd.uoml+xml",
@"vcx": @"application/vnd.vcx",
@"vsd": @"application/vnd.visio",
@"vis": @"application/vnd.visionary",
@"vsf": @"application/vnd.vsf",
@"wbxml": @"application/vnd.wap.wbxml",
@"wmlc": @"application/vnd.wap.wmlc",
@"wmlsc": @"application/vnd.wap.wmlscriptc",
@"wtb": @"application/vnd.webturbo",
@"nbp": @"application/vnd.wolfram.player",
@"wpd": @"application/vnd.wordperfect",
@"wqd": @"application/vnd.wqd",
@"stf": @"application/vnd.wt.stf",
@"xar": @"application/vnd.xara",
@"xfdl": @"application/vnd.xfdl",
@"hvd": @"application/vnd.yamaha.hv-dic",
@"hvs": @"application/vnd.yamaha.hv-script",
@"hvp": @"application/vnd.yamaha.hv-voice",
@"osf": @"application/vnd.yamaha.openscoreformat",
@"osfpvg": @"application/vnd.yamaha.openscoreformat.osfpvg+xml",
@"saf": @"application/vnd.yamaha.smaf-audio",
@"spf": @"application/vnd.yamaha.smaf-phrase",
@"cmp": @"application/vnd.yellowriver-custom-menu",
@"zir": @"application/vnd.zul",
@"zaz": @"application/vnd.zzazz.deck+xml",
@"vxml": @"application/voicexml+xml",
@"wgt": @"application/widget",
@"hlp": @"application/winhlp",
@"wsdl": @"application/wsdl+xml",
@"wspolicy": @"application/wspolicy+xml",
@"7z": @"application/x-7z-compressed",
@"abw": @"application/x-abiword",
@"ace": @"application/x-ace-compressed",
@"aab": @"application/x-authorware-bin",
@"aam": @"application/x-authorware-map",
@"aas": @"application/x-authorware-seg",
@"bcpio": @"application/x-bcpio",
@"torrent": @"application/x-bittorrent",
@"bz": @"application/x-bzip",
@"bz2": @"application/x-bzip2",
@"vcd": @"application/x-cdlink",
@"chat": @"application/x-chat",
@"pgn": @"application/x-chess-pgn",
@"cpio": @"application/x-cpio",
@"csh": @"application/x-csh",
@"deb": @"application/x-debian-package",
@"dir": @"application/x-director",
@"wad": @"application/x-doom",
@"ncx": @"application/x-dtbncx+xml",
@"dtb": @"application/x-dtbook+xml",
@"res": @"application/x-dtbresource+xml",
@"dvi": @"application/x-dvi",
@"bdf": @"application/x-font-bdf",
@"gsf": @"application/x-font-ghostscript",
@"psf": @"application/x-font-linux-psf",
@"otf": @"application/x-font-otf",
@"pcf": @"application/x-font-pcf",
@"snf": @"application/x-font-snf",
@"ttf": @"application/x-font-ttf",
@"pfa": @"application/x-font-type1",
@"woff": @"application/x-font-woff",
@"spl": @"application/x-futuresplash",
@"gnumeric": @"application/x-gnumeric",
@"gtar": @"application/x-gtar",
@"hdf": @"application/x-hdf",
@"jnlp": @"application/x-java-jnlp-file",
@"latex": @"application/x-latex",
@"prc": @"application/x-mobipocket-ebook",
@"application": @"application/x-ms-application",
@"wmd": @"application/x-ms-wmd",
@"wmz": @"application/x-ms-wmz",
@"xbap": @"application/x-ms-xbap",
@"mdb": @"application/x-msaccess",
@"obd": @"application/x-msbinder",
@"crd": @"application/x-mscardfile",
@"clp": @"application/x-msclip",
@"exe": @"application/x-msdownload",
@"mvb": @"application/x-msmediaview",
@"wmf": @"application/x-msmetafile",
@"mny": @"application/x-msmoney",
@"pub": @"application/x-mspublisher",
@"scd": @"application/x-msschedule",
@"trm": @"application/x-msterminal",
@"wri": @"application/x-mswrite",
@"nc": @"application/x-netcdf",
@"p12": @"application/x-pkcs12",
@"p7b": @"application/x-pkcs7-certificates",
@"p7r": @"application/x-pkcs7-certreqresp",
@"rar": @"application/x-rar-compressed",
@"sh": @"application/x-sh",
@"shar": @"application/x-shar",
@"swf": @"application/x-shockwave-flash",
@"xap": @"application/x-silverlight-app",
@"sit": @"application/x-stuffit",
@"sitx": @"application/x-stuffitx",
@"sv4cpio": @"application/x-sv4cpio",
@"sv4crc": @"application/x-sv4crc",
@"tar": @"application/x-tar",
@"tcl": @"application/x-tcl",
@"tex": @"application/x-tex",
@"tfm": @"application/x-tex-tfm",
@"texinfo": @"application/x-texinfo",
@"ustar": @"application/x-ustar",
@"src": @"application/x-wais-source",
@"der": @"application/x-x509-ca-cert",
@"fig": @"application/x-xfig",
@"xpi": @"application/x-xpinstall",
@"xdf": @"application/xcap-diff+xml",
@"xenc": @"application/xenc+xml",
@"xhtml": @"application/xhtml+xml",
@"xml": @"application/xml",
@"dtd": @"application/xml-dtd",
@"xop": @"application/xop+xml",
@"xslt": @"application/xslt+xml",
@"xspf": @"application/xspf+xml",
@"mxml": @"application/xv+xml",
@"yang": @"application/yang",
@"yin": @"application/yin+xml",
@"zip": @"application/zip",
@"adp": @"audio/adpcm",
@"au": @"audio/basic",
@"mid": @"audio/midi",
@"mp4a": @"audio/mp4",
@"mpga": @"audio/mpeg",
@"oga": @"audio/ogg",
@"uva": @"audio/vnd.dece.audio",
@"eol": @"audio/vnd.digital-winds",
@"dra": @"audio/vnd.dra",
@"dts": @"audio/vnd.dts",
@"dtshd": @"audio/vnd.dts.hd",
@"lvp": @"audio/vnd.lucent.voice",
@"pya": @"audio/vnd.ms-playready.media.pya",
@"ecelp4800": @"audio/vnd.nuera.ecelp4800",
@"ecelp7470": @"audio/vnd.nuera.ecelp7470",
@"ecelp9600": @"audio/vnd.nuera.ecelp9600",
@"rip": @"audio/vnd.rip",
@"weba": @"audio/webm",
@"aac": @"audio/x-aac",
@"aif": @"audio/x-aiff",
@"m3u": @"audio/x-mpegurl",
@"wax": @"audio/x-ms-wax",
@"wma": @"audio/x-ms-wma",
@"ram": @"audio/x-pn-realaudio",
@"rmp": @"audio/x-pn-realaudio-plugin",
@"wav": @"audio/x-wav",
@"cdx": @"chemical/x-cdx",
@"cif": @"chemical/x-cif",
@"cmdf": @"chemical/x-cmdf",
@"cml": @"chemical/x-cml",
@"csml": @"chemical/x-csml",
@"xyz": @"chemical/x-xyz",
@"bmp": @"image/bmp",
@"cgm": @"image/cgm",
@"g3": @"image/g3fax",
@"gif": @"image/gif",
@"ief": @"image/ief",
@"jpeg": @"image/jpeg",
@"jpg" : @"image/jpeg",
@"ktx": @"image/ktx",
@"png": @"image/png",
@"btif": @"image/prs.btif",
@"svg": @"image/svg+xml",
@"tiff": @"image/tiff",
@"psd": @"image/vnd.adobe.photoshop",
@"uvi": @"image/vnd.dece.graphic",
@"sub": @"image/vnd.dvb.subtitle",
@"djvu": @"image/vnd.djvu",
@"dwg": @"image/vnd.dwg",
@"dxf": @"image/vnd.dxf",
@"fbs": @"image/vnd.fastbidsheet",
@"fpx": @"image/vnd.fpx",
@"fst": @"image/vnd.fst",
@"mmr": @"image/vnd.fujixerox.edmics-mmr",
@"rlc": @"image/vnd.fujixerox.edmics-rlc",
@"mdi": @"image/vnd.ms-modi",
@"npx": @"image/vnd.net-fpx",
@"wbmp": @"image/vnd.wap.wbmp",
@"xif": @"image/vnd.xiff",
@"webp": @"image/webp",
@"ras": @"image/x-cmu-raster",
@"cmx": @"image/x-cmx",
@"fh": @"image/x-freehand",
@"ico": @"image/x-icon",
@"pcx": @"image/x-pcx",
@"pic": @"image/x-pict",
@"pnm": @"image/x-portable-anymap",
@"pbm": @"image/x-portable-bitmap",
@"pgm": @"image/x-portable-graymap",
@"ppm": @"image/x-portable-pixmap",
@"rgb": @"image/x-rgb",
@"xbm": @"image/x-xbitmap",
@"xpm": @"image/x-xpixmap",
@"xwd": @"image/x-xwindowdump",
@"eml": @"message/rfc822",
@"igs": @"model/iges",
@"msh": @"model/mesh",
@"dae": @"model/vnd.collada+xml",
@"dwf": @"model/vnd.dwf",
@"gdl": @"model/vnd.gdl",
@"gtw": @"model/vnd.gtw",
@"mts": @"model/vnd.mts",
@"vtu": @"model/vnd.vtu",
@"wrl": @"model/vrml",
@"ics": @"text/calendar",
@"css": @"text/css",
@"csv": @"text/csv",
@"html": @"text/html",
@"n3": @"text/n3",
@"txt": @"text/plain",
@"dsc": @"text/prs.lines.tag",
@"rtx": @"text/richtext",
@"sgml": @"text/sgml",
@"tsv": @"text/tab-separated-values",
@"t": @"text/troff",
@"ttl": @"text/turtle",
@"uri": @"text/uri-list",
@"curl": @"text/vnd.curl",
@"dcurl": @"text/vnd.curl.dcurl",
@"scurl": @"text/vnd.curl.scurl",
@"mcurl": @"text/vnd.curl.mcurl",
@"fly": @"text/vnd.fly",
@"flx": @"text/vnd.fmi.flexstor",
@"gv": @"text/vnd.graphviz",
@"3dml": @"text/vnd.in3d.3dml",
@"spot": @"text/vnd.in3d.spot",
@"jad": @"text/vnd.sun.j2me.app-descriptor",
@"wml": @"text/vnd.wap.wml",
@"wmls": @"text/vnd.wap.wmlscript",
@"s": @"text/x-asm",
@"c": @"text/x-c",
@"f": @"text/x-fortran",
@"p": @"text/x-pascal",
@"java": @"text/x-java-source",
@"etx": @"text/x-setext",
@"uu": @"text/x-uuencode",
@"vcs": @"text/x-vcalendar",
@"vcf": @"text/x-vcard",
@"3gp": @"video/3gpp",
@"3g2": @"video/3gpp2",
@"h261": @"video/h261",
@"h263": @"video/h263",
@"h264": @"video/h264",
@"jpgv": @"video/jpeg",
@"jpm": @"video/jpm",
@"mj2": @"video/mj2",
@"mp4": @"video/mp4",
@"mpeg": @"video/mpeg",
@"ogv": @"video/ogg",
@"qt": @"video/quicktime",
@"uvh": @"video/vnd.dece.hd",
@"uvm": @"video/vnd.dece.mobile",
@"uvp": @"video/vnd.dece.pd",
@"uvs": @"video/vnd.dece.sd",
@"uvv": @"video/vnd.dece.video",
@"fvt": @"video/vnd.fvt",
@"mxu": @"video/vnd.mpegurl",
@"pyv": @"video/vnd.ms-playready.media.pyv",
@"uvu": @"video/vnd.uvvu.mp4",
@"viv": @"video/vnd.vivo",
@"webm": @"video/webm",
@"f4v": @"video/x-f4v",
@"fli": @"video/x-fli",
@"flv": @"video/x-flv",
@"m4v": @"video/x-m4v",
@"asf": @"video/x-ms-asf",
@"wm": @"video/x-ms-wm",
@"wmv": @"video/x-ms-wmv",
@"wmx": @"video/x-ms-wmx",
@"wvx": @"video/x-ms-wvx",
@"avi": @"video/x-msvideo",
@"movie": @"video/x-sgi-movie",
@"mov": @"video/quicktime",
@"ice": @"x-conference/x-cooltalk",
@"par ": @"text/plain-bas",
@"yaml": @"text/yaml"
};
});
NSString * extention = nil;
if (filePath) {
extention = [filePath pathExtension];
}
if (![extention oss_isNotEmpty] && uploadName) {
extention = [uploadName pathExtension];
}
if (![extention oss_isNotEmpty]) {
return @"application/octet-stream";
}
NSString * mimeType = [mimeMap objectForKey:extention.lowercaseString];
return mimeType ? mimeType : @"application/octet-stream";
}
+ (BOOL)hasPhoneFreeSpace{
NSError *error;
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
if(error) return NO;
long long space = [[attrs objectForKey:NSFileSystemFreeSize] longLongValue];
if(space < 0) return NO;
if(space < osskDDDefaultLogMaxFileSize) return NO;
return YES;
}
+ (uint64_t)crc64ecma:(uint64_t)crc1 buffer:(void *)buffer length:(size_t)len
{
return aos_crc64(crc1, buffer, len);
}
+ (uint64_t)crc64ForCombineCRC1:(uint64_t)crc1 CRC2:(uint64_t)crc2 length:(size_t)len2
{
return aos_crc64_combine(crc1, crc2, len2);
}
+ (NSString *)sha1WithString:(NSString *)string
{
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
return [self sha1WithData:data];
}
+ (NSString *)sha1WithData:(NSData *)data
{
unsigned char *digest = NULL;
// Malloc a buffer to hold hash.
digest = malloc(CC_SHA1_DIGEST_LENGTH * sizeof(unsigned char));
memset(digest, 0x0, CC_SHA1_DIGEST_LENGTH);
CC_SHA1(data.bytes, (CC_LONG)data.length, digest);
NSString *result = [self sha1WithDigest:digest];
if (digest) {
free(digest);
}
return result;
}
+ (NSString *)sha1WithDigest:(const unsigned char *)digest
{
if (!digest) {
return nil;
}
NSMutableString *result = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * sizeof(unsigned char)];
for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) {
[result appendFormat:@"%02x",digest[i]];
}
return result;
}
+ (NSString *)sha1WithFilePath:(NSString *)filePath
{
NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:filePath];
if(!handle) {
return nil;
}
CC_SHA1_CTX sha1;
CC_SHA1_Init(&sha1);
BOOL done = NO;
unsigned char *digest = NULL;
while(!done) {
@autoreleasepool{
NSData* fileData = [handle readDataOfLength: CHUNK_SIZE];
if(fileData.length == 0) {
break;
}
CC_SHA1_Update(&sha1, fileData.bytes, (CC_LONG)[fileData length]);
}
}
if (@available(iOS 13.0, *)) {
[handle closeAndReturnError:nil];
} else {
[handle closeFile];
}
// Malloc a buffer to hold hash.
digest = malloc(CC_SHA1_DIGEST_LENGTH * sizeof(unsigned char));
memset(digest, 0x0, CC_SHA1_DIGEST_LENGTH);
CC_SHA1_Final(digest, &sha1);
NSString *result = [self sha1WithDigest:digest];
if (digest) {
free(digest);
}
return result;
}
+ (NSData *)constructHttpBodyForTriggerCallback:(NSString *)callbackParams callbackVaribles:(NSString *)callbackVaribles
{
NSMutableString *bodyString = [NSMutableString string];
[bodyString appendString:@"x-oss-process=trigger/callback,callback_"];
if ([callbackParams oss_isNotEmpty])
{
[bodyString appendString:callbackParams];
}
[bodyString appendString:@",callback-var_"];
if ([callbackVaribles oss_isNotEmpty])
{
[bodyString appendString:callbackVaribles];
}
return [bodyString dataUsingEncoding:NSUTF8StringEncoding];
}
+ (NSData *)constructHttpBodyForImagePersist:(NSString *)action toBucket:(NSString *)toBucket toObjectKey:(NSString *)toObjectKey
{
/*
* parameter has checked before
*/
NSMutableString *bodyString = [NSMutableString string];
[bodyString appendString:@"x-oss-process="];
if ([action rangeOfString:@"image/"].location == NSNotFound)
{
[bodyString appendString:@"image/"];
}
[bodyString appendString:action];
[bodyString appendString:@"|sys/"];
NSString * bucket_base64 = [[toBucket dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
NSString * objectkey_base64 = [[toObjectKey dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
[bodyString appendString:@"saveas,o_"];
[bodyString appendString:objectkey_base64];
[bodyString appendString:@",b_"];
[bodyString appendString:bucket_base64];
return [bodyString dataUsingEncoding:NSUTF8StringEncoding];
}
@end
@implementation NSString (OSS)
- (NSString *)oss_trim {
return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (BOOL)oss_isNotEmpty
{
return ![[self oss_trim] isEqualToString:@""];
}
- (NSString *)oss_stringByAppendingPathComponentForURL:(NSString *)aString
{
if ([self hasSuffix:@"/"]) {
return [NSString stringWithFormat:@"%@%@", self, aString];
} else {
return [NSString stringWithFormat:@"%@/%@", self, aString];
}
}
+ (NSString *)oss_documentDirectory
{
static NSString *documentDirectory = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
documentDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
});
return documentDirectory;
}
- (NSString *)oss_urlEncodedString {
static NSCharacterSet *allowCharacterSet = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
allowCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"!*'();:@&=+$,/?#[]"] invertedSet];
});
return [self stringByAddingPercentEncodingWithAllowedCharacters:allowCharacterSet];
}
@end