Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

CordovaHttpPlugin.m 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. #import "CordovaHttpPlugin.h"
  2. #import "CDVFile.h"
  3. #import "BinaryRequestSerializer.h"
  4. #import "BinaryResponseSerializer.h"
  5. #import "TextResponseSerializer.h"
  6. #import "TextRequestSerializer.h"
  7. #import "AFHTTPSessionManager.h"
  8. #import "SDNetworkActivityIndicator.h"
  9. @interface CordovaHttpPlugin()
  10. - (void)setRequestHeaders:(NSDictionary*)headers forManager:(AFHTTPSessionManager*)manager;
  11. - (void)handleSuccess:(NSMutableDictionary*)dictionary withResponse:(NSHTTPURLResponse*)response andData:(id)data;
  12. - (void)handleError:(NSMutableDictionary*)dictionary withResponse:(NSHTTPURLResponse*)response error:(NSError*)error;
  13. - (NSNumber*)getStatusCode:(NSError*) error;
  14. - (NSMutableDictionary*)copyHeaderFields:(NSDictionary*)headerFields;
  15. - (void)setTimeout:(NSTimeInterval)timeout forManager:(AFHTTPSessionManager*)manager;
  16. - (void)setRedirect:(bool)redirect forManager:(AFHTTPSessionManager*)manager;
  17. @end
  18. @implementation CordovaHttpPlugin {
  19. AFSecurityPolicy *securityPolicy;
  20. NSURLCredential *x509Credential;
  21. }
  22. - (void)pluginInitialize {
  23. securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
  24. }
  25. - (void)setRequestSerializer:(NSString*)serializerName forManager:(AFHTTPSessionManager*)manager {
  26. if ([serializerName isEqualToString:@"json"]) {
  27. manager.requestSerializer = [AFJSONRequestSerializer serializer];
  28. } else if ([serializerName isEqualToString:@"utf8"]) {
  29. manager.requestSerializer = [TextRequestSerializer serializer];
  30. } else if ([serializerName isEqualToString:@"raw"]) {
  31. manager.requestSerializer = [BinaryRequestSerializer serializer];
  32. } else {
  33. manager.requestSerializer = [AFHTTPRequestSerializer serializer];
  34. }
  35. }
  36. - (void)setupAuthChallengeBlock:(AFHTTPSessionManager*)manager {
  37. [manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(
  38. NSURLSession * _Nonnull session,
  39. NSURLAuthenticationChallenge * _Nonnull challenge,
  40. NSURLCredential * _Nullable __autoreleasing * _Nullable credential
  41. ) {
  42. if ([challenge.protectionSpace.authenticationMethod isEqualToString: NSURLAuthenticationMethodServerTrust]) {
  43. *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
  44. if (![self->securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
  45. return NSURLSessionAuthChallengeRejectProtectionSpace;
  46. }
  47. if (credential) {
  48. return NSURLSessionAuthChallengeUseCredential;
  49. }
  50. }
  51. if ([challenge.protectionSpace.authenticationMethod isEqualToString: NSURLAuthenticationMethodClientCertificate] && self->x509Credential) {
  52. *credential = self->x509Credential;
  53. return NSURLSessionAuthChallengeUseCredential;
  54. }
  55. return NSURLSessionAuthChallengePerformDefaultHandling;
  56. }];
  57. }
  58. - (void)setRequestHeaders:(NSDictionary*)headers forManager:(AFHTTPSessionManager*)manager {
  59. [headers enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
  60. [manager.requestSerializer setValue:obj forHTTPHeaderField:key];
  61. }];
  62. }
  63. - (void)setRedirect:(bool)followRedirect forManager:(AFHTTPSessionManager*)manager {
  64. [manager setTaskWillPerformHTTPRedirectionBlock:^NSURLRequest * _Nonnull(NSURLSession * _Nonnull session,
  65. NSURLSessionTask * _Nonnull task, NSURLResponse * _Nonnull response, NSURLRequest * _Nonnull request) {
  66. if (followRedirect) {
  67. return request;
  68. } else {
  69. return nil;
  70. }
  71. }];
  72. }
  73. - (void)setTimeout:(NSTimeInterval)timeout forManager:(AFHTTPSessionManager*)manager {
  74. [manager.requestSerializer setTimeoutInterval:timeout];
  75. }
  76. - (void)setResponseSerializer:(NSString*)responseType forManager:(AFHTTPSessionManager*)manager {
  77. if ([responseType isEqualToString: @"text"] || [responseType isEqualToString: @"json"]) {
  78. manager.responseSerializer = [TextResponseSerializer serializer];
  79. } else {
  80. manager.responseSerializer = [BinaryResponseSerializer serializer];
  81. }
  82. }
  83. - (void)handleSuccess:(NSMutableDictionary*)dictionary withResponse:(NSHTTPURLResponse*)response andData:(id)data {
  84. if (response != nil) {
  85. [dictionary setValue:response.URL.absoluteString forKey:@"url"];
  86. [dictionary setObject:[NSNumber numberWithInt:(int)response.statusCode] forKey:@"status"];
  87. [dictionary setObject:[self copyHeaderFields:response.allHeaderFields] forKey:@"headers"];
  88. }
  89. if (data != nil) {
  90. [dictionary setObject:data forKey:@"data"];
  91. }
  92. }
  93. - (void)handleError:(NSMutableDictionary*)dictionary withResponse:(NSHTTPURLResponse*)response error:(NSError*)error {
  94. if (response != nil) {
  95. [dictionary setValue:response.URL.absoluteString forKey:@"url"];
  96. [dictionary setObject:[NSNumber numberWithInt:(int)response.statusCode] forKey:@"status"];
  97. [dictionary setObject:[self copyHeaderFields:response.allHeaderFields] forKey:@"headers"];
  98. if (error.userInfo[AFNetworkingOperationFailingURLResponseBodyErrorKey]) {
  99. [dictionary setObject:error.userInfo[AFNetworkingOperationFailingURLResponseBodyErrorKey] forKey:@"error"];
  100. }
  101. } else {
  102. [dictionary setObject:[self getStatusCode:error] forKey:@"status"];
  103. [dictionary setObject:[error localizedDescription] forKey:@"error"];
  104. }
  105. }
  106. - (void)handleException:(NSException*)exception withCommand:(CDVInvokedUrlCommand*)command {
  107. CordovaHttpPlugin* __weak weakSelf = self;
  108. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  109. [dictionary setValue:exception.userInfo forKey:@"error"];
  110. [dictionary setObject:[NSNumber numberWithInt:-1] forKey:@"status"];
  111. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
  112. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  113. }
  114. - (NSNumber*)getStatusCode:(NSError*) error {
  115. switch ([error code]) {
  116. case -1001:
  117. // timeout
  118. return [NSNumber numberWithInt:-4];
  119. case -1002:
  120. // unsupported URL
  121. return [NSNumber numberWithInt:-5];
  122. case -1003:
  123. // server not found
  124. return [NSNumber numberWithInt:-3];
  125. case -1009:
  126. // no connection
  127. return [NSNumber numberWithInt:-6];
  128. case -1200: // secure connection failed
  129. case -1201: // certificate has bad date
  130. case -1202: // certificate untrusted
  131. case -1203: // certificate has unknown root
  132. case -1204: // certificate is not yet valid
  133. // configuring SSL failed
  134. return [NSNumber numberWithInt:-2];
  135. default:
  136. return [NSNumber numberWithInt:-1];
  137. }
  138. }
  139. - (NSMutableDictionary*)copyHeaderFields:(NSDictionary *)headerFields {
  140. NSMutableDictionary *headerFieldsCopy = [[NSMutableDictionary alloc] initWithCapacity:headerFields.count];
  141. NSString *headerKeyCopy;
  142. for (NSString *headerKey in headerFields.allKeys) {
  143. headerKeyCopy = [[headerKey mutableCopy] lowercaseString];
  144. [headerFieldsCopy setValue:[headerFields objectForKey:headerKey] forKey:headerKeyCopy];
  145. }
  146. return headerFieldsCopy;
  147. }
  148. - (void)executeRequestWithoutData:(CDVInvokedUrlCommand*)command withMethod:(NSString*) method {
  149. AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
  150. NSString *url = [command.arguments objectAtIndex:0];
  151. NSDictionary *headers = [command.arguments objectAtIndex:1];
  152. NSTimeInterval timeoutInSeconds = [[command.arguments objectAtIndex:2] doubleValue];
  153. bool followRedirect = [[command.arguments objectAtIndex:3] boolValue];
  154. NSString *responseType = [command.arguments objectAtIndex:4];
  155. [self setRequestSerializer: @"default" forManager: manager];
  156. [self setupAuthChallengeBlock: manager];
  157. [self setRequestHeaders: headers forManager: manager];
  158. [self setTimeout:timeoutInSeconds forManager:manager];
  159. [self setRedirect:followRedirect forManager:manager];
  160. [self setResponseSerializer:responseType forManager:manager];
  161. CordovaHttpPlugin* __weak weakSelf = self;
  162. [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
  163. @try {
  164. void (^onSuccess)(NSURLSessionTask *, id) = ^(NSURLSessionTask *task, id responseObject) {
  165. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  166. // no 'body' for HEAD request, omitting 'data'
  167. if ([method isEqualToString:@"HEAD"]) {
  168. [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:nil];
  169. } else {
  170. [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject];
  171. }
  172. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
  173. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  174. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  175. };
  176. void (^onFailure)(NSURLSessionTask *, NSError *) = ^(NSURLSessionTask *task, NSError *error) {
  177. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  178. [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
  179. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
  180. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  181. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  182. };
  183. [manager downloadTaskWithHTTPMethod:method URLString:url parameters:nil progress:nil success:onSuccess failure:onFailure];
  184. }
  185. @catch (NSException *exception) {
  186. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  187. [self handleException:exception withCommand:command];
  188. }
  189. }
  190. - (void)executeRequestWithData:(CDVInvokedUrlCommand*)command withMethod:(NSString*)method {
  191. AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
  192. NSString *url = [command.arguments objectAtIndex:0];
  193. NSDictionary *data = [command.arguments objectAtIndex:1];
  194. NSString *serializerName = [command.arguments objectAtIndex:2];
  195. NSDictionary *headers = [command.arguments objectAtIndex:3];
  196. NSTimeInterval timeoutInSeconds = [[command.arguments objectAtIndex:4] doubleValue];
  197. bool followRedirect = [[command.arguments objectAtIndex:5] boolValue];
  198. NSString *responseType = [command.arguments objectAtIndex:6];
  199. [self setRequestSerializer: serializerName forManager: manager];
  200. [self setupAuthChallengeBlock: manager];
  201. [self setRequestHeaders: headers forManager: manager];
  202. [self setTimeout:timeoutInSeconds forManager:manager];
  203. [self setRedirect:followRedirect forManager:manager];
  204. [self setResponseSerializer:responseType forManager:manager];
  205. CordovaHttpPlugin* __weak weakSelf = self;
  206. [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
  207. @try {
  208. void (^constructBody)(id<AFMultipartFormData>) = ^(id<AFMultipartFormData> formData) {
  209. NSArray *buffers = [data mutableArrayValueForKey:@"buffers"];
  210. NSArray *fileNames = [data mutableArrayValueForKey:@"fileNames"];
  211. NSArray *names = [data mutableArrayValueForKey:@"names"];
  212. NSArray *types = [data mutableArrayValueForKey:@"types"];
  213. NSError *error;
  214. for (int i = 0; i < [buffers count]; ++i) {
  215. NSData *decodedBuffer = [[NSData alloc] initWithBase64EncodedString:[buffers objectAtIndex:i] options:0];
  216. NSString *fileName = [fileNames objectAtIndex:i];
  217. NSString *partName = [names objectAtIndex:i];
  218. NSString *partType = [types objectAtIndex:i];
  219. if (![fileName isEqual:[NSNull null]]) {
  220. [formData appendPartWithFileData:decodedBuffer name:partName fileName:fileName mimeType:partType];
  221. } else {
  222. [formData appendPartWithFormData:decodedBuffer name:[names objectAtIndex:i]];
  223. }
  224. }
  225. if (error) {
  226. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  227. [dictionary setObject:[NSNumber numberWithInt:400] forKey:@"status"];
  228. [dictionary setObject:@"Could not add part to multipart request body." forKey:@"error"];
  229. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
  230. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  231. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  232. return;
  233. }
  234. };
  235. void (^onSuccess)(NSURLSessionTask *, id) = ^(NSURLSessionTask *task, id responseObject) {
  236. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  237. [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject];
  238. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
  239. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  240. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  241. };
  242. void (^onFailure)(NSURLSessionTask *, NSError *) = ^(NSURLSessionTask *task, NSError *error) {
  243. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  244. [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
  245. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
  246. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  247. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  248. };
  249. if ([serializerName isEqualToString:@"multipart"]) {
  250. [manager uploadTaskWithHTTPMethod:method URLString:url parameters:nil constructingBodyWithBlock:constructBody progress:nil success:onSuccess failure:onFailure];
  251. } else {
  252. [manager uploadTaskWithHTTPMethod:method URLString:url parameters:data progress:nil success:onSuccess failure:onFailure];
  253. }
  254. }
  255. @catch (NSException *exception) {
  256. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  257. [self handleException:exception withCommand:command];
  258. }
  259. }
  260. - (void)setServerTrustMode:(CDVInvokedUrlCommand*)command {
  261. NSString *certMode = [command.arguments objectAtIndex:0];
  262. if ([certMode isEqualToString: @"default"] || [certMode isEqualToString: @"legacy"]) {
  263. securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
  264. securityPolicy.allowInvalidCertificates = NO;
  265. securityPolicy.validatesDomainName = YES;
  266. } else if ([certMode isEqualToString: @"nocheck"]) {
  267. securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
  268. securityPolicy.allowInvalidCertificates = YES;
  269. securityPolicy.validatesDomainName = NO;
  270. } else if ([certMode isEqualToString: @"pinned"]) {
  271. securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
  272. securityPolicy.allowInvalidCertificates = NO;
  273. securityPolicy.validatesDomainName = YES;
  274. }
  275. CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
  276. [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  277. }
  278. - (void)setClientAuthMode:(CDVInvokedUrlCommand*)command {
  279. CDVPluginResult* pluginResult;
  280. NSString *mode = [command.arguments objectAtIndex:0];
  281. if ([mode isEqualToString:@"none"]) {
  282. x509Credential = nil;
  283. pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
  284. }
  285. if ([mode isEqualToString:@"systemstore"]) {
  286. NSString *alias = [command.arguments objectAtIndex:1];
  287. // TODO
  288. pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"mode 'systemstore' is not supported on iOS"];
  289. }
  290. if ([mode isEqualToString:@"buffer"]) {
  291. CFDataRef container = (__bridge CFDataRef) [command.arguments objectAtIndex:2];
  292. CFStringRef password = (__bridge CFStringRef) [command.arguments objectAtIndex:3];
  293. const void *keys[] = { kSecImportExportPassphrase };
  294. const void *values[] = { password };
  295. CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
  296. CFArrayRef items;
  297. OSStatus securityError = SecPKCS12Import(container, options, &items);
  298. CFRelease(options);
  299. if (securityError != noErr) {
  300. pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
  301. } else {
  302. CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
  303. SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
  304. self->x509Credential = [NSURLCredential credentialWithIdentity:identity certificates: nil persistence:NSURLCredentialPersistenceForSession];
  305. CFRelease(items);
  306. pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
  307. }
  308. }
  309. [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  310. }
  311. - (void)post:(CDVInvokedUrlCommand*)command {
  312. [self executeRequestWithData: command withMethod:@"POST"];
  313. }
  314. - (void)put:(CDVInvokedUrlCommand*)command {
  315. [self executeRequestWithData: command withMethod:@"PUT"];
  316. }
  317. - (void)patch:(CDVInvokedUrlCommand*)command {
  318. [self executeRequestWithData: command withMethod:@"PATCH"];
  319. }
  320. - (void)get:(CDVInvokedUrlCommand*)command {
  321. [self executeRequestWithoutData: command withMethod:@"GET"];
  322. }
  323. - (void)delete:(CDVInvokedUrlCommand*)command {
  324. [self executeRequestWithoutData: command withMethod:@"DELETE"];
  325. }
  326. - (void)head:(CDVInvokedUrlCommand*)command {
  327. [self executeRequestWithoutData: command withMethod:@"HEAD"];
  328. }
  329. - (void)options:(CDVInvokedUrlCommand*)command {
  330. [self executeRequestWithoutData: command withMethod:@"OPTIONS"];
  331. }
  332. - (void)uploadFiles:(CDVInvokedUrlCommand*)command {
  333. AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
  334. NSString *url = [command.arguments objectAtIndex:0];
  335. NSDictionary *headers = [command.arguments objectAtIndex:1];
  336. NSArray *filePaths = [command.arguments objectAtIndex: 2];
  337. NSArray *names = [command.arguments objectAtIndex: 3];
  338. NSTimeInterval timeoutInSeconds = [[command.arguments objectAtIndex:4] doubleValue];
  339. bool followRedirect = [[command.arguments objectAtIndex:5] boolValue];
  340. NSString *responseType = [command.arguments objectAtIndex:6];
  341. [self setRequestHeaders: headers forManager: manager];
  342. [self setupAuthChallengeBlock: manager];
  343. [self setTimeout:timeoutInSeconds forManager:manager];
  344. [self setRedirect:followRedirect forManager:manager];
  345. [self setResponseSerializer:responseType forManager:manager];
  346. CordovaHttpPlugin* __weak weakSelf = self;
  347. [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
  348. @try {
  349. [manager POST:url parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
  350. NSError *error;
  351. for (int i = 0; i < [filePaths count]; i++) {
  352. NSString *filePath = (NSString *) [filePaths objectAtIndex:i];
  353. NSString *uploadName = (NSString *) [names objectAtIndex:i];
  354. NSURL *fileURL = [NSURL URLWithString: filePath];
  355. [formData appendPartWithFileURL:fileURL name:uploadName error:&error];
  356. }
  357. if (error) {
  358. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  359. [dictionary setObject:[NSNumber numberWithInt:500] forKey:@"status"];
  360. [dictionary setObject:@"Could not add file to post body." forKey:@"error"];
  361. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
  362. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  363. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  364. return;
  365. }
  366. } progress:nil success:^(NSURLSessionTask *task, id responseObject) {
  367. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  368. [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject];
  369. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
  370. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  371. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  372. } failure:^(NSURLSessionTask *task, NSError *error) {
  373. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  374. [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
  375. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
  376. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  377. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  378. }];
  379. }
  380. @catch (NSException *exception) {
  381. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  382. [self handleException:exception withCommand:command];
  383. }
  384. }
  385. - (void)downloadFile:(CDVInvokedUrlCommand*)command {
  386. AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
  387. manager.responseSerializer = [AFHTTPResponseSerializer serializer];
  388. NSString *url = [command.arguments objectAtIndex:0];
  389. NSDictionary *headers = [command.arguments objectAtIndex:1];
  390. NSString *filePath = [command.arguments objectAtIndex: 2];
  391. NSTimeInterval timeoutInSeconds = [[command.arguments objectAtIndex:3] doubleValue];
  392. bool followRedirect = [[command.arguments objectAtIndex:4] boolValue];
  393. [self setRequestHeaders: headers forManager: manager];
  394. [self setupAuthChallengeBlock: manager];
  395. [self setTimeout:timeoutInSeconds forManager:manager];
  396. [self setRedirect:followRedirect forManager:manager];
  397. if ([filePath hasPrefix:@"file://"]) {
  398. filePath = [filePath substringFromIndex:7];
  399. }
  400. CordovaHttpPlugin* __weak weakSelf = self;
  401. [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
  402. @try {
  403. [manager GET:url parameters:nil progress: nil success:^(NSURLSessionTask *task, id responseObject) {
  404. /*
  405. *
  406. * Licensed to the Apache Software Foundation (ASF) under one
  407. * or more contributor license agreements. See the NOTICE file
  408. * distributed with this work for additional information
  409. * regarding copyright ownership. The ASF licenses this file
  410. * to you under the Apache License, Version 2.0 (the
  411. * "License"); you may not use this file except in compliance
  412. * with the License. You may obtain a copy of the License at
  413. *
  414. * http://www.apache.org/licenses/LICENSE-2.0
  415. *
  416. * Unless required by applicable law or agreed to in writing,
  417. * software distributed under the License is distributed on an
  418. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  419. * KIND, either express or implied. See the License for the
  420. * specific language governing permissions and limitations
  421. * under the License.
  422. *
  423. * Modified by Andrew Stephan for Sync OnSet
  424. *
  425. */
  426. // Download response is okay; begin streaming output to file
  427. NSString* parentPath = [filePath stringByDeletingLastPathComponent];
  428. // create parent directories if needed
  429. NSError *error;
  430. if ([[NSFileManager defaultManager] createDirectoryAtPath:parentPath withIntermediateDirectories:YES attributes:nil error:&error] == NO) {
  431. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  432. [dictionary setObject:[NSNumber numberWithInt:500] forKey:@"status"];
  433. if (error) {
  434. [dictionary setObject:[NSString stringWithFormat:@"Could not create path to save downloaded file: %@", [error localizedDescription]] forKey:@"error"];
  435. } else {
  436. [dictionary setObject:@"Could not create path to save downloaded file" forKey:@"error"];
  437. }
  438. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
  439. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  440. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  441. return;
  442. }
  443. NSData *data = (NSData *)responseObject;
  444. if (![data writeToFile:filePath atomically:YES]) {
  445. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  446. [dictionary setObject:[NSNumber numberWithInt:500] forKey:@"status"];
  447. [dictionary setObject:@"Could not write the data to the given filePath." forKey:@"error"];
  448. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
  449. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  450. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  451. return;
  452. }
  453. id filePlugin = [self.commandDelegate getCommandInstance:@"File"];
  454. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  455. [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:nil];
  456. [dictionary setObject:[filePlugin getDirectoryEntry:filePath isDirectory:NO] forKey:@"file"];
  457. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
  458. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  459. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  460. } failure:^(NSURLSessionTask *task, NSError *error) {
  461. NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
  462. [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
  463. [dictionary setObject:@"There was an error downloading the file" forKey:@"error"];
  464. CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
  465. [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
  466. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  467. }];
  468. }
  469. @catch (NSException *exception) {
  470. [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
  471. [self handleException:exception withCommand:command];
  472. }
  473. }
  474. @end