diff --git a/plugin.xml b/plugin.xml index c8ef95f..34b42bf 100644 --- a/plugin.xml +++ b/plugin.xml @@ -10,9 +10,11 @@ + + @@ -24,6 +26,7 @@ + @@ -33,6 +36,7 @@ + @@ -64,4 +68,4 @@ - \ No newline at end of file + diff --git a/src/android/com/synconset/cordovahttp/CordovaHttp.java b/src/android/com/synconset/cordovahttp/CordovaHttp.java index 0dfd3fb..0c008c2 100644 --- a/src/android/com/synconset/cordovahttp/CordovaHttp.java +++ b/src/android/com/synconset/cordovahttp/CordovaHttp.java @@ -144,7 +144,11 @@ abstract class CordovaHttp { if (new String("json").equals(this.getSerializerName())) { request.contentType(request.CONTENT_TYPE_JSON, request.CHARSET_UTF8); request.send(this.getParamsObject().toString()); - } else { + } else if (new String("utf8").equals(this.getSerializerName())) { + request.contentType("text/plain", request.CHARSET_UTF8); + request.send(this.getParamsMap().get("text").toString()); + } else + { request.form(this.getParamsMap()); } diff --git a/src/ios/CordovaHttpPlugin.m b/src/ios/CordovaHttpPlugin.m index 6f64cd9..6f34c8b 100644 --- a/src/ios/CordovaHttpPlugin.m +++ b/src/ios/CordovaHttpPlugin.m @@ -1,6 +1,7 @@ #import "CordovaHttpPlugin.h" #import "CDVFile.h" #import "TextResponseSerializer.h" +#import "TextRequestSerializer.h" #import "AFHTTPSessionManager.h" @interface CordovaHttpPlugin() @@ -28,6 +29,8 @@ - (void)setRequestSerializer:(NSString*)serializerName forManager:(AFHTTPSessionManager*)manager { if ([serializerName isEqualToString:@"json"]) { manager.requestSerializer = [AFJSONRequestSerializer serializer]; + } else if ([serializerName isEqualToString:@"utf8"]) { + manager.requestSerializer = [TextRequestSerializer serializer]; } else { manager.requestSerializer = [AFHTTPRequestSerializer serializer]; } @@ -73,6 +76,17 @@ } } +- (void)handleException:(NSException*)exception withCommand:(CDVInvokedUrlCommand*)command { + CordovaHttpPlugin* __weak weakSelf = self; + + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [dictionary setValue:exception.userInfo forKey:@"error"]; + [dictionary setObject:[NSNumber numberWithInt:-1] forKey:@"status"]; + + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; +} + - (NSNumber*)getStatusCode:(NSError*) error { switch ([error code]) { case -1001: @@ -159,19 +173,25 @@ CordovaHttpPlugin* __weak weakSelf = self; manager.responseSerializer = [TextResponseSerializer serializer]; - [manager POST:url parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } failure:^(NSURLSessionTask *task, NSError *error) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + @try { + [manager POST:url parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } failure:^(NSURLSessionTask *task, NSError *error) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + }]; + } + @catch (NSException *exception) { + [self handleException:exception withCommand:command]; + } } - (void)get:(CDVInvokedUrlCommand*)command { @@ -190,21 +210,26 @@ [self setRedirect: manager]; CordovaHttpPlugin* __weak weakSelf = self; - manager.responseSerializer = [TextResponseSerializer serializer]; - [manager GET:url parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } failure:^(NSURLSessionTask *task, NSError *error) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + @try { + [manager GET:url parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } failure:^(NSURLSessionTask *task, NSError *error) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + }]; + } + @catch (NSException *exception) { + [self handleException:exception withCommand:command]; + } } - (void)put:(CDVInvokedUrlCommand*)command { @@ -224,19 +249,25 @@ CordovaHttpPlugin* __weak weakSelf = self; manager.responseSerializer = [TextResponseSerializer serializer]; - [manager PUT:url parameters:parameters success:^(NSURLSessionTask *task, id responseObject) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } failure:^(NSURLSessionTask *task, NSError *error) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + @try { + [manager PUT:url parameters:parameters success:^(NSURLSessionTask *task, id responseObject) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } failure:^(NSURLSessionTask *task, NSError *error) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + }]; + } + @catch (NSException *exception) { + [self handleException:exception withCommand:command]; + } } - (void)patch:(CDVInvokedUrlCommand*)command { @@ -256,19 +287,25 @@ CordovaHttpPlugin* __weak weakSelf = self; manager.responseSerializer = [TextResponseSerializer serializer]; - [manager PATCH:url parameters:parameters success:^(NSURLSessionTask *task, id responseObject) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } failure:^(NSURLSessionTask *task, NSError *error) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + @try { + [manager PATCH:url parameters:parameters success:^(NSURLSessionTask *task, id responseObject) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } failure:^(NSURLSessionTask *task, NSError *error) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + }]; + } + @catch (NSException *exception) { + [self handleException:exception withCommand:command]; + } } - (void)delete:(CDVInvokedUrlCommand*)command { @@ -286,21 +323,26 @@ [self setRedirect: manager]; CordovaHttpPlugin* __weak weakSelf = self; - manager.responseSerializer = [TextResponseSerializer serializer]; - [manager DELETE:url parameters:parameters success:^(NSURLSessionTask *task, id responseObject) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } failure:^(NSURLSessionTask *task, NSError *error) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + @try { + [manager DELETE:url parameters:parameters success:^(NSURLSessionTask *task, id responseObject) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } failure:^(NSURLSessionTask *task, NSError *error) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + }]; + } + @catch (NSException *exception) { + [self handleException:exception withCommand:command]; + } } - (void)head:(CDVInvokedUrlCommand*)command { @@ -316,22 +358,27 @@ [self setRedirect: manager]; CordovaHttpPlugin* __weak weakSelf = self; - manager.responseSerializer = [AFHTTPResponseSerializer serializer]; - [manager HEAD:url parameters:parameters success:^(NSURLSessionTask *task) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - // no 'body' for HEAD request, omitting 'data' - [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:nil]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } failure:^(NSURLSessionTask *task, NSError *error) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + @try { + [manager HEAD:url parameters:parameters success:^(NSURLSessionTask *task) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + // no 'body' for HEAD request, omitting 'data' + [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:nil]; - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } failure:^(NSURLSessionTask *task, NSError *error) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + }]; + } + @catch (NSException *exception) { + [self handleException:exception withCommand:command]; + } } - (void)uploadFile:(CDVInvokedUrlCommand*)command { @@ -353,30 +400,36 @@ 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]; - if (error) { + + @try { + [manager POST:url parameters:parameters constructingBodyWithBlock:^(id formData) { + NSError *error; + [formData appendPartWithFileURL:fileURL name:name error:&error]; + if (error) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [dictionary setObject:[NSNumber numberWithInt:500] forKey:@"status"]; + [dictionary setObject:@"Could not add file to post body." forKey:@"error"]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } + } progress:nil success:^(NSURLSessionTask *task, id responseObject) { NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [dictionary setObject:[NSNumber numberWithInt:500] forKey:@"status"]; - [dictionary setObject:@"Could not add file to post body." forKey:@"error"]; + [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; + + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } failure:^(NSURLSessionTask *task, NSError *error) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - return; - } - } progress:nil success:^(NSURLSessionTask *task, id responseObject) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject]; - - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } failure:^(NSURLSessionTask *task, NSError *error) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; - - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; + }]; + } + @catch (NSException *exception) { + [self handleException:exception withCommand:command]; + } } @@ -400,70 +453,76 @@ CordovaHttpPlugin* __weak weakSelf = self; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; - [manager GET:url parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject) { - /* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - * Modified by Andrew Stephan for Sync OnSet - * - */ - // Download response is okay; begin streaming output to file - NSString* parentPath = [filePath stringByDeletingLastPathComponent]; - // create parent directories if needed - NSError *error; - if ([[NSFileManager defaultManager] createDirectoryAtPath:parentPath withIntermediateDirectories:YES attributes:nil error:&error] == NO) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [dictionary setObject:[NSNumber numberWithInt:500] forKey:@"status"]; - if (error) { - [dictionary setObject:[NSString stringWithFormat:@"Could not create path to save downloaded file: %@", [error localizedDescription]] forKey:@"error"]; - } else { - [dictionary setObject:@"Could not create path to save downloaded file" forKey:@"error"]; + @try { + [manager GET:url parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject) { + /* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * Modified by Andrew Stephan for Sync OnSet + * + */ + // Download response is okay; begin streaming output to file + NSString* parentPath = [filePath stringByDeletingLastPathComponent]; + + // create parent directories if needed + NSError *error; + if ([[NSFileManager defaultManager] createDirectoryAtPath:parentPath withIntermediateDirectories:YES attributes:nil error:&error] == NO) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [dictionary setObject:[NSNumber numberWithInt:500] forKey:@"status"]; + if (error) { + [dictionary setObject:[NSString stringWithFormat:@"Could not create path to save downloaded file: %@", [error localizedDescription]] forKey:@"error"]; + } else { + [dictionary setObject:@"Could not create path to save downloaded file" forKey:@"error"]; + } + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; } - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - return; - } - NSData *data = (NSData *)responseObject; - if (![data writeToFile:filePath atomically:YES]) { + NSData *data = (NSData *)responseObject; + if (![data writeToFile:filePath atomically:YES]) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [dictionary setObject:[NSNumber numberWithInt:500] forKey:@"status"]; + [dictionary setObject:@"Could not write the data to the given filePath." forKey:@"error"]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } + + id filePlugin = [self.commandDelegate getCommandInstance:@"File"]; NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [dictionary setObject:[NSNumber numberWithInt:500] forKey:@"status"]; - [dictionary setObject:@"Could not write the data to the given filePath." forKey:@"error"]; + [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:nil]; + [dictionary setObject:[filePlugin getDirectoryEntry:filePath isDirectory:NO] forKey:@"file"]; + + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; + [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } failure:^(NSURLSessionTask *task, NSError *error) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - return; - } - - id filePlugin = [self.commandDelegate getCommandInstance:@"File"]; - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:nil]; - [dictionary setObject:[filePlugin getDirectoryEntry:filePath isDirectory:NO] forKey:@"file"]; - - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } failure:^(NSURLSessionTask *task, NSError *error) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - [self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error]; - - CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary]; - [weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; + }]; + } + @catch (NSException *exception) { + [self handleException:exception withCommand:command]; + } } @end diff --git a/src/ios/TextRequestSerializer.h b/src/ios/TextRequestSerializer.h new file mode 100644 index 0000000..56ddad4 --- /dev/null +++ b/src/ios/TextRequestSerializer.h @@ -0,0 +1,8 @@ +#import +#import "AFURLRequestSerialization.h" + +@interface TextRequestSerializer : AFHTTPRequestSerializer + ++ (instancetype)serializer; + +@end diff --git a/src/ios/TextRequestSerializer.m b/src/ios/TextRequestSerializer.m new file mode 100644 index 0000000..31c1c2e --- /dev/null +++ b/src/ios/TextRequestSerializer.m @@ -0,0 +1,53 @@ +#import "TextRequestSerializer.h" + +@implementation TextRequestSerializer + ++ (instancetype)serializer +{ + TextRequestSerializer *serializer = [[self alloc] init]; + return serializer; +} + +#pragma mark - AFURLRequestSerialization + +- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request + withParameters:(id)parameters + error:(NSError *__autoreleasing *)error +{ + NSParameterAssert(request); + + if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) { + return [super requestBySerializingRequest:request withParameters:parameters error:error]; + } + + NSMutableURLRequest *mutableRequest = [request mutableCopy]; + + [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) { + if (![request valueForHTTPHeaderField:field]) { + [mutableRequest setValue:value forHTTPHeaderField:field]; + } + }]; + + if (parameters) { + if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) { + [mutableRequest setValue:@"text/plain; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; + } + + [mutableRequest setHTTPBody: [[parameters valueForKey:@"text"] dataUsingEncoding:NSUTF8StringEncoding]]; + } + + return mutableRequest; +} + +#pragma mark - NSSecureCoding + +- (instancetype)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (!self) { + return nil; + } + + return self; +} + +@end diff --git a/test/app-test-definitions.js b/test/app-test-definitions.js index 1c687a3..0fbc3fe 100644 --- a/test/app-test-definitions.js +++ b/test/app-test-definitions.js @@ -8,6 +8,7 @@ const hooks = { const helpers = { acceptAllCerts: function(done) { cordova.plugin.http.acceptAllCerts(true, done, done); }, setJsonSerializer: function(done) { done(cordova.plugin.http.setDataSerializer('json')); }, + setUtf8StringSerializer: function(done) { done(cordova.plugin.http.setDataSerializer('utf8')); }, setUrlEncodedSerializer: function(done) { done(cordova.plugin.http.setDataSerializer('urlencoded')); }, getWithXhr: function(done, url) { var xhr = new XMLHttpRequest(); @@ -382,6 +383,17 @@ const tests = [ cookies.myCookie.should.be.equal('myValue'); cookies.mySecondCookie.should.be.equal('mySecondValue'); } + },{ + description: 'should send UTF-8 encoded raw string correctly (POST)', + expected: 'resolved: {"status": 200, "data": "{\\"data\\": \\"this is a test string\\"...', + before: helpers.setUtf8StringSerializer, + func: function(resolve, reject) { + cordova.plugin.http.post('http://httpbin.org/anything', 'this is a test string', {}, resolve, reject); + }, + validationFunc: function(driver, result) { + result.type.should.be.equal('resolved'); + JSON.parse(result.data.data).data.should.eql('this is a test string'); + } } ]; diff --git a/test/js-mocha-specs.js b/test/js-mocha-specs.js index d9a7c5b..4ad48a3 100644 --- a/test/js-mocha-specs.js +++ b/test/js-mocha-specs.js @@ -3,12 +3,18 @@ const mock = require('mock-require'); const path = require('path'); const should = chai.should(); + +const HELPERS_ID = path.resolve(__dirname, '..', 'www', 'helpers'); const PLUGIN_ID = path.resolve(__dirname, '..', 'www', 'advanced-http'); describe('Advanced HTTP www interface', function() { let http = {}; + let helpers = {}; + const noop = () => { /* intentionally doing nothing */ }; + const loadHttp = () => { + mock(`${PLUGIN_ID}.helpers`, mock.reRequire('../www/helpers')); http = mock.reRequire('../www/advanced-http'); }; @@ -19,8 +25,12 @@ describe('Advanced HTTP www interface', function() { global.btoa = decoded => new Buffer(decoded).toString('base64'); mock('cordova/exec', noop); - mock(`${PLUGIN_ID}.angular-integration`, { registerService: noop }); mock(`${PLUGIN_ID}.cookie-handler`, {}); + mock(`${HELPERS_ID}.cookie-handler`, {}); + mock(`${PLUGIN_ID}.messages`, require('../www/messages')); + mock(`${HELPERS_ID}.messages`, require('../www/messages')); + mock(`${PLUGIN_ID}.angular-integration`, { registerService: noop }); + loadHttp(); }); @@ -40,7 +50,7 @@ describe('Advanced HTTP www interface', function() { }); it('resolves global headers correctly #24', () => { - mock(`${PLUGIN_ID}.cookie-handler`, { + mock(`${HELPERS_ID}.cookie-handler`, { getCookieString: () => 'fakeCookieString' }); @@ -59,7 +69,7 @@ describe('Advanced HTTP www interface', function() { }); it('resolves host headers correctly (set without port number) #37', () => { - mock(`${PLUGIN_ID}.cookie-handler`, { + mock(`${HELPERS_ID}.cookie-handler`, { getCookieString: () => 'fakeCookieString' }); @@ -78,7 +88,7 @@ describe('Advanced HTTP www interface', function() { }); it('resolves host headers correctly (set with port number) #37', () => { - mock(`${PLUGIN_ID}.cookie-handler`, { + mock(`${HELPERS_ID}.cookie-handler`, { getCookieString: () => 'fakeCookieString' }); @@ -97,7 +107,7 @@ describe('Advanced HTTP www interface', function() { }); it('resolves request headers correctly', () => { - mock(`${PLUGIN_ID}.cookie-handler`, { + mock(`${HELPERS_ID}.cookie-handler`, { getCookieString: () => 'fakeCookieString' }); diff --git a/www/advanced-http.js b/www/advanced-http.js index fc13358..82076e4 100644 --- a/www/advanced-http.js +++ b/www/advanced-http.js @@ -20,155 +20,20 @@ * under the License. * * Modified by Andrew Stephan for Sync OnSet - * Modified by Sefa Ilkimen: - * - added configurable params serializer - * - added put and delete methods - * - using cordova www module pattern - * - some minor improvements - * + * Modified by Sefa Ilkimen */ /* * An HTTP Plugin for PhoneGap. */ -var pluginId = module.id.slice(0, module.id.indexOf('.')); -var validSerializers = ['urlencoded', 'json']; +var pluginId = module.id.slice(0, module.id.lastIndexOf('.')); var exec = require('cordova/exec'); var angularIntegration = require(pluginId +'.angular-integration'); var cookieHandler = require(pluginId + '.cookie-handler'); - -var MANDATORY_SUCCESS = 'advanced-http: missing mandatory "onSuccess" callback function'; -var MANDATORY_FAIL = 'advanced-http: missing mandatory "onFail" callback function'; -var ADDING_COOKIES_NOT_SUPPORTED = 'advanced-http: "setHeader" does not support adding cookies, please use "setCookie" function instead'; -var HEADER_VALUE_MUST_BE_STRING = 'advanced-http: header values must be strings'; - -// Thanks Mozilla: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_.22Unicode_Problem.22 -function b64EncodeUnicode(str) { - return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { - return String.fromCharCode('0x' + p1); - })); -} - -function mergeHeaders(globalHeaders, localHeaders) { - var globalKeys = Object.keys(globalHeaders); - var key; - - for (var i = 0; i < globalKeys.length; i++) { - key = globalKeys[i]; - - if (!localHeaders.hasOwnProperty(key)) { - localHeaders[key] = globalHeaders[key]; - } - } - - return localHeaders; -} - -function checkHeaders(headers) { - var keys = Object.keys(headers); - var key; - - for (var i = 0; i < keys.length; i++) { - key = keys[i]; - - if (typeof headers[key] !== 'string') { - return false; - } - } - - return true; -} - -function onInvalidHeader(handler) { - handler({ - status: 0, - error: HEADER_VALUE_MUST_BE_STRING, - headers: {} - }); -} - -function checkSerializer(serializer) { - serializer = serializer || ''; - serializer = serializer.trim().toLowerCase(); - - if (validSerializers.indexOf(serializer) > -1) { - return serializer; - } - - return serializer[0]; -} - -function resolveCookieString(headers) { - var keys = Object.keys(headers || {}); - - for (var i = 0; i < keys.length; ++i) { - if (keys[i].match(/^set-cookie$/i)) { - return headers[keys[i]]; - } - } - - return null; -} - -function createFileEntry(rawEntry) { - var entry = new (require('cordova-plugin-file.FileEntry'))(); - - entry.isDirectory = rawEntry.isDirectory; - entry.isFile = rawEntry.isFile; - entry.name = rawEntry.name; - entry.fullPath = rawEntry.fullPath; - entry.filesystem = new FileSystem(rawEntry.filesystemName || (rawEntry.filesystem == window.PERSISTENT ? 'persistent' : 'temporary')); - entry.nativeURL = rawEntry.nativeURL; - - return entry; -} - -function injectCookieHandler(url, cb) { - return function(response) { - cookieHandler.setCookieFromString(url, resolveCookieString(response.headers)); - cb(response); - } -} - -function injectFileEntryHandler(cb) { - return function(response) { - cb(createFileEntry(response.file)); - } -} - -function getCookieHeader(url) { - return { Cookie: cookieHandler.getCookieString(url) }; -} - -function getMatchingHostHeaders(url, headersList) { - var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); - var domain = matches && matches[1]; - - return headersList[domain] || null; -} - -function getMergedHeaders(url, requestHeaders, predefinedHeaders) { - var globalHeaders = predefinedHeaders['*'] || {}; - var hostHeaders = getMatchingHostHeaders(url, predefinedHeaders) || {}; - var mergedHeaders = mergeHeaders(globalHeaders, hostHeaders); - - mergedHeaders = mergeHeaders(mergedHeaders, requestHeaders); - mergedHeaders = mergeHeaders(mergedHeaders, getCookieHeader(url)); - - return mergedHeaders; -} - -function handleMissingCallbacks(successFn, failFn) { - if (Object.prototype.toString.call(successFn) !== '[object Function]') { - throw new Error(MANDATORY_SUCCESS); - } - - if (Object.prototype.toString.call(failFn) !== '[object Function]') { - throw new Error(MANDATORY_FAIL); - } -} +var helpers = require(pluginId + '.helpers'); +var messages = require(pluginId + '.messages'); var http = { headers: {}, @@ -176,10 +41,10 @@ var http = { sslPinning: false, timeoutInSeconds: 60.0, getBasicAuthHeader: function (username, password) { - return {'Authorization': 'Basic ' + b64EncodeUnicode(username + ':' + password)}; + return {'Authorization': 'Basic ' + helpers.b64EncodeUnicode(username + ':' + password)}; }, useBasicAuth: function (username, password) { - this.setHeader('*', 'Authorization', 'Basic ' + b64EncodeUnicode(username + ':' + password)); + this.setHeader('*', 'Authorization', 'Basic ' + helpers.b64EncodeUnicode(username + ':' + password)); }, setHeader: function () { // this one is for being backward compatible @@ -194,18 +59,18 @@ var http = { } if (header.toLowerCase() === 'cookie') { - throw new Error(ADDING_COOKIES_NOT_SUPPORTED); + throw new Error(messages.ADDING_COOKIES_NOT_SUPPORTED); } if (typeof value !== 'string') { - throw new Error(HEADER_VALUE_MUST_BE_STRING); + throw new Error(messages.HEADER_VALUE_MUST_BE_STRING); } this.headers[host] = this.headers[host] || {}; this.headers[host][header] = value; }, setDataSerializer: function (serializer) { - this.dataSerializer = checkSerializer(serializer); + this.dataSerializer = helpers.checkSerializer(serializer); }, setCookie: function (url, cookie, options) { cookieHandler.setCookie(url, cookie, options); @@ -232,127 +97,127 @@ var http = { return exec(success, failure, 'CordovaHttpPlugin', 'disableRedirect', [disable]); }, validateDomainName: function (validate, success, failure) { - failure('advanced-http: "validateDomainName" is no more supported, please see change log for further info'); + failure(messages.DEPRECATED_VDN); }, post: function (url, data, headers, success, failure) { - handleMissingCallbacks(success, failure); + helpers.handleMissingCallbacks(success, failure); - data = data || {}; - headers = getMergedHeaders(url, headers, this.headers); + data = helpers.getProcessedData(data, this.dataSerializer); + headers = helpers.getMergedHeaders(url, headers, this.headers); - if (!checkHeaders(headers)) { - return onInvalidHeader(failure); + if (!helpers.checkHeaders(headers)) { + return helpers.onInvalidHeader(failure); } - var onSuccess = injectCookieHandler(url, success); - var onFail = injectCookieHandler(url, failure); + var onSuccess = helpers.injectCookieHandler(url, success); + var onFail = helpers.injectCookieHandler(url, failure); return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'post', [url, data, this.dataSerializer, headers, this.timeoutInSeconds]); }, get: function (url, params, headers, success, failure) { - handleMissingCallbacks(success, failure); + helpers.handleMissingCallbacks(success, failure); params = params || {}; - headers = getMergedHeaders(url, headers, this.headers); + headers = helpers.getMergedHeaders(url, headers, this.headers); - if (!checkHeaders(headers)) { - return onInvalidHeader(failure); + if (!helpers.checkHeaders(headers)) { + return helpers.onInvalidHeader(failure); } - var onSuccess = injectCookieHandler(url, success); - var onFail = injectCookieHandler(url, failure); + var onSuccess = helpers.injectCookieHandler(url, success); + var onFail = helpers.injectCookieHandler(url, failure); return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'get', [url, params, headers, this.timeoutInSeconds]); }, put: function (url, data, headers, success, failure) { - handleMissingCallbacks(success, failure); + helpers.handleMissingCallbacks(success, failure); - data = data || {}; - headers = getMergedHeaders(url, headers, this.headers); + data = helpers.getProcessedData(data, this.dataSerializer); + headers = helpers.getMergedHeaders(url, headers, this.headers); - if (!checkHeaders(headers)) { - return onInvalidHeader(failure); + if (!helpers.checkHeaders(headers)) { + return helpers.onInvalidHeader(failure); } - var onSuccess = injectCookieHandler(url, success); - var onFail = injectCookieHandler(url, failure); + var onSuccess = helpers.injectCookieHandler(url, success); + var onFail = helpers.injectCookieHandler(url, failure); return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'put', [url, data, this.dataSerializer, headers, this.timeoutInSeconds]); }, patch: function (url, data, headers, success, failure) { - handleMissingCallbacks(success, failure); + helpers.handleMissingCallbacks(success, failure); - data = data || {}; - headers = getMergedHeaders(url, headers, this.headers); + data = helpers.getProcessedData(data, this.dataSerializer); + headers = helpers.getMergedHeaders(url, headers, this.headers); - if (!checkHeaders(headers)) { - return onInvalidHeader(failure); + if (!helpers.checkHeaders(headers)) { + return helpers.onInvalidHeader(failure); } - var onSuccess = injectCookieHandler(url, success); - var onFail = injectCookieHandler(url, failure); + var onSuccess = helpers.injectCookieHandler(url, success); + var onFail = helpers.injectCookieHandler(url, failure); return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'patch', [url, data, this.dataSerializer, headers, this.timeoutInSeconds]); }, delete: function (url, params, headers, success, failure) { - handleMissingCallbacks(success, failure); + helpers.handleMissingCallbacks(success, failure); params = params || {}; - headers = getMergedHeaders(url, headers, this.headers); + headers = helpers.getMergedHeaders(url, headers, this.headers); - if (!checkHeaders(headers)) { - return onInvalidHeader(failure); + if (!helpers.checkHeaders(headers)) { + return helpers.onInvalidHeader(failure); } - var onSuccess = injectCookieHandler(url, success); - var onFail = injectCookieHandler(url, failure); + var onSuccess = helpers.injectCookieHandler(url, success); + var onFail = helpers.injectCookieHandler(url, failure); return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'delete', [url, params, headers, this.timeoutInSeconds]); }, head: function (url, params, headers, success, failure) { - handleMissingCallbacks(success, failure); + helpers.handleMissingCallbacks(success, failure); params = params || {}; - headers = getMergedHeaders(url, headers, this.headers); + headers = helpers.getMergedHeaders(url, headers, this.headers); - if (!checkHeaders(headers)) { - return onInvalidHeader(failure); + if (!helpers.checkHeaders(headers)) { + return helpers.onInvalidHeader(failure); } - var onSuccess = injectCookieHandler(url, success); - var onFail = injectCookieHandler(url, failure); + var onSuccess = helpers.injectCookieHandler(url, success); + var onFail = helpers.injectCookieHandler(url, failure); return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'head', [url, params, headers, this.timeoutInSeconds]); }, uploadFile: function (url, params, headers, filePath, name, success, failure) { - handleMissingCallbacks(success, failure); + helpers.handleMissingCallbacks(success, failure); params = params || {}; - headers = getMergedHeaders(url, headers, this.headers); + headers = helpers.getMergedHeaders(url, headers, this.headers); - if (!checkHeaders(headers)) { - return onInvalidHeader(failure); + if (!helpers.checkHeaders(headers)) { + return helpers.onInvalidHeader(failure); } - var onSuccess = injectCookieHandler(url, success); - var onFail = injectCookieHandler(url, failure); + var onSuccess = helpers.injectCookieHandler(url, success); + var onFail = helpers.injectCookieHandler(url, failure); return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'uploadFile', [url, params, headers, filePath, name, this.timeoutInSeconds]); }, downloadFile: function (url, params, headers, filePath, success, failure) { - handleMissingCallbacks(success, failure); + helpers.handleMissingCallbacks(success, failure); params = params || {}; - headers = getMergedHeaders(url, headers, this.headers); + headers = helpers.getMergedHeaders(url, headers, this.headers); - if (!checkHeaders(headers)) { - return onInvalidHeader(failure); + if (!helpers.checkHeaders(headers)) { + return helpers.onInvalidHeader(failure); } - var onSuccess = injectCookieHandler(url, injectFileEntryHandler(success)); - var onFail = injectCookieHandler(url, failure); + var onSuccess = helpers.injectCookieHandler(url, helpers.injectFileEntryHandler(success)); + var onFail = helpers.injectCookieHandler(url, failure); return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'downloadFile', [url, params, headers, filePath, this.timeoutInSeconds]); } diff --git a/www/cookie-handler.js b/www/cookie-handler.js index 2399f96..0f97780 100644 --- a/www/cookie-handler.js +++ b/www/cookie-handler.js @@ -1,4 +1,4 @@ -var pluginId = module.id.slice(0, module.id.indexOf('.')); +var pluginId = module.id.slice(0, module.id.lastIndexOf('.')); var ToughCookie = require(pluginId + '.tough-cookie'); var WebStorageCookieStore = require(pluginId + '.local-storage-store'); diff --git a/www/helpers.js b/www/helpers.js new file mode 100644 index 0000000..6ecc609 --- /dev/null +++ b/www/helpers.js @@ -0,0 +1,195 @@ +var pluginId = module.id.slice(0, module.id.lastIndexOf('.')); +var cookieHandler = require(pluginId + '.cookie-handler'); +var messages = require(pluginId + '.messages'); + +var validSerializers = ['urlencoded', 'json', 'utf8' ]; + +module.exports = { + b64EncodeUnicode: b64EncodeUnicode, + checkHeaders: checkHeaders, + onInvalidHeader: onInvalidHeader, + checkSerializer: checkSerializer, + injectCookieHandler: injectCookieHandler, + injectFileEntryHandler: injectFileEntryHandler, + getMergedHeaders: getMergedHeaders, + getProcessedData: getProcessedData, + handleMissingCallbacks: handleMissingCallbacks +}; + +// Thanks Mozilla: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_.22Unicode_Problem.22 +function b64EncodeUnicode(str) { + return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { + return String.fromCharCode('0x' + p1); + })); +} + +function mergeHeaders(globalHeaders, localHeaders) { + var globalKeys = Object.keys(globalHeaders); + var key; + + for (var i = 0; i < globalKeys.length; i++) { + key = globalKeys[i]; + + if (!localHeaders.hasOwnProperty(key)) { + localHeaders[key] = globalHeaders[key]; + } + } + + return localHeaders; +} + +function checkHeaders(headers) { + var keys = Object.keys(headers); + var key; + + for (var i = 0; i < keys.length; i++) { + key = keys[i]; + + if (typeof headers[key] !== 'string') { + return false; + } + } + + return true; +} + +function onInvalidHeader(handler) { + handler({ + status: 0, + error: messages.HEADER_VALUE_MUST_BE_STRING, + headers: {} + }); +} + +function checkSerializer(serializer) { + serializer = serializer || ''; + serializer = serializer.trim().toLowerCase(); + + if (validSerializers.indexOf(serializer) > -1) { + return serializer; + } + + return serializer[0]; +} + +function resolveCookieString(headers) { + var keys = Object.keys(headers || {}); + + for (var i = 0; i < keys.length; ++i) { + if (keys[i].match(/^set-cookie$/i)) { + return headers[keys[i]]; + } + } + + return null; +} + +function createFileEntry(rawEntry) { + var entry = new (require('cordova-plugin-file.FileEntry'))(); + + entry.isDirectory = rawEntry.isDirectory; + entry.isFile = rawEntry.isFile; + entry.name = rawEntry.name; + entry.fullPath = rawEntry.fullPath; + entry.filesystem = new FileSystem(rawEntry.filesystemName || (rawEntry.filesystem == window.PERSISTENT ? 'persistent' : 'temporary')); + entry.nativeURL = rawEntry.nativeURL; + + return entry; +} + +function injectCookieHandler(url, cb) { + return function(response) { + cookieHandler.setCookieFromString(url, resolveCookieString(response.headers)); + cb(response); + } +} + +function injectFileEntryHandler(cb) { + return function(response) { + cb(createFileEntry(response.file)); + } +} + +function getCookieHeader(url) { + return { Cookie: cookieHandler.getCookieString(url) }; +} + +function getMatchingHostHeaders(url, headersList) { + var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); + var domain = matches && matches[1]; + + return headersList[domain] || null; +} + +function getMergedHeaders(url, requestHeaders, predefinedHeaders) { + var globalHeaders = predefinedHeaders['*'] || {}; + var hostHeaders = getMatchingHostHeaders(url, predefinedHeaders) || {}; + var mergedHeaders = mergeHeaders(globalHeaders, hostHeaders); + + mergedHeaders = mergeHeaders(mergedHeaders, requestHeaders); + mergedHeaders = mergeHeaders(mergedHeaders, getCookieHeader(url)); + + return mergedHeaders; +} + +// typeof is not working reliably in JS +function getTypeOf(object) { + switch (Object.prototype.toString.call(object)) { + case '[object Array]': + return 'Array'; + case '[object Boolean]': + return 'Boolean'; + case '[object Function]': + return 'Function'; + case '[object Null]': + return 'Null'; + case '[object Number]': + return 'Number'; + case '[object Object]': + return 'Object'; + case '[object String]': + return 'String'; + case '[object Undefined]': + return 'Undefined'; + default: + return 'Unknown'; + } +} + +function getAllowedDataTypes(dataSerializer) { + switch (dataSerializer) { + case 'utf8': + return ['String']; + case 'urlencoded': + return ['Object']; + default: + return ['Array', 'Object']; + } +} + +function getProcessedData(data, dataSerializer) { + data = data || {}; + + var currentDataType = getTypeOf(data); + var allowedDataTypes = getAllowedDataTypes(dataSerializer); + + if (allowedDataTypes.indexOf(currentDataType) === -1) { + throw new Error(messages.DATA_TYPE_MISMATCH + ' ' + allowedDataTypes.join(', ')); + } + + if (dataSerializer === 'utf8') { + data = { text: data }; + } + + return data; +} + +function handleMissingCallbacks(successFn, failFn) { + if (getTypeOf(successFn) !== 'Function') { + throw new Error(messages.MANDATORY_SUCCESS); + } + + if (getTypeOf(failFn) !== 'Function') { + throw new Error(messages.MANDATORY_FAIL); + } +} diff --git a/www/local-storage-store.js b/www/local-storage-store.js index 044e7ca..4c5b7b0 100644 --- a/www/local-storage-store.js +++ b/www/local-storage-store.js @@ -30,7 +30,7 @@ 'use strict'; -var pluginId = module.id.slice(0, module.id.indexOf('.')); +var pluginId = module.id.slice(0, module.id.lastIndexOf('.')); var ToughCookie = require(pluginId + '.tough-cookie'); var _ = require(pluginId + '.lodash'); diff --git a/www/messages.js b/www/messages.js new file mode 100644 index 0000000..6708841 --- /dev/null +++ b/www/messages.js @@ -0,0 +1,8 @@ +module.exports = { + ADDING_COOKIES_NOT_SUPPORTED: 'advanced-http: "setHeader" does not support adding cookies, please use "setCookie" function instead', + DATA_TYPE_MISMATCH: 'advanced-http: "data" argument supports only following data types:', + DEPRECATED_VDN: 'advanced-http: "validateDomainName" is no more supported, please see change log for further info', + HEADER_VALUE_MUST_BE_STRING: 'advanced-http: header values must be strings', + MANDATORY_SUCCESS: 'advanced-http: missing mandatory "onSuccess" callback function', + MANDATORY_FAIL: 'advanced-http: missing mandatory "onFail" callback function' +};