You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by sh...@apache.org on 2016/07/25 07:57:36 UTC

[50/57] [abbrv] cordova-plugins git commit: Merge commit '394cfb12f80de35255a506c0dcbf4a21910e849a'

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.h
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.h
index 381b122,0000000..dad0114
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.h
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.h
@@@ -1,81 -1,0 +1,81 @@@
 +/*
-  Copyright (c) 2012-2014, Pierre-Olivier Latour
++ Copyright (c) 2012-2015, Pierre-Olivier Latour
 + All rights reserved.
 + 
 + Redistribution and use in source and binary forms, with or without
 + modification, are permitted provided that the following conditions are met:
 + * Redistributions of source code must retain the above copyright
 + notice, this list of conditions and the following disclaimer.
 + * Redistributions in binary form must reproduce the above copyright
 + notice, this list of conditions and the following disclaimer in the
 + documentation and/or other materials provided with the distribution.
 + * The name of Pierre-Olivier Latour may not be used to endorse
 + or promote products derived from this software without specific
 + prior written permission.
 + 
 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
 + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#import "GCDWebServerDataResponse.h"
 +#import "GCDWebServerHTTPStatusCodes.h"
 +
 +/**
 + *  The GCDWebServerDataResponse subclass of GCDWebServerDataResponse generates
 + *  an HTML body from an HTTP status code and an error message.
 + */
 +@interface GCDWebServerErrorResponse : GCDWebServerDataResponse
 +
 +/**
 + *  Creates a client error response with the corresponding HTTP status code.
 + */
 ++ (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2,3);
 +
 +/**
 + *  Creates a server error response with the corresponding HTTP status code.
 + */
 ++ (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2,3);
 +
 +/**
 + *  Creates a client error response with the corresponding HTTP status code
 + *  and an underlying NSError.
 + */
 ++ (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3,4);
 +
 +/**
 + *  Creates a server error response with the corresponding HTTP status code
 + *  and an underlying NSError.
 + */
 ++ (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3,4);
 +
 +/**
 + *  Initializes a client error response with the corresponding HTTP status code.
 + */
 +- (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2,3);
 +
 +/**
 + *  Initializes a server error response with the corresponding HTTP status code.
 + */
 +- (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2,3);
 +
 +/**
 + *  Initializes a client error response with the corresponding HTTP status code
 + *  and an underlying NSError.
 + */
 +- (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3,4);
 +
 +/**
 + *  Initializes a server error response with the corresponding HTTP status code
 + *  and an underlying NSError.
 + */
 +- (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3,4);
 +
 +@end

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.m
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.m
index c2e4422,0000000..ef6a991
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.m
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.m
@@@ -1,128 -1,0 +1,128 @@@
 +/*
-  Copyright (c) 2012-2014, Pierre-Olivier Latour
++ Copyright (c) 2012-2015, Pierre-Olivier Latour
 + All rights reserved.
 + 
 + Redistribution and use in source and binary forms, with or without
 + modification, are permitted provided that the following conditions are met:
 + * Redistributions of source code must retain the above copyright
 + notice, this list of conditions and the following disclaimer.
 + * Redistributions in binary form must reproduce the above copyright
 + notice, this list of conditions and the following disclaimer in the
 + documentation and/or other materials provided with the distribution.
 + * The name of Pierre-Olivier Latour may not be used to endorse
 + or promote products derived from this software without specific
 + prior written permission.
 + 
 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
 + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#if !__has_feature(objc_arc)
 +#error GCDWebServer requires ARC
 +#endif
 +
 +#import "GCDWebServerPrivate.h"
 +
 +@interface GCDWebServerErrorResponse ()
 +- (instancetype)initWithStatusCode:(NSInteger)statusCode underlyingError:(NSError*)underlyingError messageFormat:(NSString*)format arguments:(va_list)arguments;
 +@end
 +
 +@implementation GCDWebServerErrorResponse
 +
 ++ (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... {
 +  GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500));
 +  va_list arguments;
 +  va_start(arguments, format);
 +  GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments];
 +  va_end(arguments);
 +  return response;
 +}
 +
 ++ (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... {
 +  GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600));
 +  va_list arguments;
 +  va_start(arguments, format);
 +  GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments];
 +  va_end(arguments);
 +  return response;
 +}
 +
 ++ (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... {
 +  GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500));
 +  va_list arguments;
 +  va_start(arguments, format);
 +  GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments];
 +  va_end(arguments);
 +  return response;
 +}
 +
 ++ (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... {
 +  GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600));
 +  va_list arguments;
 +  va_start(arguments, format);
 +  GCDWebServerErrorResponse* response = [[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments];
 +  va_end(arguments);
 +  return response;
 +}
 +
 +static inline NSString* _EscapeHTMLString(NSString* string) {
 +  return [string stringByReplacingOccurrencesOfString:@"\"" withString:@"&quot;"];
 +}
 +
 +- (instancetype)initWithStatusCode:(NSInteger)statusCode underlyingError:(NSError*)underlyingError messageFormat:(NSString*)format arguments:(va_list)arguments {
 +  NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments];
 +  NSString* title = [NSString stringWithFormat:@"HTTP Error %i", (int)statusCode];
 +  NSString* error = underlyingError ? [NSString stringWithFormat:@"[%@] %@ (%li)", underlyingError.domain, _EscapeHTMLString(underlyingError.localizedDescription), (long)underlyingError.code] : @"";
 +  NSString* html = [NSString stringWithFormat:@"<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"utf-8\"><title>%@</title></head><body><h1>%@: %@</h1><h3>%@</h3></body></html>",
 +                                              title, title, _EscapeHTMLString(message), error];
 +  if ((self = [self initWithHTML:html])) {
 +    self.statusCode = statusCode;
 +  }
 +  return self;
 +}
 +
 +- (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... {
 +  GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500));
 +  va_list arguments;
 +  va_start(arguments, format);
 +  self = [self initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments];
 +  va_end(arguments);
 +  return self;
 +}
 +
 +- (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... {
 +  GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600));
 +  va_list arguments;
 +  va_start(arguments, format);
 +  self = [self initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments];
 +  va_end(arguments);
 +  return self;
 +}
 +
 +- (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... {
 +  GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500));
 +  va_list arguments;
 +  va_start(arguments, format);
 +  self = [self initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments];
 +  va_end(arguments);
 +  return self;
 +}
 +
 +- (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... {
 +  GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600));
 +  va_list arguments;
 +  va_start(arguments, format);
 +  self = [self initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments];
 +  va_end(arguments);
 +  return self;
 +}
 +
 +@end

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.h
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.h
index 19d284d,0000000..050e92f
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.h
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.h
@@@ -1,96 -1,0 +1,96 @@@
 +/*
-  Copyright (c) 2012-2014, Pierre-Olivier Latour
++ Copyright (c) 2012-2015, Pierre-Olivier Latour
 + All rights reserved.
 + 
 + Redistribution and use in source and binary forms, with or without
 + modification, are permitted provided that the following conditions are met:
 + * Redistributions of source code must retain the above copyright
 + notice, this list of conditions and the following disclaimer.
 + * Redistributions in binary form must reproduce the above copyright
 + notice, this list of conditions and the following disclaimer in the
 + documentation and/or other materials provided with the distribution.
 + * The name of Pierre-Olivier Latour may not be used to endorse
 + or promote products derived from this software without specific
 + prior written permission.
 + 
 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
 + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#import "GCDWebServerResponse.h"
 +
 +/**
 + *  The GCDWebServerFileResponse subclass of GCDWebServerResponse reads the body
 + *  of the HTTP response from a file on disk.
 + *
 + *  It will automatically set the contentType, lastModifiedDate and eTag
 + *  properties of the GCDWebServerResponse according to the file extension and
 + *  metadata.
 + */
 +@interface GCDWebServerFileResponse : GCDWebServerResponse
 +
 +/**
 + *  Creates a response with the contents of a file.
 + */
 ++ (instancetype)responseWithFile:(NSString*)path;
 +
 +/**
 + *  Creates a response like +responseWithFile: and sets the "Content-Disposition"
 + *  HTTP header for a download if the "attachment" argument is YES.
 + */
 ++ (instancetype)responseWithFile:(NSString*)path isAttachment:(BOOL)attachment;
 +
 +/**
 + *  Creates a response like +responseWithFile: but restricts the file contents
 + *  to a specific byte range.
 + *
 + *  See -initWithFile:byteRange: for details.
 + */
 ++ (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range;
 +
 +/**
 + *  Creates a response like +responseWithFile:byteRange: and sets the
 + *  "Content-Disposition" HTTP header for a download if the "attachment"
 + *  argument is YES.
 + */
 ++ (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment;
 +
 +/**
 + *  Initializes a response with the contents of a file.
 + */
 +- (instancetype)initWithFile:(NSString*)path;
 +
 +/**
 + *  Initializes a response like +responseWithFile: and sets the
 + *  "Content-Disposition" HTTP header for a download if the "attachment"
 + *  argument is YES.
 + */
 +- (instancetype)initWithFile:(NSString*)path isAttachment:(BOOL)attachment;
 +
 +/**
 + *  Initializes a response like -initWithFile: but restricts the file contents
 + *  to a specific byte range. This range should be set to (NSUIntegerMax, 0) for
 + *  the full file, (offset, length) if expressed from the beginning of the file,
 + *  or (NSUIntegerMax, length) if expressed from the end of the file. The "offset"
 + *  and "length" values will be automatically adjusted to be compatible with the
 + *  actual size of the file.
 + *
 + *  This argument would typically be set to the value of the byteRange property
 + *  of the current GCDWebServerRequest.
 + */
 +- (instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range;
 +
 +/**
 + *  This method is the designated initializer for the class.
 + */
 +- (instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment;
 +
 +@end

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.m
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.m
index 2004327,0000000..a2b7c3c
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.m
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.m
@@@ -1,181 -1,0 +1,187 @@@
 +/*
-  Copyright (c) 2012-2014, Pierre-Olivier Latour
++ Copyright (c) 2012-2015, Pierre-Olivier Latour
 + All rights reserved.
 + 
 + Redistribution and use in source and binary forms, with or without
 + modification, are permitted provided that the following conditions are met:
 + * Redistributions of source code must retain the above copyright
 + notice, this list of conditions and the following disclaimer.
 + * Redistributions in binary form must reproduce the above copyright
 + notice, this list of conditions and the following disclaimer in the
 + documentation and/or other materials provided with the distribution.
 + * The name of Pierre-Olivier Latour may not be used to endorse
 + or promote products derived from this software without specific
 + prior written permission.
 + 
 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
 + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#if !__has_feature(objc_arc)
 +#error GCDWebServer requires ARC
 +#endif
 +
 +#import <sys/stat.h>
 +
 +#import "GCDWebServerPrivate.h"
 +
 +#define kFileReadBufferSize (32 * 1024)
 +
 +@interface GCDWebServerFileResponse () {
 +@private
 +  NSString* _path;
 +  NSUInteger _offset;
 +  NSUInteger _size;
 +  int _file;
 +}
 +@end
 +
 +@implementation GCDWebServerFileResponse
 +
 ++ (instancetype)responseWithFile:(NSString*)path {
 +  return [[[self class] alloc] initWithFile:path];
 +}
 +
 ++ (instancetype)responseWithFile:(NSString*)path isAttachment:(BOOL)attachment {
 +  return [[[self class] alloc] initWithFile:path isAttachment:attachment];
 +}
 +
 ++ (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range {
 +  return [[[self class] alloc] initWithFile:path byteRange:range];
 +}
 +
 ++ (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment {
 +  return [[[self class] alloc] initWithFile:path byteRange:range isAttachment:attachment];
 +}
 +
 +- (instancetype)initWithFile:(NSString*)path {
 +  return [self initWithFile:path byteRange:NSMakeRange(NSUIntegerMax, 0) isAttachment:NO];
 +}
 +
 +- (instancetype)initWithFile:(NSString*)path isAttachment:(BOOL)attachment {
 +  return [self initWithFile:path byteRange:NSMakeRange(NSUIntegerMax, 0) isAttachment:attachment];
 +}
 +
 +- (instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range {
 +  return [self initWithFile:path byteRange:range isAttachment:NO];
 +}
 +
 +static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
 +  return [NSDate dateWithTimeIntervalSince1970:((NSTimeInterval)t->tv_sec + (NSTimeInterval)t->tv_nsec / 1000000000.0)];
 +}
 +
 +- (instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment {
 +  struct stat info;
 +  if (lstat([path fileSystemRepresentation], &info) || !(info.st_mode & S_IFREG)) {
 +    GWS_DNOT_REACHED();
 +    return nil;
 +  }
 +#ifndef __LP64__
 +  if (info.st_size >= (off_t)4294967295) {  // In 32 bit mode, we can't handle files greater than 4 GiBs (don't use "NSUIntegerMax" here to avoid potential unsigned to signed conversion issues)
 +    GWS_DNOT_REACHED();
 +    return nil;
 +  }
 +#endif
 +  NSUInteger fileSize = (NSUInteger)info.st_size;
 +  
 +  BOOL hasByteRange = GCDWebServerIsValidByteRange(range);
 +  if (hasByteRange) {
 +    if (range.location != NSUIntegerMax) {
 +      range.location = MIN(range.location, fileSize);
 +      range.length = MIN(range.length, fileSize - range.location);
 +    } else {
 +      range.length = MIN(range.length, fileSize);
 +      range.location = fileSize - range.length;
 +    }
 +    if (range.length == 0) {
 +      return nil;  // TODO: Return 416 status code and "Content-Range: bytes */{file length}" header
 +    }
 +  } else {
 +    range.location = 0;
 +    range.length = fileSize;
 +  }
 +  
 +  if ((self = [super init])) {
 +    _path = [path copy];
 +    _offset = range.location;
 +    _size = range.length;
 +    if (hasByteRange) {
 +      [self setStatusCode:kGCDWebServerHTTPStatusCode_PartialContent];
 +      [self setValue:[NSString stringWithFormat:@"bytes %lu-%lu/%lu", (unsigned long)_offset, (unsigned long)(_offset + _size - 1), (unsigned long)fileSize] forAdditionalHeader:@"Content-Range"];
 +      GWS_LOG_DEBUG(@"Using content bytes range [%lu-%lu] for file \"%@\"", (unsigned long)_offset, (unsigned long)(_offset + _size - 1), path);
 +    }
 +    
 +    if (attachment) {
 +      NSString* fileName = [path lastPathComponent];
 +      NSData* data = [[fileName stringByReplacingOccurrencesOfString:@"\"" withString:@""] dataUsingEncoding:NSISOLatin1StringEncoding allowLossyConversion:YES];
 +      NSString* lossyFileName = data ? [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding] : nil;
 +      if (lossyFileName) {
 +        NSString* value = [NSString stringWithFormat:@"attachment; filename=\"%@\"; filename*=UTF-8''%@", lossyFileName, GCDWebServerEscapeURLString(fileName)];
 +        [self setValue:value forAdditionalHeader:@"Content-Disposition"];
 +      } else {
 +        GWS_DNOT_REACHED();
 +      }
 +    }
 +    
 +    self.contentType = GCDWebServerGetMimeTypeForExtension([_path pathExtension]);
 +    self.contentLength = _size;
 +    self.lastModifiedDate = _NSDateFromTimeSpec(&info.st_mtimespec);
 +    self.eTag = [NSString stringWithFormat:@"%llu/%li/%li", info.st_ino, info.st_mtimespec.tv_sec, info.st_mtimespec.tv_nsec];
 +  }
 +  return self;
 +}
 +
 +- (BOOL)open:(NSError**)error {
 +  _file = open([_path fileSystemRepresentation], O_NOFOLLOW | O_RDONLY);
 +  if (_file <= 0) {
-     *error = GCDWebServerMakePosixError(errno);
++    if (error) {
++      *error = GCDWebServerMakePosixError(errno);
++    }
 +    return NO;
 +  }
 +  if (lseek(_file, _offset, SEEK_SET) != (off_t)_offset) {
-     *error = GCDWebServerMakePosixError(errno);
++    if (error) {
++      *error = GCDWebServerMakePosixError(errno);
++    }
 +    close(_file);
 +    return NO;
 +  }
 +  return YES;
 +}
 +
 +- (NSData*)readData:(NSError**)error {
 +  size_t length = MIN((NSUInteger)kFileReadBufferSize, _size);
 +  NSMutableData* data = [[NSMutableData alloc] initWithLength:length];
 +  ssize_t result = read(_file, data.mutableBytes, length);
 +  if (result < 0) {
-     *error = GCDWebServerMakePosixError(errno);
++    if (error) {
++      *error = GCDWebServerMakePosixError(errno);
++    }
 +    return nil;
 +  }
 +  if (result > 0) {
 +    [data setLength:result];
 +    _size -= result;
 +  }
 +  return data;
 +}
 +
 +- (void)close {
 +  close(_file);
 +}
 +
 +- (NSString*)description {
 +  NSMutableString* description = [NSMutableString stringWithString:[super description]];
 +  [description appendFormat:@"\n\n{%@}", _path];
 +  return description;
 +}
 +
 +@end

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.h
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.h
index 4f39625,0000000..2731b7c
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.h
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.h
@@@ -1,78 -1,0 +1,75 @@@
 +/*
-  Copyright (c) 2012-2014, Pierre-Olivier Latour
++ Copyright (c) 2012-2015, Pierre-Olivier Latour
 + All rights reserved.
 + 
 + Redistribution and use in source and binary forms, with or without
 + modification, are permitted provided that the following conditions are met:
 + * Redistributions of source code must retain the above copyright
 + notice, this list of conditions and the following disclaimer.
 + * Redistributions in binary form must reproduce the above copyright
 + notice, this list of conditions and the following disclaimer in the
 + documentation and/or other materials provided with the distribution.
 + * The name of Pierre-Olivier Latour may not be used to endorse
 + or promote products derived from this software without specific
 + prior written permission.
 + 
 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
 + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#import "GCDWebServerResponse.h"
 +
 +/**
 + *  The GCDWebServerStreamBlock is called to stream the data for the HTTP body.
-  *  The block must return empty NSData when done or nil on error and set the
-  *  "error" argument which is guaranteed to be non-NULL.
++ *  The block must return either a chunk of data, an empty NSData when done, or
++ *  nil on error and set the "error" argument which is guaranteed to be non-NULL.
 + */
 +typedef NSData* (^GCDWebServerStreamBlock)(NSError** error);
 +
 +/**
 + *  The GCDWebServerAsyncStreamBlock works like the GCDWebServerStreamBlock
 + *  except the streamed data can be returned at a later time allowing for
 + *  truly asynchronous generation of the data.
 + *
-  *  The block must return empty NSData when done or nil on error and set the
-  *  "error" argument which is guaranteed to be non-NULL.
++ *  The block must call "completionBlock" passing the new chunk of data when ready,
++ *  an empty NSData when done, or nil on error and pass a NSError.
 + *
-  *  The block must regularly call "completionBlock" passing new streamed data.
-  *  Eventually it must call "completionBlock" passing an empty NSData indicating
-  *  the end of the stream has been reached, or pass nil and an NSError in case of
-  *  error.
++ *  The block cannot call "completionBlock" more than once per invocation.
 + */
 +typedef void (^GCDWebServerAsyncStreamBlock)(GCDWebServerBodyReaderCompletionBlock completionBlock);
 +
 +/**
 + *  The GCDWebServerStreamedResponse subclass of GCDWebServerResponse streams
 + *  the body of the HTTP response using a GCD block.
 + */
 +@interface GCDWebServerStreamedResponse : GCDWebServerResponse
 +
 +/**
 + *  Creates a response with streamed data and a given content type.
 + */
 ++ (instancetype)responseWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block;
 +
 +/**
 + *  Creates a response with async streamed data and a given content type.
 + */
 ++ (instancetype)responseWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block;
 +
 +/**
 + *  Initializes a response with streamed data and a given content type.
 + */
 +- (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block;
 +
 +/**
 + *  This method is the designated initializer for the class.
 + */
 +- (instancetype)initWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block;
 +
 +@end

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.m
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.m
index 7f96943,0000000..4669617
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.m
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.m
@@@ -1,79 -1,0 +1,79 @@@
 +/*
-  Copyright (c) 2012-2014, Pierre-Olivier Latour
++ Copyright (c) 2012-2015, Pierre-Olivier Latour
 + All rights reserved.
 + 
 + Redistribution and use in source and binary forms, with or without
 + modification, are permitted provided that the following conditions are met:
 + * Redistributions of source code must retain the above copyright
 + notice, this list of conditions and the following disclaimer.
 + * Redistributions in binary form must reproduce the above copyright
 + notice, this list of conditions and the following disclaimer in the
 + documentation and/or other materials provided with the distribution.
 + * The name of Pierre-Olivier Latour may not be used to endorse
 + or promote products derived from this software without specific
 + prior written permission.
 + 
 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
 + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#if !__has_feature(objc_arc)
 +#error GCDWebServer requires ARC
 +#endif
 +
 +#import "GCDWebServerPrivate.h"
 +
 +@interface GCDWebServerStreamedResponse () {
 +@private
 +  GCDWebServerAsyncStreamBlock _block;
 +}
 +@end
 +
 +@implementation GCDWebServerStreamedResponse
 +
 ++ (instancetype)responseWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block {
 +  return [[[self class] alloc] initWithContentType:type streamBlock:block];
 +}
 +
 ++ (instancetype)responseWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block {
 +  return [[[self class] alloc] initWithContentType:type asyncStreamBlock:block];
 +}
 +
 +- (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block {
 +  return [self initWithContentType:type asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) {
 +    
 +    NSError* error = nil;
 +    NSData* data = block(&error);
 +    completionBlock(data, error);
 +    
 +  }];
 +}
 +
 +- (instancetype)initWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block {
 +  if ((self = [super init])) {
 +    _block = [block copy];
 +    
 +    self.contentType = type;
 +  }
 +  return self;
 +}
 +
 +- (void)asyncReadDataWithCompletion:(GCDWebServerBodyReaderCompletionBlock)block {
 +  _block(block);
 +}
 +
 +- (NSString*)description {
 +  NSMutableString* description = [NSMutableString stringWithString:[super description]];
 +  [description appendString:@"\n\n<STREAM>"];
 +  return description;
 +}
 +
 +@end

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/css/index.css
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/css/index.css
index aed15e4,0000000..53b0247
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/css/index.css
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/css/index.css
@@@ -1,130 -1,0 +1,130 @@@
 +/*
-  Copyright (c) 2012-2014, Pierre-Olivier Latour
++ Copyright (c) 2012-2015, Pierre-Olivier Latour
 + All rights reserved.
 + 
 + Redistribution and use in source and binary forms, with or without
 + modification, are permitted provided that the following conditions are met:
 + * Redistributions of source code must retain the above copyright
 + notice, this list of conditions and the following disclaimer.
 + * Redistributions in binary form must reproduce the above copyright
 + notice, this list of conditions and the following disclaimer in the
 + documentation and/or other materials provided with the distribution.
 + * The name of Pierre-Olivier Latour may not be used to endorse
 + or promote products derived from this software without specific
 + prior written permission.
 + 
 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
 + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +.row-file {
 +  height: 40px;
 +}
 +
 +.column-icon {
 +  width: 40px;
 +  text-align: center;
 +}
 +
 +.column-name {
 +}
 +
 +.column-size {
 +  width: 100px;
 +  text-align: right;
 +}
 +
 +.column-move {
 +  width: 40px;
 +  text-align: center;
 +}
 +
 +.column-delete {
 +  width: 40px;
 +  text-align: center;
 +}
 +
 +.column-path {  
 +}
 +
 +.column-progress {
 +  width: 200px;
 +}
 +
 +.footer {
 +  color: #999;
 +  text-align: center;
 +  font-size: 0.9em;
 +}
 +
 +#reload {
 +  float: right;
 +}
 +
 +#create-input {
 +  width: 50%;
 +  height: 20px;
 +}
 +
 +#move-input {
 +  width: 80%;
 +  height: 20px;
 +}
 +
 +/* Bootstrap overrides */
 +
 +.btn:focus {
 +  outline: none;  /* FIXME: Work around for Chrome only but still draws focus ring while button pressed */
 +}
 +
 +.btn-toolbar {
 +  margin-top: 30px;
 +  margin-bottom: 20px;
 +}
 +
 +.table .progress {
 +  margin-top: 0px;
 +  margin-bottom: 0px;
 +  height: 16px;
 +}
 +
 +.panel-default > .panel-heading {
 +  color: #555;
 +}
 +
 +.breadcrumb {
 +  background-color: transparent;
 +  border-radius: 0px;
 +  margin-bottom: 0px;
 +  padding: 0px;
 +}
 +
 +.breadcrumb > .active {
 +  color: #555;
 +}
 +
 +.breadcrumb > li + li:before {
 +  color: #999;
 +}
 +
 +.table > tbody > tr > td {
 +  vertical-align: middle;
 +}
 +
 +.table > tbody > tr > td > p {
 +  margin: 0px;
 +}
 +
 +/* Initial state */
 +
 +.uploading {
 +  display: none;
 +}

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/index.html
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/index.html
index 28d371c,0000000..1bfd28e
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/index.html
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/index.html
@@@ -1,196 -1,0 +1,196 @@@
 +<!--
-  Copyright (c) 2012-2014, Pierre-Olivier Latour
++ Copyright (c) 2012-2015, Pierre-Olivier Latour
 + All rights reserved.
 + 
 + Redistribution and use in source and binary forms, with or without
 + modification, are permitted provided that the following conditions are met:
 + * Redistributions of source code must retain the above copyright
 + notice, this list of conditions and the following disclaimer.
 + * Redistributions in binary form must reproduce the above copyright
 + notice, this list of conditions and the following disclaimer in the
 + documentation and/or other materials provided with the distribution.
 + * The name of Pierre-Olivier Latour may not be used to endorse
 + or promote products derived from this software without specific
 + prior written permission.
 + 
 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
 + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 +-->
 +
 +<!DOCTYPE html>
 +<html lang="en">
 +  <head>
 +    <meta charset="utf-8">
 +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 +    <meta name="viewport" content="width=device-width, initial-scale=1">
 +    <title>%title%</title>
 +    <link rel="stylesheet" href="css/bootstrap.css">
 +    <link rel="stylesheet" href="css/bootstrap-theme.css">
 +    <link rel="stylesheet" href="css/jquery.fileupload.css">
 +    <link rel="stylesheet" href="css/index.css">
 +    <!--[if lt IE 9]>
 +      <script type="text/javascript" src="js/html5shiv.min.js"></script>
 +      <script type="text/javascript" src="js/respond.min.js"></script>
 +    <![endif]-->
 +    <script type="text/javascript" src="js/jquery.min.js"></script>
 +    <script type="text/javascript" src="js/jquery.ui.widget.js"></script>
 +    <script type="text/javascript" src="js/jquery.jeditable.js"></script>
 +    <script type="text/javascript" src="js/jquery.fileupload.js"></script>
 +    <script type="text/javascript" src="js/jquery.iframe-transport.js"></script>
 +    <script type="text/javascript" src="js/bootstrap.min.js"></script>
 +    <script type="text/javascript" src="js/tmpl.min.js"></script>
 +    <script type="text/javascript">
 +      var _device = "%device%";
 +    </script>
 +    <script type="text/javascript" src="js/index.js"></script>
 +  </head>
 +  <body>
 +    
 +    <div class="container">
 +      
 +      <div class="page-header">
 +        <h1>%header%</h1>
 +      </div>
 +      
 +      %prologue%
 +      
 +      <div id="alerts"></div>
 +      
 +      <div class="btn-toolbar">
-         <button type="button" class="btn btn-primary fileinput-button">
++        <button type="button" class="btn btn-primary fileinput-button" id="upload-file">
 +          <span class="glyphicon glyphicon-upload"></span> Upload Files&hellip;
 +          <input id="fileupload" type="file" name="files[]" multiple>
 +        </button>
 +        <button type="button" class="btn btn-success" id="create-folder">
 +          <span class="glyphicon glyphicon-folder-close"></span> Create Folder&hellip;
 +        </button>
 +        <button type="button" class="btn btn-default" id="reload">
 +          <span class="glyphicon glyphicon-refresh"></span> Refresh
 +        </button>
 +      </div>
 +      
 +      <div class="panel panel-default uploading">
 +        <div class="panel-heading">File Uploads in Progress</div>
 +        <table class="table table-striped"><tbody id="uploads"></tbody></table>
 +      </div>
 +      
 +      <div class="panel panel-default">
 +        <div class="panel-heading">
 +          <ol class="breadcrumb" id="path"></ol>
 +        </div>
 +        <table class="table table-striped"><tbody id="listing"></tbody></table>
 +      </div>
 +      
 +      %epilogue%
 +      
 +      <p class="footer">%footer%</p>
 +      
 +    </div>
 +    
 +    <div class="modal fade" id="create-modal" tabindex="-1">
 +      <div class="modal-dialog">
 +        <div class="modal-content">
 +          <div class="modal-header">
 +            <button type="button" class="close" data-dismiss="modal">&times;</button>
 +            <h4 class="modal-title">Create Folder</h4>
 +          </div>
 +          <div class="modal-body">
 +            <p>Please enter the name of the folder to be created:</p>
 +            <form onsubmit="return false">
 +              <input type="text" autocomplete="off" id="create-input">
 +            </form>
 +          </div>
 +          <div class="modal-footer">
 +            <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
 +            <button type="button" class="btn btn-primary" id="create-confirm">Create Folder</button>
 +          </div>
 +        </div>
 +      </div>
 +    </div>
 +    
 +    <div class="modal fade" id="move-modal" tabindex="-1">
 +      <div class="modal-dialog">
 +        <div class="modal-content">
 +          <div class="modal-header">
 +            <button type="button" class="close" data-dismiss="modal">&times;</button>
 +            <h4 class="modal-title">Move Item</h4>
 +          </div>
 +          <div class="modal-body">
 +            <p>Please enter the new location for this item:</p>
 +            <form onsubmit="return false">
 +              <input type="text" autocomplete="off" id="move-input">
 +            </form>
 +          </div>
 +          <div class="modal-footer">
 +            <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
 +            <button type="button" class="btn btn-primary" id="move-confirm">Move Item</button>
 +          </div>
 +        </div>
 +      </div>
 +    </div>
 +    
 +    <script type="text/x-tmpl" id="template-listing">
 +      <tr class="row-file">
 +        <td class="column-icon">
 +          {% if (o.size != null) { %}
 +            <button type="button" class="btn btn-default btn-xs button-download">
 +              <span class="glyphicon glyphicon-download-alt"></span>
 +            </button>
 +          {% } else { %}
 +            <button type="button" class="btn btn-default btn-xs button-open">
 +              <span class="glyphicon glyphicon-folder-open"></span>
 +            </button>
 +          {% } %}
 +        </td>
 +        <td class="column-name"><p class="edit">{%=o.name%}</p></td>
 +        <td class="column-size">
 +          {% if (o.size != null) { %}
 +            <p>{%=formatFileSize(o.size)%}</p>
 +          {% } %}
 +        </td>
 +        <td class="column-move">
 +          <button type="button" class="btn btn-default btn-xs button-move">
 +            <span class="glyphicon glyphicon glyphicon-share-alt"></span>
 +          </button>
 +        </td>
 +        <td class="column-delete">
 +          <button type="button" class="btn btn-danger btn-xs button-delete">
 +            <span class="glyphicon glyphicon-trash"></span>
 +          </button>
 +        </td>
 +      </tr>
 +    </script>
 +    
 +    <script type="text/x-tmpl" id="template-uploads">
 +      <tr class="row-file">
 +        <td class="column-icon">
 +          <button type="button" class="btn btn-warning btn-xs button-cancel">
 +            <span class="glyphicon glyphicon-ban-circle"></span>
 +          </button>
 +        </td>
 +        <td class="column-path"><p>{%=o.path%}</p></td>
 +        <td class="column-progress">
 +          <div class="progress">
 +            <div class="progress-bar" id="progress-bar"></div>
 +          </div>
 +        </ts>
 +      </tr>
 +    </script>
 +    
 +    <script type="text/x-tmpl" id="template-alert">
 +      <div class="alert alert-{%=o.level%} alert-dismissable">
 +        <button type="button" class="close" data-dismiss="alert">&times;</button>
 +        <strong>{%=o.title%}</strong>{%=o.description%}
 +      </div>
 +    </script>
 +    
 +  </body>
 +</html>

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/js/index.js
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/js/index.js
index 5bd9218,0000000..012926d
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/js/index.js
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.bundle/js/index.js
@@@ -1,305 -1,0 +1,316 @@@
 +/*
-  Copyright (c) 2012-2014, Pierre-Olivier Latour
++ Copyright (c) 2012-2015, Pierre-Olivier Latour
 + All rights reserved.
 + 
 + Redistribution and use in source and binary forms, with or without
 + modification, are permitted provided that the following conditions are met:
 + * Redistributions of source code must retain the above copyright
 + notice, this list of conditions and the following disclaimer.
 + * Redistributions in binary form must reproduce the above copyright
 + notice, this list of conditions and the following disclaimer in the
 + documentation and/or other materials provided with the distribution.
 + * The name of Pierre-Olivier Latour may not be used to endorse
 + or promote products derived from this software without specific
 + prior written permission.
 + 
 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
 + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +var ENTER_KEYCODE = 13;
 +
 +var _path = null;
 +var _pendingReloads = [];
 +var _reloadingDisabled = 0;
 +
 +function formatFileSize(bytes) {
 +  if (bytes >= 1000000000) {
 +    return (bytes / 1000000000).toFixed(2) + ' GB';
 +  }
 +  if (bytes >= 1000000) {
 +    return (bytes / 1000000).toFixed(2) + ' MB';
 +  }
 +  return (bytes / 1000).toFixed(2) + ' KB';
 +}
 +
 +function _showError(message, textStatus, errorThrown) {
 +  $("#alerts").prepend(tmpl("template-alert", {
 +    level: "danger",
 +    title: (errorThrown != "" ? errorThrown : textStatus) + ": ",
 +    description: message
 +  }));
 +}
 +
 +function _disableReloads() {
 +  _reloadingDisabled += 1;
 +}
 +
 +function _enableReloads() {
 +  _reloadingDisabled -= 1;
 +  
 +  if (_pendingReloads.length > 0) {
 +    _reload(_pendingReloads.shift());
 +  }
 +}
 +
 +function _reload(path) {
 +  if (_reloadingDisabled) {
 +    if ($.inArray(path, _pendingReloads) < 0) {
 +      _pendingReloads.push(path);
 +    }
 +    return;
 +  }
 +  
 +  _disableReloads();
 +  $.ajax({
 +    url: 'list',
 +    type: 'GET',
 +    data: {path: path},
 +    dataType: 'json'
 +  }).fail(function(jqXHR, textStatus, errorThrown) {
 +    _showError("Failed retrieving contents of \"" + path + "\"", textStatus, errorThrown);
 +  }).done(function(data, textStatus, jqXHR) {
 +    var scrollPosition = $(document).scrollTop();
 +    
 +    if (path != _path) {
 +      $("#path").empty();
 +      if (path == "/") {
 +        $("#path").append('<li class="active">' + _device + '</li>');
 +      } else {
 +        $("#path").append('<li data-path="/"><a>' + _device + '</a></li>');
 +        var components = path.split("/").slice(1, -1);
 +        for (var i = 0; i < components.length - 1; ++i) {
 +          var subpath = "/" + components.slice(0, i + 1).join("/") + "/";
 +          $("#path").append('<li data-path="' + subpath + '"><a>' + components[i] + '</a></li>');
 +        }
 +        $("#path > li").click(function(event) {
 +          _reload($(this).data("path"));
 +          event.preventDefault();
 +        });
 +        $("#path").append('<li class="active">' + components[components.length - 1] + '</li>');
 +      }
 +      _path = path;
 +    }
 +    
 +    $("#listing").empty();
 +    for (var i = 0, file; file = data[i]; ++i) {
 +      $(tmpl("template-listing", file)).data(file).appendTo("#listing");
 +    }
 +    
 +    $(".edit").editable(function(value, settings) { 
 +      var name = $(this).parent().parent().data("name");
 +      if (value != name) {
 +        var path = $(this).parent().parent().data("path");
 +        $.ajax({
 +          url: 'move',
 +          type: 'POST',
 +          data: {oldPath: path, newPath: _path + value},
 +          dataType: 'json'
 +        }).fail(function(jqXHR, textStatus, errorThrown) {
 +          _showError("Failed moving \"" + path + "\" to \"" + _path + value + "\"", textStatus, errorThrown);
 +        }).always(function() {
 +          _reload(_path);
 +        });
 +      }
 +      return value;
 +    }, {
 +      onedit: function(settings, original) {
 +        _disableReloads();
 +      },
 +      onsubmit: function(settings, original) {
 +        _enableReloads();
 +      },
 +      onreset: function(settings, original) {
 +        _enableReloads();
 +      },
 +      tooltip: 'Click to rename...'
 +    });
 +    
 +    $(".button-download").click(function(event) {
 +      var path = $(this).parent().parent().data("path");
 +      setTimeout(function() {
 +        window.location = "download?path=" + encodeURIComponent(path);
 +      }, 0);
 +    });
 +    
 +    $(".button-open").click(function(event) {
 +      var path = $(this).parent().parent().data("path");
 +      _reload(path);
 +    });
 +    
 +    $(".button-move").click(function(event) {
 +      var path = $(this).parent().parent().data("path");
 +      if (path[path.length - 1] == "/") {
 +        path = path.slice(0, path.length - 1);
 +      }
 +      $("#move-input").data("path", path);
 +      $("#move-input").val(path);
 +      $("#move-modal").modal("show");
 +    });
 +    
 +    $(".button-delete").click(function(event) {
 +      var path = $(this).parent().parent().data("path");
 +      $.ajax({
 +        url: 'delete',
 +        type: 'POST',
 +        data: {path: path},
 +        dataType: 'json'
 +      }).fail(function(jqXHR, textStatus, errorThrown) {
 +        _showError("Failed deleting \"" + path + "\"", textStatus, errorThrown);
 +      }).always(function() {
 +        _reload(_path);
 +      });
 +    });
 +    
 +    $(document).scrollTop(scrollPosition);
 +  }).always(function() {
 +    _enableReloads();
 +  });
 +}
 +
 +$(document).ready(function() {
 +  
++  // Workaround Firefox and IE not showing file selection dialog when clicking on "upload-file" <button>
++  // Making it a <div> instead also works but then it the button doesn't work anymore with tab selection or accessibility
++  $("#upload-file").click(function(event) {
++    $("#fileupload").click();
++  });
++  
++  // Prevent event bubbling when using workaround above
++  $("#fileupload").click(function(event) {
++    event.stopPropagation();
++  });
++  
 +  $("#fileupload").fileupload({
 +    dropZone: $(document),
 +    pasteZone: null,
 +    autoUpload: true,
 +    sequentialUploads: true,
 +    // limitConcurrentUploads: 2,
 +    // forceIframeTransport: true,
 +    
 +    url: 'upload',
 +    type: 'POST',
 +    dataType: 'json',
 +    
 +    start: function(e) {
 +      $(".uploading").show();
 +    },
 +    
 +    stop: function(e) {
 +      $(".uploading").hide();
 +    },
 +    
 +    add: function(e, data) {
 +      var file = data.files[0];
 +      data.formData = {
 +        path: _path
 +      };
 +      data.context = $(tmpl("template-uploads", {
 +        path: _path + file.name
 +      })).appendTo("#uploads");
 +      var jqXHR = data.submit();
 +      data.context.find("button").click(function(event) {
 +        jqXHR.abort();
 +      });
 +    },
 +    
 +    progress: function(e, data) {
 +      var progress = parseInt(data.loaded / data.total * 100, 10);
 +      data.context.find(".progress-bar").css("width", progress + "%");
 +    },
 +    
 +    done: function(e, data) {
 +      _reload(_path);
 +    },
 +    
 +    fail: function(e, data) {
 +      var file = data.files[0];
 +      if (data.errorThrown != "abort") {
 +        _showError("Failed uploading \"" + file.name + "\" to \"" + _path + "\"", data.textStatus, data.errorThrown);
 +      }
 +    },
 +    
 +    always: function(e, data) {
 +      data.context.remove();
 +    },
 +    
 +  });
 +  
 +  $("#create-input").keypress(function(event) {
 +    if (event.keyCode == ENTER_KEYCODE) {
 +      $("#create-confirm").click();
 +    };
 +  });
 +  
 +  $("#create-modal").on("shown.bs.modal", function(event) {
 +    $("#create-input").focus();
 +    $("#create-input").select();
 +  });
 +  
 +  $("#create-folder").click(function(event) {
 +    $("#create-input").val("Untitled folder");
 +    $("#create-modal").modal("show");
 +  });
 +  
 +  $("#create-confirm").click(function(event) {
 +    $("#create-modal").modal("hide");
 +    var name = $("#create-input").val();
 +    if (name != "") {
 +      $.ajax({
 +        url: 'create',
 +        type: 'POST',
 +        data: {path: _path + name},
 +        dataType: 'json'
 +      }).fail(function(jqXHR, textStatus, errorThrown) {
 +        _showError("Failed creating folder \"" + name + "\" in \"" + _path + "\"", textStatus, errorThrown);
 +      }).always(function() {
 +        _reload(_path);
 +      });
 +    }
 +  });
 +  
 +  $("#move-input").keypress(function(event) {
 +    if (event.keyCode == ENTER_KEYCODE) {
 +      $("#move-confirm").click();
 +    };
 +  });
 +  
 +  $("#move-modal").on("shown.bs.modal", function(event) {
 +    $("#move-input").focus();
 +    $("#move-input").select();
 +  })
 +  
 +  $("#move-confirm").click(function(event) {
 +    $("#move-modal").modal("hide");
 +    var oldPath = $("#move-input").data("path");
 +    var newPath = $("#move-input").val();
 +    if ((newPath != "") && (newPath[0] == "/") && (newPath != oldPath)) {
 +      $.ajax({
 +        url: 'move',
 +        type: 'POST',
 +        data: {oldPath: oldPath, newPath: newPath},
 +        dataType: 'json'
 +      }).fail(function(jqXHR, textStatus, errorThrown) {
 +        _showError("Failed moving \"" + oldPath + "\" to \"" + newPath + "\"", textStatus, errorThrown);
 +      }).always(function() {
 +        _reload(_path);
 +      });
 +    }
 +  });
 +  
 +  $("#reload").click(function(event) {
 +    _reload(_path);
 +  });
 +  
 +  _reload("/");
 +  
 +});

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.h
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.h
index 02ff30d,0000000..d2c92e9
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.h
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.h
@@@ -1,197 -1,0 +1,197 @@@
 +/*
-  Copyright (c) 2012-2014, Pierre-Olivier Latour
++ Copyright (c) 2012-2015, Pierre-Olivier Latour
 + All rights reserved.
 + 
 + Redistribution and use in source and binary forms, with or without
 + modification, are permitted provided that the following conditions are met:
 + * Redistributions of source code must retain the above copyright
 + notice, this list of conditions and the following disclaimer.
 + * Redistributions in binary form must reproduce the above copyright
 + notice, this list of conditions and the following disclaimer in the
 + documentation and/or other materials provided with the distribution.
 + * The name of Pierre-Olivier Latour may not be used to endorse
 + or promote products derived from this software without specific
 + prior written permission.
 + 
 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
 + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#import "GCDWebServer.h"
 +
 +@class GCDWebUploader;
 +
 +/**
 + *  Delegate methods for GCDWebUploader.
 + *
 + *  @warning These methods are always called on the main thread in a serialized way.
 + */
 +@protocol GCDWebUploaderDelegate <GCDWebServerDelegate>
 +@optional
 +
 +/**
 + *  This method is called whenever a file has been downloaded.
 + */
 +- (void)webUploader:(GCDWebUploader*)uploader didDownloadFileAtPath:(NSString*)path;
 +
 +/**
 + *  This method is called whenever a file has been uploaded.
 + */
 +- (void)webUploader:(GCDWebUploader*)uploader didUploadFileAtPath:(NSString*)path;
 +
 +/**
 + *  This method is called whenever a file or directory has been moved.
 + */
 +- (void)webUploader:(GCDWebUploader*)uploader didMoveItemFromPath:(NSString*)fromPath toPath:(NSString*)toPath;
 +
 +/**
 + *  This method is called whenever a file or directory has been deleted.
 + */
 +- (void)webUploader:(GCDWebUploader*)uploader didDeleteItemAtPath:(NSString*)path;
 +
 +/**
 + *  This method is called whenever a directory has been created.
 + */
 +- (void)webUploader:(GCDWebUploader*)uploader didCreateDirectoryAtPath:(NSString*)path;
 +
 +@end
 +
 +/**
 + *  The GCDWebUploader subclass of GCDWebServer implements an HTML 5 web browser
 + *  interface for uploading or downloading files, and moving or deleting files
 + *  or directories.
 + *
 + *  See the README.md file for more information about the features of GCDWebUploader.
 + *
 + *  @warning For GCDWebUploader to work, "GCDWebUploader.bundle" must be added
 + *  to the resources of the Xcode target.
 + */
 +@interface GCDWebUploader : GCDWebServer
 +
 +/**
 + *  Returns the upload directory as specified when the uploader was initialized.
 + */
 +@property(nonatomic, readonly) NSString* uploadDirectory;
 +
 +/**
 + *  Sets the delegate for the uploader.
 + */
 +@property(nonatomic, assign) id<GCDWebUploaderDelegate> delegate;
 +
 +/**
 + *  Sets which files are allowed to be operated on depending on their extension.
 + *
 + *  The default value is nil i.e. all file extensions are allowed.
 + */
 +@property(nonatomic, copy) NSArray* allowedFileExtensions;
 +
 +/**
 + *  Sets if files and directories whose name start with a period are allowed to
 + *  be operated on.
 + *
 + *  The default value is NO.
 + */
 +@property(nonatomic) BOOL allowHiddenItems;
 +
 +/**
 + *  Sets the title for the uploader web interface.
 + *
 + *  The default value is the application name.
 + *
 + *  @warning Any reserved HTML characters in the string value for this property
 + *  must have been replaced by character entities e.g. "&" becomes "&amp;".
 + */
 +@property(nonatomic, copy) NSString* title;
 +
 +/**
 + *  Sets the header for the uploader web interface.
 + *
 + *  The default value is the same as the title property.
 + *
 + *  @warning Any reserved HTML characters in the string value for this property
 + *  must have been replaced by character entities e.g. "&" becomes "&amp;".
 + */
 +@property(nonatomic, copy) NSString* header;
 +
 +/**
 + *  Sets the prologue for the uploader web interface.
 + *
 + *  The default value is a short help text.
 + *
 + *  @warning The string value for this property must be raw HTML
 + *  e.g. "<p>Some text</p>"
 + */
 +@property(nonatomic, copy) NSString* prologue;
 +
 +/**
 + *  Sets the epilogue for the uploader web interface.
 + *
 + *  The default value is nil i.e. no epilogue.
 + *
 + *  @warning The string value for this property must be raw HTML
 + *  e.g. "<p>Some text</p>"
 + */
 +@property(nonatomic, copy) NSString* epilogue;
 +
 +/**
 + *  Sets the footer for the uploader web interface.
 + *
 + *  The default value is the application name and version.
 + *
 + *  @warning Any reserved HTML characters in the string value for this property
 + *  must have been replaced by character entities e.g. "&" becomes "&amp;".
 + */
 +@property(nonatomic, copy) NSString* footer;
 +
 +/**
 + *  This method is the designated initializer for the class.
 + */
 +- (instancetype)initWithUploadDirectory:(NSString*)path;
 +
 +@end
 +
 +/**
 + *  Hooks to customize the behavior of GCDWebUploader.
 + *
 + *  @warning These methods can be called on any GCD thread.
 + */
 +@interface GCDWebUploader (Subclassing)
 +
 +/**
 + *  This method is called to check if a file upload is allowed to complete.
 + *  The uploaded file is available for inspection at "tempPath".
 + *
 + *  The default implementation returns YES.
 + */
 +- (BOOL)shouldUploadFileAtPath:(NSString*)path withTemporaryFile:(NSString*)tempPath;
 +
 +/**
 + *  This method is called to check if a file or directory is allowed to be moved.
 + *
 + *  The default implementation returns YES.
 + */
 +- (BOOL)shouldMoveItemFromPath:(NSString*)fromPath toPath:(NSString*)toPath;
 +
 +/**
 + *  This method is called to check if a file or directory is allowed to be deleted.
 + *
 + *  The default implementation returns YES.
 + */
 +- (BOOL)shouldDeleteItemAtPath:(NSString*)path;
 +
 +/**
 + *  This method is called to check if a directory is allowed to be created.
 + *
 + *  The default implementation returns YES.
 + */
 +- (BOOL)shouldCreateDirectoryAtPath:(NSString*)path;
 +
 +@end

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.m
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.m
index d88a45a,0000000..9bb4453
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.m
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebUploader/GCDWebUploader.m
@@@ -1,417 -1,0 +1,419 @@@
 +/*
-  Copyright (c) 2012-2014, Pierre-Olivier Latour
++ Copyright (c) 2012-2015, Pierre-Olivier Latour
 + All rights reserved.
 + 
 + Redistribution and use in source and binary forms, with or without
 + modification, are permitted provided that the following conditions are met:
 + * Redistributions of source code must retain the above copyright
 + notice, this list of conditions and the following disclaimer.
 + * Redistributions in binary form must reproduce the above copyright
 + notice, this list of conditions and the following disclaimer in the
 + documentation and/or other materials provided with the distribution.
 + * The name of Pierre-Olivier Latour may not be used to endorse
 + or promote products derived from this software without specific
 + prior written permission.
 + 
 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 + DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY
 + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#if !__has_feature(objc_arc)
 +#error GCDWebUploader requires ARC
 +#endif
 +
 +#import <TargetConditionals.h>
 +#if TARGET_OS_IPHONE
 +#import <UIKit/UIKit.h>
 +#else
 +#import <SystemConfiguration/SystemConfiguration.h>
 +#endif
 +
 +#import "GCDWebUploader.h"
 +
 +#import "GCDWebServerDataRequest.h"
 +#import "GCDWebServerMultiPartFormRequest.h"
 +#import "GCDWebServerURLEncodedFormRequest.h"
 +
 +#import "GCDWebServerDataResponse.h"
 +#import "GCDWebServerErrorResponse.h"
 +#import "GCDWebServerFileResponse.h"
 +
 +@interface GCDWebUploader () {
 +@private
 +  NSString* _uploadDirectory;
 +  NSArray* _allowedExtensions;
 +  BOOL _allowHidden;
 +  NSString* _title;
 +  NSString* _header;
 +  NSString* _prologue;
 +  NSString* _epilogue;
 +  NSString* _footer;
 +}
 +@end
 +
 +@implementation GCDWebUploader (Methods)
 +
 +// Must match implementation in GCDWebDAVServer
 +- (BOOL)_checkSandboxedPath:(NSString*)path {
 +  return [[path stringByStandardizingPath] hasPrefix:_uploadDirectory];
 +}
 +
 +- (BOOL)_checkFileExtension:(NSString*)fileName {
 +  if (_allowedExtensions && ![_allowedExtensions containsObject:[[fileName pathExtension] lowercaseString]]) {
 +    return NO;
 +  }
 +  return YES;
 +}
 +
 +- (NSString*) _uniquePathForPath:(NSString*)path {
 +  if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
 +    NSString* directory = [path stringByDeletingLastPathComponent];
 +    NSString* file = [path lastPathComponent];
 +    NSString* base = [file stringByDeletingPathExtension];
 +    NSString* extension = [file pathExtension];
 +    int retries = 0;
 +    do {
 +      if (extension.length) {
 +        path = [directory stringByAppendingPathComponent:[[base stringByAppendingFormat:@" (%i)", ++retries] stringByAppendingPathExtension:extension]];
 +      } else {
 +        path = [directory stringByAppendingPathComponent:[base stringByAppendingFormat:@" (%i)", ++retries]];
 +      }
 +    } while ([[NSFileManager defaultManager] fileExistsAtPath:path]);
 +  }
 +  return path;
 +}
 +
 +- (GCDWebServerResponse*)listDirectory:(GCDWebServerRequest*)request {
 +  NSString* relativePath = [[request query] objectForKey:@"path"];
 +  NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
 +  BOOL isDirectory = NO;
 +  if (![self _checkSandboxedPath:absolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
 +  }
 +  if (!isDirectory) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"\"%@\" is not a directory", relativePath];
 +  }
 +  
 +  NSString* directoryName = [absolutePath lastPathComponent];
 +  if (!_allowHidden && [directoryName hasPrefix:@"."]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Listing directory name \"%@\" is not allowed", directoryName];
 +  }
 +  
 +  NSError* error = nil;
 +  NSArray* contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:absolutePath error:&error];
 +  if (contents == nil) {
 +    return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed listing directory \"%@\"", relativePath];
 +  }
 +  
 +  NSMutableArray* array = [NSMutableArray array];
 +  for (NSString* item in [contents sortedArrayUsingSelector:@selector(localizedStandardCompare:)]) {
 +    if (_allowHidden || ![item hasPrefix:@"."]) {
 +      NSDictionary* attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[absolutePath stringByAppendingPathComponent:item] error:NULL];
 +      NSString* type = [attributes objectForKey:NSFileType];
 +      if ([type isEqualToString:NSFileTypeRegular] && [self _checkFileExtension:item]) {
 +        [array addObject:@{
 +                           @"path": [relativePath stringByAppendingPathComponent:item],
 +                           @"name": item,
 +                           @"size": [attributes objectForKey:NSFileSize]
 +                           }];
 +      } else if ([type isEqualToString:NSFileTypeDirectory]) {
 +        [array addObject:@{
 +                           @"path": [[relativePath stringByAppendingPathComponent:item] stringByAppendingString:@"/"],
 +                           @"name": item
 +                           }];
 +      }
 +    }
 +  }
 +  return [GCDWebServerDataResponse responseWithJSONObject:array];
 +}
 +
 +- (GCDWebServerResponse*)downloadFile:(GCDWebServerRequest*)request {
 +  NSString* relativePath = [[request query] objectForKey:@"path"];
 +  NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
 +  BOOL isDirectory = NO;
 +  if (![self _checkSandboxedPath:absolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
 +  }
 +  if (isDirectory) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"\"%@\" is a directory", relativePath];
 +  }
 +  
 +  NSString* fileName = [absolutePath lastPathComponent];
 +  if (([fileName hasPrefix:@"."] && !_allowHidden) || ![self _checkFileExtension:fileName]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Downlading file name \"%@\" is not allowed", fileName];
 +  }
 +  
 +  if ([self.delegate respondsToSelector:@selector(webUploader:didDownloadFileAtPath:  )]) {
 +    dispatch_async(dispatch_get_main_queue(), ^{
 +      [self.delegate webUploader:self didDownloadFileAtPath:absolutePath];
 +    });
 +  }
 +  return [GCDWebServerFileResponse responseWithFile:absolutePath isAttachment:YES];
 +}
 +
 +- (GCDWebServerResponse*)uploadFile:(GCDWebServerMultiPartFormRequest*)request {
 +  NSRange range = [[request.headers objectForKey:@"Accept"] rangeOfString:@"application/json" options:NSCaseInsensitiveSearch];
 +  NSString* contentType = (range.location != NSNotFound ? @"application/json" : @"text/plain; charset=utf-8");  // Required when using iFrame transport (see https://github.com/blueimp/jQuery-File-Upload/wiki/Setup)
 +  
 +  GCDWebServerMultiPartFile* file = [request firstFileForControlName:@"files[]"];
 +  if ((!_allowHidden && [file.fileName hasPrefix:@"."]) || ![self _checkFileExtension:file.fileName]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Uploaded file name \"%@\" is not allowed", file.fileName];
 +  }
 +  NSString* relativePath = [[request firstArgumentForControlName:@"path"] string];
 +  NSString* absolutePath = [self _uniquePathForPath:[[_uploadDirectory stringByAppendingPathComponent:relativePath] stringByAppendingPathComponent:file.fileName]];
 +  if (![self _checkSandboxedPath:absolutePath]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
 +  }
 +  
 +  if (![self shouldUploadFileAtPath:absolutePath withTemporaryFile:file.temporaryPath]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Uploading file \"%@\" to \"%@\" is not permitted", file.fileName, relativePath];
 +  }
 +  
 +  NSError* error = nil;
 +  if (![[NSFileManager defaultManager] moveItemAtPath:file.temporaryPath toPath:absolutePath error:&error]) {
 +    return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed moving uploaded file to \"%@\"", relativePath];
 +  }
 +  
 +  if ([self.delegate respondsToSelector:@selector(webUploader:didUploadFileAtPath:)]) {
 +    dispatch_async(dispatch_get_main_queue(), ^{
 +      [self.delegate webUploader:self didUploadFileAtPath:absolutePath];
 +    });
 +  }
 +  return [GCDWebServerDataResponse responseWithJSONObject:@{} contentType:contentType];
 +}
 +
 +- (GCDWebServerResponse*)moveItem:(GCDWebServerURLEncodedFormRequest*)request {
 +  NSString* oldRelativePath = [request.arguments objectForKey:@"oldPath"];
 +  NSString* oldAbsolutePath = [_uploadDirectory stringByAppendingPathComponent:oldRelativePath];
 +  BOOL isDirectory = NO;
 +  if (![self _checkSandboxedPath:oldAbsolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:oldAbsolutePath isDirectory:&isDirectory]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", oldRelativePath];
 +  }
 +  
 +  NSString* newRelativePath = [request.arguments objectForKey:@"newPath"];
 +  NSString* newAbsolutePath = [self _uniquePathForPath:[_uploadDirectory stringByAppendingPathComponent:newRelativePath]];
 +  if (![self _checkSandboxedPath:newAbsolutePath]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", newRelativePath];
 +  }
 +  
 +  NSString* itemName = [newAbsolutePath lastPathComponent];
 +  if ((!_allowHidden && [itemName hasPrefix:@"."]) || (!isDirectory && ![self _checkFileExtension:itemName])) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Moving to item name \"%@\" is not allowed", itemName];
 +  }
 +  
 +  if (![self shouldMoveItemFromPath:oldAbsolutePath toPath:newAbsolutePath]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Moving \"%@\" to \"%@\" is not permitted", oldRelativePath, newRelativePath];
 +  }
 +  
 +  NSError* error = nil;
 +  if (![[NSFileManager defaultManager] moveItemAtPath:oldAbsolutePath toPath:newAbsolutePath error:&error]) {
 +    return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed moving \"%@\" to \"%@\"", oldRelativePath, newRelativePath];
 +  }
 +  
 +  if ([self.delegate respondsToSelector:@selector(webUploader:didMoveItemFromPath:toPath:)]) {
 +    dispatch_async(dispatch_get_main_queue(), ^{
 +      [self.delegate webUploader:self didMoveItemFromPath:oldAbsolutePath toPath:newAbsolutePath];
 +    });
 +  }
 +  return [GCDWebServerDataResponse responseWithJSONObject:@{}];
 +}
 +
 +- (GCDWebServerResponse*)deleteItem:(GCDWebServerURLEncodedFormRequest*)request {
 +  NSString* relativePath = [request.arguments objectForKey:@"path"];
 +  NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
 +  BOOL isDirectory = NO;
 +  if (![self _checkSandboxedPath:absolutePath] || ![[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
 +  }
 +  
 +  NSString* itemName = [absolutePath lastPathComponent];
 +  if (([itemName hasPrefix:@"."] && !_allowHidden) || (!isDirectory && ![self _checkFileExtension:itemName])) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Deleting item name \"%@\" is not allowed", itemName];
 +  }
 +  
 +  if (![self shouldDeleteItemAtPath:absolutePath]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Deleting \"%@\" is not permitted", relativePath];
 +  }
 +  
 +  NSError* error = nil;
 +  if (![[NSFileManager defaultManager] removeItemAtPath:absolutePath error:&error]) {
 +    return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed deleting \"%@\"", relativePath];
 +  }
 +  
 +  if ([self.delegate respondsToSelector:@selector(webUploader:didDeleteItemAtPath:)]) {
 +    dispatch_async(dispatch_get_main_queue(), ^{
 +      [self.delegate webUploader:self didDeleteItemAtPath:absolutePath];
 +    });
 +  }
 +  return [GCDWebServerDataResponse responseWithJSONObject:@{}];
 +}
 +
 +- (GCDWebServerResponse*)createDirectory:(GCDWebServerURLEncodedFormRequest*)request {
 +  NSString* relativePath = [request.arguments objectForKey:@"path"];
 +  NSString* absolutePath = [self _uniquePathForPath:[_uploadDirectory stringByAppendingPathComponent:relativePath]];
 +  if (![self _checkSandboxedPath:absolutePath]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
 +  }
 +  
 +  NSString* directoryName = [absolutePath lastPathComponent];
 +  if (!_allowHidden && [directoryName hasPrefix:@"."]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Creating directory name \"%@\" is not allowed", directoryName];
 +  }
 +  
 +  if (![self shouldCreateDirectoryAtPath:absolutePath]) {
 +    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Creating directory \"%@\" is not permitted", relativePath];
 +  }
 +  
 +  NSError* error = nil;
 +  if (![[NSFileManager defaultManager] createDirectoryAtPath:absolutePath withIntermediateDirectories:NO attributes:nil error:&error]) {
 +    return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed creating directory \"%@\"", relativePath];
 +  }
 +  
 +  if ([self.delegate respondsToSelector:@selector(webUploader:didCreateDirectoryAtPath:)]) {
 +    dispatch_async(dispatch_get_main_queue(), ^{
 +      [self.delegate webUploader:self didCreateDirectoryAtPath:absolutePath];
 +    });
 +  }
 +  return [GCDWebServerDataResponse responseWithJSONObject:@{}];
 +}
 +
 +@end
 +
 +@implementation GCDWebUploader
 +
 +@synthesize uploadDirectory=_uploadDirectory, allowedFileExtensions=_allowedExtensions, allowHiddenItems=_allowHidden,
 +            title=_title, header=_header, prologue=_prologue, epilogue=_epilogue, footer=_footer;
 +
++@dynamic delegate;
++
 +- (instancetype)initWithUploadDirectory:(NSString*)path {
 +  if ((self = [super init])) {
-     NSBundle* siteBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"GCDWebUploader" ofType:@"bundle"]];
++    NSBundle* siteBundle = [NSBundle bundleWithPath:[[NSBundle bundleForClass:[GCDWebUploader class]] pathForResource:@"GCDWebUploader" ofType:@"bundle"]];
 +    if (siteBundle == nil) {
 +      return nil;
 +    }
 +    _uploadDirectory = [[path stringByStandardizingPath] copy];
 +    GCDWebUploader* __unsafe_unretained server = self;
 +    
 +    // Resource files
 +    [self addGETHandlerForBasePath:@"/" directoryPath:[siteBundle resourcePath] indexFilename:nil cacheAge:3600 allowRangeRequests:NO];
 +    
 +    // Web page
 +    [self addHandlerForMethod:@"GET" path:@"/" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
 +      
 +#if TARGET_OS_IPHONE
 +      NSString* device = [[UIDevice currentDevice] name];
 +#else
 +      NSString* device = CFBridgingRelease(SCDynamicStoreCopyComputerName(NULL, NULL));
 +#endif
 +      NSString* title = server.title;
 +      if (title == nil) {
 +        title = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
 +        if (title == nil) {
 +          title = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
 +        }
 +#if !TARGET_OS_IPHONE
 +        if (title == nil) {
 +          title = [[NSProcessInfo processInfo] processName];
 +        }
 +#endif
 +      }
 +      NSString* header = server.header;
 +      if (header == nil) {
 +        header = title;
 +      }
 +      NSString* prologue = server.prologue;
 +      if (prologue == nil) {
 +        prologue = [siteBundle localizedStringForKey:@"PROLOGUE" value:@"" table:nil];
 +      }
 +      NSString* epilogue = server.epilogue;
 +      if (epilogue == nil) {
 +        epilogue = [siteBundle localizedStringForKey:@"EPILOGUE" value:@"" table:nil];
 +      }
 +      NSString* footer = server.footer;
 +      if (footer == nil) {
 +        NSString* name = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
 +        NSString* version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
 +#if !TARGET_OS_IPHONE
 +        if (!name && !version) {
 +          name = @"OS X";
 +          version = [[NSProcessInfo processInfo] operatingSystemVersionString];
 +        }
 +#endif
 +        footer = [NSString stringWithFormat:[siteBundle localizedStringForKey:@"FOOTER_FORMAT" value:@"" table:nil], name, version];
 +      }
 +      return [GCDWebServerDataResponse responseWithHTMLTemplate:[siteBundle pathForResource:@"index" ofType:@"html"]
 +                                                      variables:@{
 +                                                                  @"device": device,
 +                                                                  @"title": title,
 +                                                                  @"header": header,
 +                                                                  @"prologue": prologue,
 +                                                                  @"epilogue": epilogue,
 +                                                                  @"footer": footer
 +                                                                  }];
 +      
 +    }];
 +    
 +    // File listing
 +    [self addHandlerForMethod:@"GET" path:@"/list" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
 +      return [server listDirectory:request];
 +    }];
 +    
 +    // File download
 +    [self addHandlerForMethod:@"GET" path:@"/download" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
 +      return [server downloadFile:request];
 +    }];
 +    
 +    // File upload
 +    [self addHandlerForMethod:@"POST" path:@"/upload" requestClass:[GCDWebServerMultiPartFormRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
 +      return [server uploadFile:(GCDWebServerMultiPartFormRequest*)request];
 +    }];
 +    
 +    // File and folder moving
 +    [self addHandlerForMethod:@"POST" path:@"/move" requestClass:[GCDWebServerURLEncodedFormRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
 +      return [server moveItem:(GCDWebServerURLEncodedFormRequest*)request];
 +    }];
 +    
 +    // File and folder deletion
 +    [self addHandlerForMethod:@"POST" path:@"/delete" requestClass:[GCDWebServerURLEncodedFormRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
 +      return [server deleteItem:(GCDWebServerURLEncodedFormRequest*)request];
 +    }];
 +    
 +    // Directory creation
 +    [self addHandlerForMethod:@"POST" path:@"/create" requestClass:[GCDWebServerURLEncodedFormRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
 +      return [server createDirectory:(GCDWebServerURLEncodedFormRequest*)request];
 +    }];
 +    
 +  }
 +  return self;
 +}
 +
 +@end
 +
 +@implementation GCDWebUploader (Subclassing)
 +
 +- (BOOL)shouldUploadFileAtPath:(NSString*)path withTemporaryFile:(NSString*)tempPath {
 +  return YES;
 +}
 +
 +- (BOOL)shouldMoveItemFromPath:(NSString*)fromPath toPath:(NSString*)toPath {
 +  return YES;
 +}
 +
 +- (BOOL)shouldDeleteItemAtPath:(NSString*)path {
 +  return YES;
 +}
 +
 +- (BOOL)shouldCreateDirectoryAtPath:(NSString*)path {
 +  return YES;
 +}
 +
 +@end


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org