diff --git a/src/android/com/synconset/CordovaHTTP/CordovaHttp.java b/src/android/com/synconset/CordovaHTTP/CordovaHttp.java index 0cc9b9a..583d5c4 100644 --- a/src/android/com/synconset/CordovaHTTP/CordovaHttp.java +++ b/src/android/com/synconset/CordovaHTTP/CordovaHttp.java @@ -25,6 +25,8 @@ import javax.net.ssl.HostnameVerifier; import java.util.Iterator; import android.util.Log; + +import com.github.kevinsawicki.http.HttpRequest; public abstract class CordovaHttp { protected static final String TAG = "CordovaHTTP"; @@ -89,12 +91,15 @@ public abstract class CordovaHttp { return this.callbackContext; } - protected boolean sslPinning() { - return sslPinning; - } - - protected boolean acceptAllCerts() { - return acceptAllCerts; + protected HttpRequest setupSecurity(HttpRequest request) { + if (acceptAllCerts) { + request.trustAllCerts(); + request.trustAllHosts(); + } + if (sslPinning) { + request.pinToCerts(); + } + return request; } protected void respondWithError(String msg) { diff --git a/src/android/com/synconset/CordovaHTTP/CordovaHttpDownload.java b/src/android/com/synconset/CordovaHTTP/CordovaHttpDownload.java index f3c3431..51262b2 100644 --- a/src/android/com/synconset/CordovaHTTP/CordovaHttpDownload.java +++ b/src/android/com/synconset/CordovaHTTP/CordovaHttpDownload.java @@ -31,13 +31,7 @@ public class CordovaHttpDownload extends CordovaHttp implements Runnable { public void run() { try { HttpRequest request = HttpRequest.get(this.getUrlString(), this.getParams(), true); - if (this.acceptAllCerts()) { - request.trustAllCerts(); - request.trustAllHosts(); - } - if (this.sslPinning()) { - request.pinToCerts(); - } + this.setupSecurity(request); request.acceptCharset(CHARSET); request.headers(this.getHeaders()); int code = request.code(); diff --git a/src/android/com/synconset/CordovaHTTP/CordovaHttpGet.java b/src/android/com/synconset/CordovaHTTP/CordovaHttpGet.java index db71bbb..b23c0c6 100644 --- a/src/android/com/synconset/CordovaHTTP/CordovaHttpGet.java +++ b/src/android/com/synconset/CordovaHTTP/CordovaHttpGet.java @@ -31,21 +31,11 @@ public class CordovaHttpGet extends CordovaHttp implements Runnable { public void run() { try { HttpRequest request = HttpRequest.get(this.getUrlString(), this.getParams(), true); - if (this.acceptAllCerts()) { - request.trustAllCerts(); - request.trustAllHosts(); - } - if (this.sslPinning()) { - request.pinToCerts(); - } + this.setupSecurity(request); request.acceptCharset(CHARSET); request.headers(this.getHeaders()); int code = request.code(); String body = request.body(CHARSET); - - Log.d(TAG, Integer.toString(code)); - Log.d(TAG, body); - JSONObject response = new JSONObject(); response.put("status", code); if (code >= 200 && code < 300) { diff --git a/src/android/com/synconset/CordovaHTTP/CordovaHttpPost.java b/src/android/com/synconset/CordovaHTTP/CordovaHttpPost.java index 9adbba5..c257927 100644 --- a/src/android/com/synconset/CordovaHTTP/CordovaHttpPost.java +++ b/src/android/com/synconset/CordovaHTTP/CordovaHttpPost.java @@ -22,27 +22,13 @@ public class CordovaHttpPost extends CordovaHttp implements Runnable { @Override public void run() { try { - Log.d(TAG, this.getParams().toString()); HttpRequest request = HttpRequest.post(this.getUrlString()); - if (this.acceptAllCerts()) { - request.trustAllCerts(); - request.trustAllHosts(); - } - if (this.sslPinning()) { - Log.d(TAG, "ssl pinning"); - request.pinToCerts(); - } + this.setupSecurity(request); request.acceptCharset(CHARSET); request.headers(this.getHeaders()); - request.form(this.getParams()); - int code = request.code(); String body = request.body(CHARSET); - - Log.d(TAG, Integer.toString(code)); - Log.d(TAG, body); - JSONObject response = new JSONObject(); response.put("status", code); if (code >= 200 && code < 300) { diff --git a/src/android/com/synconset/CordovaHTTP/CordovaHttpUpload.java b/src/android/com/synconset/CordovaHTTP/CordovaHttpUpload.java index 71a6511..35788bd 100644 --- a/src/android/com/synconset/CordovaHTTP/CordovaHttpUpload.java +++ b/src/android/com/synconset/CordovaHTTP/CordovaHttpUpload.java @@ -16,6 +16,7 @@ import org.json.JSONException; import org.json.JSONObject; import android.util.Log; +import android.webkit.MimeTypeMap; import com.github.kevinsawicki.http.HttpRequest; import com.github.kevinsawicki.http.HttpRequest.HttpRequestException; @@ -34,21 +35,17 @@ public class CordovaHttpUpload extends CordovaHttp implements Runnable { public void run() { try { HttpRequest request = HttpRequest.post(this.getUrlString()); - if (this.acceptAllCerts()) { - request.trustAllCerts(); - request.trustAllHosts(); - } - if (this.sslPinning()) { - request.pinToCerts(); - } + this.setupSecurity(request); request.acceptCharset(CHARSET); request.headers(this.getHeaders()); URI uri = new URI(filePath); - Log.d(TAG, uri.toString()); - Log.d(TAG, name); int index = filePath.lastIndexOf('/'); - String filename = filePath.substring(index); - request.part(this.name, filename, "image/jpeg", new File(uri)); + String filename = filePath.substring(index + 1); + index = filePath.lastIndexOf('.'); + String ext = filePath.substring(index + 1); + MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton(); + String mimeType = mimeTypeMap.getMimeTypeFromExtension(ext); + request.part(this.name, filename, mimeType, new File(uri)); Set set = (Set)this.getParams().entrySet(); Iterator i = set.iterator(); diff --git a/src/ios/AFNetworking/AFSecurityPolicy.m b/src/ios/AFNetworking/AFSecurityPolicy.m index ca1120c..de7dab1 100755 --- a/src/ios/AFNetworking/AFSecurityPolicy.m +++ b/src/ios/AFNetworking/AFSecurityPolicy.m @@ -25,16 +25,16 @@ #if !defined(__IPHONE_OS_VERSION_MIN_REQUIRED) static NSData * AFSecKeyGetData(SecKeyRef key) { CFDataRef data = NULL; - + #if defined(NS_BLOCK_ASSERTIONS) SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data); #else OSStatus status = SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data); NSCAssert(status == errSecSuccess, @"SecItemExport error: %ld", (long int)status); #endif - + NSCParameterAssert(data); - + return (__bridge_transfer NSData *)data; } #endif @@ -50,10 +50,10 @@ static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) { static id AFPublicKeyForCertificate(NSData *certificate) { SecCertificateRef allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate); NSCParameterAssert(allowedCertificate); - + SecCertificateRef allowedCertificates[] = {allowedCertificate}; CFArrayRef tempCertificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 1, NULL); - + SecPolicyRef policy = SecPolicyCreateBasicX509(); SecTrustRef allowedTrust = NULL; #if defined(NS_BLOCK_ASSERTIONS) @@ -62,49 +62,49 @@ static id AFPublicKeyForCertificate(NSData *certificate) { OSStatus status = SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust); NSCAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates error: %ld", (long int)status); #endif - + SecTrustResultType result = 0; - + #if defined(NS_BLOCK_ASSERTIONS) SecTrustEvaluate(allowedTrust, &result); #else status = SecTrustEvaluate(allowedTrust, &result); NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status); #endif - + SecKeyRef allowedPublicKey = SecTrustCopyPublicKey(allowedTrust); NSCParameterAssert(allowedPublicKey); - + CFRelease(allowedTrust); CFRelease(policy); CFRelease(tempCertificates); CFRelease(allowedCertificate); - + return (__bridge_transfer id)allowedPublicKey; } static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) { SecTrustResultType result = 0; - + #if defined(NS_BLOCK_ASSERTIONS) SecTrustEvaluate(serverTrust, &result); #else OSStatus status = SecTrustEvaluate(serverTrust, &result); NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status); #endif - + return (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed); } static NSArray * AFCertificateTrustChainForServerTrust(SecTrustRef serverTrust) { CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; - + for (CFIndex i = 0; i < certificateCount; i++) { SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); [trustChain addObject:(__bridge_transfer NSData *)SecCertificateCopyData(certificate)]; } - + return [NSArray arrayWithArray:trustChain]; } @@ -114,68 +114,36 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; for (CFIndex i = 0; i < certificateCount; i++) { SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); - + SecCertificateRef someCertificates[] = {certificate}; CFArrayRef certificates = CFArrayCreate(NULL, (const void **)someCertificates, 1, NULL); - + SecTrustRef trust = NULL; - + #if defined(NS_BLOCK_ASSERTIONS) SecTrustCreateWithCertificates(certificates, policy, &trust); - + SecTrustResultType result; SecTrustEvaluate(trust, &result); #else OSStatus status = SecTrustCreateWithCertificates(certificates, policy, &trust); NSCAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates error: %ld", (long int)status); - + SecTrustResultType result; status = SecTrustEvaluate(trust, &result); NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status); #endif - + [trustChain addObject:(__bridge_transfer id)SecTrustCopyPublicKey(trust)]; - + CFRelease(trust); CFRelease(certificates); } CFRelease(policy); - + return [NSArray arrayWithArray:trustChain]; } -static NSComparisonResult AFDomainComponentCompare(NSString *component1, NSString *component2) { - if ([component1 isEqualToString:@"*"] || [component2 isEqualToString:@"*"]) { - return NSOrderedSame; - } - - return [component1 compare:component2]; -} - -static BOOL AFCertificateHostMatchesDomain(NSString *certificateHost, NSString *domain) { - certificateHost = [certificateHost lowercaseString]; - domain = [domain lowercaseString]; - - if ([certificateHost isEqualToString:domain]) { - return YES; - } - - NSArray *certificateHostComponents = [certificateHost componentsSeparatedByString:@"."]; - NSArray *domainComponents = [domain componentsSeparatedByString:@"."]; - - if ([certificateHostComponents count] != [domainComponents count]) { - return NO; - } - - BOOL certificateHostMatchesDomain = ([certificateHostComponents indexOfObjectPassingTest:^BOOL(NSString *certificateHostComponent, NSUInteger idx, __unused BOOL *stop) { - NSString *domainComponent = [domainComponents objectAtIndex:idx]; - - return AFDomainComponentCompare(certificateHostComponent, domainComponent) != NSOrderedSame; - }] == NSNotFound); - - return certificateHostMatchesDomain; -} - #pragma mark - @interface AFSecurityPolicy() @@ -190,23 +158,23 @@ static BOOL AFCertificateHostMatchesDomain(NSString *certificateHost, NSString * dispatch_once(&onceToken, ^{ NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."]; - + NSMutableArray *certificates = [NSMutableArray arrayWithCapacity:[paths count]]; for (NSString *path in paths) { NSData *certificateData = [NSData dataWithContentsOfFile:path]; [certificates addObject:certificateData]; } - + _defaultPinnedCertificates = [[NSArray alloc] initWithArray:certificates]; }); - + return _defaultPinnedCertificates; } + (instancetype)defaultPolicy { AFSecurityPolicy *securityPolicy = [[self alloc] init]; securityPolicy.SSLPinningMode = AFSSLPinningModeNone; - + return securityPolicy; } @@ -215,7 +183,7 @@ static BOOL AFCertificateHostMatchesDomain(NSString *certificateHost, NSString * securityPolicy.SSLPinningMode = pinningMode; securityPolicy.validatesDomainName = YES; [securityPolicy setPinnedCertificates:[self defaultPinnedCertificates]]; - + return securityPolicy; } @@ -234,7 +202,7 @@ static BOOL AFCertificateHostMatchesDomain(NSString *certificateHost, NSString * - (void)setPinnedCertificates:(NSArray *)pinnedCertificates { _pinnedCertificates = pinnedCertificates; - + if (self.pinnedCertificates) { NSMutableArray *mutablePinnedPublicKeys = [NSMutableArray arrayWithCapacity:[self.pinnedCertificates count]]; for (NSData *certificate in self.pinnedCertificates) { @@ -255,12 +223,15 @@ static BOOL AFCertificateHostMatchesDomain(NSString *certificateHost, NSString * - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain { - BOOL shouldTrustServer = NO; - - if (self.SSLPinningMode == AFSSLPinningModeNone && self.allowInvalidCertificates) { - return YES; + NSMutableArray *policies = [NSMutableArray array]; + if (self.validatesDomainName) { + [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)]; + } else { + [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()]; } + SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies); + if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) { return NO; } @@ -270,6 +241,20 @@ static BOOL AFCertificateHostMatchesDomain(NSString *certificateHost, NSString * case AFSSLPinningModeNone: return YES; case AFSSLPinningModeCertificate: { + NSMutableArray *pinnedCertificates = [NSMutableArray array]; + for (NSData *certificateData in self.pinnedCertificates) { + [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)]; + } + SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates); + + if (!AFServerTrustIsValid(serverTrust)) { + return NO; + } + + if (!self.validatesCertificateChain) { + return YES; + } + NSUInteger trustedCertificateCount = 0; for (NSData *trustChainCertificate in serverCertificates) { if ([self.pinnedCertificates containsObject:trustChainCertificate]) { @@ -277,12 +262,14 @@ static BOOL AFCertificateHostMatchesDomain(NSString *certificateHost, NSString * } } - shouldTrustServer = trustedCertificateCount > 0 && ((self.validatesCertificateChain && trustedCertificateCount == [serverCertificates count]) || (!self.validatesCertificateChain && trustedCertificateCount >= 1)); + return trustedCertificateCount == [serverCertificates count]; } - break; case AFSSLPinningModePublicKey: { NSUInteger trustedPublicKeyCount = 0; NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust); + if (!self.validatesCertificateChain && [publicKeys count] > 0) { + publicKeys = @[[publicKeys firstObject]]; + } for (id trustChainPublicKey in publicKeys) { for (id pinnedPublicKey in self.pinnedPublicKeys) { @@ -292,22 +279,11 @@ static BOOL AFCertificateHostMatchesDomain(NSString *certificateHost, NSString * } } - shouldTrustServer = trustedPublicKeyCount > 0 && ((self.validatesCertificateChain && trustedPublicKeyCount == [serverCertificates count]) || (!self.validatesCertificateChain && trustedPublicKeyCount >= 1)); + return trustedPublicKeyCount > 0 && ((self.validatesCertificateChain && trustedPublicKeyCount == [serverCertificates count]) || (!self.validatesCertificateChain && trustedPublicKeyCount >= 1)); } - break; } - if (shouldTrustServer && domain && self.validatesDomainName) { - NSData *serverCertificate = [serverCertificates firstObject]; - SecCertificateRef matchingCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)serverCertificate); - NSParameterAssert(matchingCertificate); - - shouldTrustServer = AFCertificateHostMatchesDomain((__bridge_transfer NSString *)SecCertificateCopySubjectSummary(matchingCertificate), domain); - - CFRelease(matchingCertificate); - } - - return shouldTrustServer; + return NO; } #pragma mark - NSKeyValueObserving diff --git a/src/ios/AFNetworking/AFURLRequestSerialization.h b/src/ios/AFNetworking/AFURLRequestSerialization.h index d78ee06..b686ffd 100755 --- a/src/ios/AFNetworking/AFURLRequestSerialization.h +++ b/src/ios/AFNetworking/AFURLRequestSerialization.h @@ -191,7 +191,7 @@ forHTTPHeaderField:(NSString *)field; */ - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString - parameters:(NSDictionary *)parameters DEPRECATED_ATTRIBUTE; + parameters:(id)parameters DEPRECATED_ATTRIBUTE; /** Creates an `NSMutableURLRequest` object with the specified HTTP method and URL string. @@ -207,7 +207,7 @@ forHTTPHeaderField:(NSString *)field; */ - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString - parameters:(NSDictionary *)parameters + parameters:(id)parameters error:(NSError * __autoreleasing *)error; /** diff --git a/src/ios/AFNetworking/AFURLRequestSerialization.m b/src/ios/AFNetworking/AFURLRequestSerialization.m index 8873f98..1526466 100755 --- a/src/ios/AFNetworking/AFURLRequestSerialization.m +++ b/src/ios/AFNetworking/AFURLRequestSerialization.m @@ -212,8 +212,9 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) { if (userAgent) { if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) { NSMutableString *mutableUserAgent = [userAgent mutableCopy]; - CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false); - userAgent = mutableUserAgent; + if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) { + userAgent = mutableUserAgent; + } } [self setValue:userAgent forHTTPHeaderField:@"User-Agent"]; } @@ -262,14 +263,14 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) { - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString - parameters:(NSDictionary *)parameters + parameters:(id)parameters { return [self requestWithMethod:method URLString:URLString parameters:parameters error:nil]; } - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString - parameters:(NSDictionary *)parameters + parameters:(id)parameters error:(NSError *__autoreleasing *)error { NSParameterAssert(method); diff --git a/src/ios/AFNetworking/AFURLResponseSerialization.m b/src/ios/AFNetworking/AFURLResponseSerialization.m index cde7257..90d2229 100755 --- a/src/ios/AFNetworking/AFURLResponseSerialization.m +++ b/src/ios/AFNetworking/AFURLResponseSerialization.m @@ -101,20 +101,11 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) { } if (self.acceptableStatusCodes && ![self.acceptableStatusCodes containsIndex:(NSUInteger)response.statusCode]) { - NSStringEncoding stringEncoding = self.stringEncoding; - if (response.textEncodingName) { - CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName); - if (encoding != kCFStringEncodingInvalidId) { - stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding); - } - } - - NSString *responseString = [[NSString alloc] initWithData:data encoding:stringEncoding]; NSDictionary *userInfo = @{ - NSLocalizedDescriptionKey: responseString, - NSURLErrorFailingURLErrorKey:[response URL], - AFNetworkingOperationFailingURLResponseErrorKey: response - }; + NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: %@ (%lu)", @"AFNetworking", nil), [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode], (unsigned long)response.statusCode], + NSURLErrorFailingURLErrorKey:[response URL], + AFNetworkingOperationFailingURLResponseErrorKey: response + }; validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo], validationError); @@ -220,33 +211,35 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) { } id responseObject = nil; - NSString *responseString = [[NSString alloc] initWithData:data encoding:stringEncoding]; - if (responseString && ![responseString isEqualToString:@" "]) { - // Workaround for a bug in NSJSONSerialization when Unicode character escape codes are used instead of the actual character - // See http://stackoverflow.com/a/12843465/157142 - data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; + NSError *serializationError = nil; + @autoreleasepool { + NSString *responseString = [[NSString alloc] initWithData:data encoding:stringEncoding]; + if (responseString && ![responseString isEqualToString:@" "]) { + // Workaround for a bug in NSJSONSerialization when Unicode character escape codes are used instead of the actual character + // See http://stackoverflow.com/a/12843465/157142 + data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; - NSError *serializationError = nil; - if (data) { - if ([data length] > 0) { - responseObject = [NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError]; + if (data) { + if ([data length] > 0) { + responseObject = [NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError]; + } else { + return nil; + } } else { - return nil; + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"Data failed decoding as a UTF-8 string", nil, @"AFNetworking"), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", nil, @"AFNetworking"), responseString] + }; + + serializationError = [NSError errorWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo]; } - } else { - NSDictionary *userInfo = @{ - NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"Data failed decoding as a UTF-8 string", nil, @"AFNetworking"), - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", nil, @"AFNetworking"), responseString] - }; - - serializationError = [NSError errorWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo]; - } - - if (error) { - *error = AFErrorWithUnderlyingError(serializationError, *error); } } - + + if (error) { + *error = AFErrorWithUnderlyingError(serializationError, *error);; + } + return responseObject; } diff --git a/src/ios/CordovaHttpPlugin.h b/src/ios/CordovaHttpPlugin.h index 41c1415..445bc8a 100644 --- a/src/ios/CordovaHttpPlugin.h +++ b/src/ios/CordovaHttpPlugin.h @@ -5,17 +5,13 @@ @interface CordovaHttpPlugin : CDVPlugin -- (void)setAuthorizationHeaderWithUsernameAndPassword:(CDVInvokedUrlCommand*)command; +- (void)useBasicAuth:(CDVInvokedUrlCommand*)command; - (void)setHeader:(CDVInvokedUrlCommand*)command; -- (void)setSSLPinningMode:(CDVInvokedUrlCommand*)command; -- (void)validateEntireCertificateChain:(CDVInvokedUrlCommand*)command; -- (void)allowInvalidCertificates:(CDVInvokedUrlCommand*)command; -- (void)acceptText:(CDVInvokedUrlCommand*)command; -- (void)acceptData:(CDVInvokedUrlCommand*)command; -- (void)setAcceptableContentTypes:(CDVInvokedUrlCommand*)command; +- (void)enableSSLPinning:(CDVInvokedUrlCommand*)command; +- (void)acceptAllCerts:(CDVInvokedUrlCommand*)command; - (void)post:(CDVInvokedUrlCommand*)command; - (void)get:(CDVInvokedUrlCommand*)command; - (void)uploadFile:(CDVInvokedUrlCommand*)command; - (void)downloadFile:(CDVInvokedUrlCommand*)command; -@end +@end \ No newline at end of file diff --git a/src/ios/CordovaHttpPlugin.m b/src/ios/CordovaHttpPlugin.m index a139879..54de660 100644 --- a/src/ios/CordovaHttpPlugin.m +++ b/src/ios/CordovaHttpPlugin.m @@ -3,13 +3,36 @@ #import "TextResponseSerializer.h" #import "HttpManager.h" -@implementation CordovaHttpPlugin +@interface CordovaHttpPlugin() -- (void)setAuthorizationHeaderWithUsernameAndPassword:(CDVInvokedUrlCommand*)command { +- (void)setRequestHeaders:(NSDictionary*)headers; + +@end + + +@implementation CordovaHttpPlugin { + AFHTTPRequestSerializer *requestSerializer; +} + +- (void)pluginInitialize { + requestSerializer = [AFHTTPRequestSerializer serializer]; +} + +- (void)setRequestHeaders:(NSDictionary*)headers { + [HttpManager sharedClient].requestSerializer = [AFHTTPRequestSerializer serializer]; + [requestSerializer.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [[HttpManager sharedClient].requestSerializer setValue:obj forHTTPHeaderField:key]; + }]; + [headers enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [[HttpManager sharedClient].requestSerializer setValue:obj forHTTPHeaderField:key]; + }]; +} + +- (void)useBasicAuth:(CDVInvokedUrlCommand*)command { NSString *username = [command.arguments objectAtIndex:0]; NSString *password = [command.arguments objectAtIndex:1]; - [[HttpManager sharedClient].requestSerializer setAuthorizationHeaderFieldWithUsername:username password:password]; + [requestSerializer setAuthorizationHeaderFieldWithUsername:username password:password]; CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; @@ -19,30 +42,26 @@ NSString *header = [command.arguments objectAtIndex:0]; NSString *value = [command.arguments objectAtIndex:1]; - [[HttpManager sharedClient].requestSerializer setValue:value forHTTPHeaderField: header]; + [requestSerializer setValue:value forHTTPHeaderField: header]; CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - (void)enableSSLPinning:(CDVInvokedUrlCommand*)command { - [HttpManager sharedClient].securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; + bool enable = [[command.arguments objectAtIndex:0] boolValue]; + if (enable) { + [HttpManager sharedClient].securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; + [HttpManager sharedClient].securityPolicy.validatesCertificateChain = NO; + } else { + [HttpManager sharedClient].securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; + } CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } -- (void)validateEntireCertificateChain:(CDVInvokedUrlCommand*)command { - CDVPluginResult* pluginResult = nil; - bool validate = [[command.arguments objectAtIndex:0] boolValue]; - - [HttpManager sharedClient].securityPolicy.validatesCertificateChain = validate; - - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - -- (void)allowInvalidCertificates:(CDVInvokedUrlCommand*)command { +- (void)acceptAllCerts:(CDVInvokedUrlCommand*)command { CDVPluginResult* pluginResult = nil; bool allow = [[command.arguments objectAtIndex:0] boolValue]; @@ -52,34 +71,15 @@ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } -- (void)acceptText:(CDVInvokedUrlCommand*)command { - [HttpManager sharedClient].responseSerializer = [TextResponseSerializer serializer]; - - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - -- (void)acceptData:(CDVInvokedUrlCommand*)command { - [HttpManager sharedClient].responseSerializer = [AFHTTPResponseSerializer serializer]; - - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - -- (void)setAcceptableContentTypes:(CDVInvokedUrlCommand*)command { - [HttpManager sharedClient].responseSerializer.acceptableContentTypes = [NSSet setWithArray: command.arguments]; - - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - - (void)post:(CDVInvokedUrlCommand*)command { HttpManager *manager = [HttpManager sharedClient]; NSString *url = [command.arguments objectAtIndex:0]; NSDictionary *parameters = [command.arguments objectAtIndex:1]; + NSDictionary *headers = [command.arguments objectAtIndex:2]; + [self setRequestHeaders: headers]; CordovaHttpPlugin* __weak weakSelf = self; - + manager.responseSerializer = [TextResponseSerializer serializer]; [manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; [dictionary setObject:[NSNumber numberWithInt:operation.response.statusCode] forKey:@"status"]; @@ -99,9 +99,12 @@ HttpManager *manager = [HttpManager sharedClient]; NSString *url = [command.arguments objectAtIndex:0]; NSDictionary *parameters = [command.arguments objectAtIndex:1]; + NSDictionary *headers = [command.arguments objectAtIndex:2]; + [self setRequestHeaders: headers]; CordovaHttpPlugin* __weak weakSelf = self; + manager.responseSerializer = [TextResponseSerializer serializer]; [manager GET:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; [dictionary setObject:[NSNumber numberWithInt:operation.response.statusCode] forKey:@"status"]; @@ -121,12 +124,16 @@ HttpManager *manager = [HttpManager sharedClient]; NSString *url = [command.arguments objectAtIndex:0]; NSDictionary *parameters = [command.arguments objectAtIndex:1]; - NSString *filePath = [command.arguments objectAtIndex: 2]; - NSString *name = [command.arguments objectAtIndex: 3]; + NSDictionary *headers = [command.arguments objectAtIndex:2]; + NSString *filePath = [command.arguments objectAtIndex: 3]; + NSString *name = [command.arguments objectAtIndex: 4]; NSURL *fileURL = [NSURL fileURLWithPath: filePath]; + [self setRequestHeaders: headers]; + CordovaHttpPlugin* __weak weakSelf = self; + manager.responseSerializer = [TextResponseSerializer serializer]; [manager POST:url parameters:parameters constructingBodyWithBlock:^(id formData) { NSError *error; [formData appendPartWithFileURL:fileURL name:name error:&error]; @@ -157,9 +164,13 @@ HttpManager *manager = [HttpManager sharedClient]; NSString *url = [command.arguments objectAtIndex:0]; NSDictionary *parameters = [command.arguments objectAtIndex:1]; - NSString *filePath = [command.arguments objectAtIndex: 2]; + NSDictionary *headers = [command.arguments objectAtIndex:2]; + NSString *filePath = [command.arguments objectAtIndex: 3]; + [self setRequestHeaders: headers]; + CordovaHttpPlugin* __weak weakSelf = self; + manager.responseSerializer = [AFHTTPResponseSerializer serializer]; [manager GET:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { /* * diff --git a/src/ios/TextResponseSerializer.m b/src/ios/TextResponseSerializer.m index 29660fe..39d4080 100644 --- a/src/ios/TextResponseSerializer.m +++ b/src/ios/TextResponseSerializer.m @@ -23,7 +23,7 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) { return nil; } - self.acceptableContentTypes = [NSSet setWithObjects:@"text/*", nil]; + self.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"text/html", @"text/json", @"application/json", @"text/xml", @"application/xml", @"text/css", nil]; return self; }