cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From shaz...@apache.org
Subject [24/50] cordova-plugins git commit: Removed plugins other than local-webserver, moved plugin to root
Date Wed, 22 Feb 2017 02:29:14 GMT
http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/notification/src/firefoxos/notification.js
----------------------------------------------------------------------
diff --git a/notification/src/firefoxos/notification.js b/notification/src/firefoxos/notification.js
deleted file mode 100644
index 4ff541a..0000000
--- a/notification/src/firefoxos/notification.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- *
- * 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.
- *
-*/ 
-
-var NotificationError = require('./NotificationError');
-var modulemapper = require('cordova/modulemapper');
-
-// keep hold of notification for future use
-var mozNotifications = {};
-var mozNotification = modulemapper.getOriginalSymbol(window, 'window.Notification');
-
-var closeEvent = new Event('close');
-var clickEvent = new Event('click');
-var showEvent = new Event('show');
-var errorEvent = new Event('error');
-
-function makeNotification(successCB, errorCB, options) {
-    var title = options.title;
-    var nId = options.notificationId;
-    var pluginObject = options.pluginObject;
-    delete options.title;
-    delete options.notificationId;
-    delete options.pluginObject;
-
-    var notification = new mozNotification(title, options);
-    mozNotifications[nId] = notification;
-
-    // handle events
-    notification.onclose = function() {
-        pluginObject.dispatchEvent(closeEvent);
-    }
-    notification.onclick = function() {
-        pluginObject.dispatchEvent(clickEvent);
-    }
-    notification.onshow = function() {
-        pluginObject.dispatchEvent(showEvent);
-    }
-    notification.onerror = function() {
-        pluginObject.dispatchEvent(errorEvent);
-    }
-
-    successCB();
-}
-
-// errors currently reporting String for debug only
-function create(successCB, errorCB, options) {
-    console.log('FxOS DEBUG: create', options);
-
-    if (mozNotification.permission === 'denied') {
-        errorCB(new NotificationError(NotificationError.PERMISSION_DENIED,
-              'FxOS Notification: Permission denied'));
-        return;
-    }
-    if (mozNotification.permission === 'granted') {
-        makeNotification(successCB, errorCB, options);
-        return;
-    }
-    mozNotification.requestPermission(function (permission) {
-        if (permission === 'granted') {
-            makeNotification(successCB, errorCB, options);
-        } else {
-            errorCB(new NotificationError(NotificationError.USER_DENIED,
-                  'FxOS Notification: User denied'));
-        }
-    });
-}
-
-function remove(successCB, errorCB, params) {
-    successCB = (successCB) ? successCB : function() {};
-    errorCB = (errorCB) ? errorCB : function() {};
-    var nId = params.notificationId;
-    mozNotifications[nId].close();
-    successCB();
-}
-
-
-module.exports = {
-    create: create,
-    remove: remove
-};    
-    
-require("cordova/exec/proxy").add("Notification", module.exports);

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/notification/www/NotificationError.js
----------------------------------------------------------------------
diff --git a/notification/www/NotificationError.js b/notification/www/NotificationError.js
deleted file mode 100644
index 590720b..0000000
--- a/notification/www/NotificationError.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *
- * 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.
- *
-*/
-
-
-/**
- * Notification error object
- *
- * @constructor
- * @param code
- * @param message
- */
-var NotificationError = function(code, message) {
-    this.code = code || null;
-    this.message = message || '';
-};
-
-// Notification error codes
-NotificationError.UNKNOWN_ERROR = 0;
-NotificationError.PERMISSION_DENIED = 1;
-NotificationError.USER_DENIED = 2;
-
-module.exports = NotificationError;

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/notification/www/notification.js
----------------------------------------------------------------------
diff --git a/notification/www/notification.js b/notification/www/notification.js
deleted file mode 100644
index f10bab3..0000000
--- a/notification/www/notification.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *
- * 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.
- *
-*/
-
-var argscheck = require('cordova/argscheck'),
-    utils = require('cordova/utils'),
-    exec = require('cordova/exec');
-   
-// counter for a notification id
-var nId = 0;
-
-// This might not be the best idea
-// from http://stackoverflow.com/questions/22186467/how-to-use-javascript-eventtarget
-
-function Emitter () {
-  var eventTarget = document.createDocumentFragment();
-
-  function delegate (method) {
-    this[method] = eventTarget[method].bind(eventTarget);
-  }
-
-  Emitter.methods.forEach(delegate, this);
-}
-
-Emitter.methods = ["addEventListener", "dispatchEvent", "removeEventListener"];
-
-function Notification(title, options, successCB, errorCB) {
-
-    options = (options) ? options : {};
-    successCB = (successCB) ? successCB : function() {};
-    errorCB = (errorCB) ? errorCB : function() {};
-
-    // return object in success callback
-    var self = this;
-    function success() {
-        successCB(self);
-    }
-
-    // add emitter methods to Notification
-    Emitter.call(this);
-
-    // set parameters
-    this.title = options.title = title;
-    this.dir = options.dir || null;
-    this.lang = options.lang || null;
-    this.body = options.dir || null;
-    this.dir = options.dir || null;
-    this.dir = options.dir || null;
-    this.dir = options.dir || null;
-    // add and store notificationId
-    this._notificationId = options.notificationId = nId++;
-    options.pluginObject = self;
-    exec(success, errorCB, "Notification", "create", options);
-}
-
-// handling closing an event
-Notification.prototype.close = function(successCB, errorCB) {
-    var options = {notificationId: this._notificationId};
-    exec(successCB, errorCB, "Notification", "remove", options);
-};
-
-module.exports = Notification;

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..9c99957
--- /dev/null
+++ b/package.json
@@ -0,0 +1,36 @@
+{
+  "name": "cordova-labs-local-webserver",
+  "version": "2.3.1",
+  "description": "Cordova Local Web Server Plugin",
+  "cordova": {
+    "id": "cordova-labs-local-webserver",
+    "platforms": [
+      "ios"
+    ]
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/Collaborne/cordova-plugins.git"
+  },
+  "keywords": [
+    "cordova",
+    "local web server",
+    "ecosystem:cordova",
+    "cordova-ios"
+  ],
+  "engines": [
+    {
+      "name": "cordova-ios",
+      "version": ">=4.0.0-dev"
+    }
+  ],
+  "author": "",
+  "license": "Apache-2.0",
+  "bugs": {
+    "url": "https://github.com/Collaborne/cordova-plugins/issues"
+  },
+  "homepage": "https://github.com/Collaborne/cordova-plugins#readme",
+  "dependencies": {
+    "urijs": "^1.17.1"
+  }
+}

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/plugin.xml
----------------------------------------------------------------------
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..e9f1609
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,94 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!--
+  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.
+-->
+<plugin id="cordova-labs-local-webserver" version="2.4.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
+    <name>CordovaLocalWebServer</name>
+    <description>Cordova Local Web Server Plugin</description>
+    <keywords>cordova,local web server</keywords>
+    <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugins.git#local-webserver</repo>
+
+    <hook type="after_plugin_install" src="scripts/after_install.js" />
+    <hook type="before_plugin_uninstall" src="scripts/before_uninstall.js" />
+
+    <dependency id="cordova-plugin-file" url="https://git-wip-us.apache.org/repos/asf/cordova-plugin-file.git" version=">=1.3.4" />
+
+    <engines>
+        <engine name="cordova-ios" version=">=4.1.0" />
+    </engines>
+
+    <!-- ios -->
+    <platform name="ios">
+
+        <config-file target="config.xml" parent="/*">
+		    <feature name="CordovaLocalWebServer">
+			    <param name="ios-package" value="CDVLocalWebServer"/>
+			    <param name="onload" value="true"/>
+		    </feature>
+            <preference name="CordovaLocalWebServerStartOnSimulator" value="true" />
+			<access origin="http://localhost" />
+      <allow-navigation href="http://localhost:*/*" />
+        </config-file>
+		
+        
+	    <header-file src="src/ios/CDVLocalWebServer.h" />
+	    <source-file src="src/ios/CDVLocalWebServer.m" />
+
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServer.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServerConnection.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServerFunctions.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServerHTTPStatusCodes.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServerPrivate.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServerRequest.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServerResponse.h" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServer.m" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServerConnection.m" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServerFunctions.m" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServerRequest.m" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Core/GCDWebServerResponse.m" />
+
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Requests/GCDWebServerDataRequest.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Requests/GCDWebServerFileRequest.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.h" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Requests/GCDWebServerDataRequest.m" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Requests/GCDWebServerFileRequest.m" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.m" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.m" />
+
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerDataResponse.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.h" />
+	    <header-file src="src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.h" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerDataResponse.m" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.m" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.m" />
+	    <source-file src="src/ios/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.m" />
+
+	    <framework src="AssetsLibrary.framework" />
+	    <framework src="MobileCoreServices.framework" />
+	    <framework src="CFNetwork.framework" />
+        <framework src="libz.dylib" />
+
+        <info>
+        If your &lt;content&gt; element did not already point to 'http://localhost[:port]', it will now point to a http://localhost:0 location (randomized port), e.g. &lt;content src="http://localhost:0" /&gt;
+        WARNING: For localStorage and IndexedDB persistence, you must choose a non-randomized port (between 1 and 49152, to avoid the ephemeral port range 49152 to 65535 on iOS).
+    </info>
+
+    </platform>
+</plugin>

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/scripts/after_install.js
----------------------------------------------------------------------
diff --git a/scripts/after_install.js b/scripts/after_install.js
new file mode 100644
index 0000000..90768d8
--- /dev/null
+++ b/scripts/after_install.js
@@ -0,0 +1,61 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+ */
+
+// This script modifies the project root's config.xml
+// The <content> tag "src" attribute is modified to point to http://localhost:0
+
+var fs = require('fs');
+var path = require('path');
+var URI = require('url');
+var old_content_src_value;
+
+module.exports = function(context) {
+    var config_xml = path.join(context.opts.projectRoot, 'config.xml');
+    var et = context.requireCordovaModule('elementtree');
+
+    var data = fs.readFileSync(config_xml).toString();
+    var etree = et.parse(data);
+
+    var content_tags = etree.findall('./content[@src]');
+    if (content_tags.length > 0) {
+        old_content_src_value = content_tags[0].get('src');
+        var content_src = URI.parse(old_content_src_value);
+        if (content_src.hostname !== 'localhost') {
+            var backup_json = path.join(context.opts.plugin.dir, 'backup.json');
+            var backup_value = { content_src : old_content_src_value };
+            fs.writeFileSync(backup_json, JSON.stringify(backup_value));
+
+            // XXX: Should we retain the name of the index file here?
+            content_tags[0].set('src', 'http://localhost:0');
+        }
+    }
+
+    var altcontentsrcTag = etree.findall("./preference[@name='AlternateContentSrc']");
+    if (altcontentsrcTag.length > 0) {
+        altcontentsrcTag[0].set('value', old_content_src_value);
+    } else {
+      var pref = et.Element('preference', { name: 'AlternateContentSrc', value: old_content_src_value });
+      etree.getroot().append(pref);
+    }
+
+    data = etree.write({'indent': 4});
+    fs.writeFileSync(config_xml, data);
+}

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/scripts/before_uninstall.js
----------------------------------------------------------------------
diff --git a/scripts/before_uninstall.js b/scripts/before_uninstall.js
new file mode 100644
index 0000000..ee3bb25
--- /dev/null
+++ b/scripts/before_uninstall.js
@@ -0,0 +1,62 @@
+#!/usr/bin/env node
+
+/*
+ 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.
+ */
+
+// This script modifies the project root's config.xml
+// This restores the content tag's src attribute to its original value.
+
+var content_src_value = "http://localhost:0";
+var fs = require('fs');
+var path = require('path');
+var old_content_src_value;
+
+module.exports = function(context) {
+    var config_xml = path.join(context.opts.projectRoot, 'config.xml');
+    var et = context.requireCordovaModule('elementtree');
+
+    var data = fs.readFileSync(config_xml).toString();
+    var etree = et.parse(data);
+
+    var content_tags = etree.findall('./content[@src]');
+    if (content_tags.length > 0) {
+        var backup_json = path.join(context.opts.plugin.dir, 'backup.json');
+        var backup_data = JSON.parse(fs.readFileSync(backup_json).toString());
+
+        var config_content_src_value = content_tags[0].get('src');
+        // it's our value, we can restore old value
+        if (config_content_src_value === content_src_value) {
+            content_tags[0].set('src', backup_data.content_src);
+        }
+    }
+
+    var altcontentsrcTag = etree.findall("./preference[@name='AlternateContentSrc']");
+    if (altcontentsrcTag.length > 0) {
+      try {
+         // elementtree 0.1.6
+         etree.getroot().remove(altcontentsrcTag[0]);
+      } catch (e) {
+         // elementtree 0.1.5
+         etree.getroot().remove(0, altcontentsrcTag[0]);
+      }
+    }
+
+    data = etree.write({'indent': 4});
+    fs.writeFileSync(config_xml, data);
+}

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/src/ios/CDVLocalWebServer.h
----------------------------------------------------------------------
diff --git a/src/ios/CDVLocalWebServer.h b/src/ios/CDVLocalWebServer.h
new file mode 100644
index 0000000..e5be9f6
--- /dev/null
+++ b/src/ios/CDVLocalWebServer.h
@@ -0,0 +1,26 @@
+/*
+ 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.
+ */
+
+#import <Cordova/CDVPlugin.h>
+#import "GCDWebServer.h"
+
+@interface CDVLocalWebServer : CDVPlugin
+
+@property (nonatomic, strong) GCDWebServer* server;
+@end

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/src/ios/CDVLocalWebServer.m
----------------------------------------------------------------------
diff --git a/src/ios/CDVLocalWebServer.m b/src/ios/CDVLocalWebServer.m
new file mode 100644
index 0000000..91e977f
--- /dev/null
+++ b/src/ios/CDVLocalWebServer.m
@@ -0,0 +1,368 @@
+/*
+ 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.
+ */
+
+#import "CDVLocalWebServer.h"
+#import "GCDWebServerPrivate.h"
+#import <Cordova/CDVViewController.h>
+#import <Cordova/NSDictionary+CordovaPreferences.h>
+#import <AssetsLibrary/AssetsLibrary.h>
+#import <MobileCoreServices/MobileCoreServices.h>
+#import <objc/message.h>
+#import <netinet/in.h>
+
+
+#define LOCAL_FILESYSTEM_PATH   @"local-filesystem"
+#define ASSETS_LIBRARY_PATH     @"assets-library"
+#define ERROR_PATH              @"error"
+
+@interface GCDWebServer()
+- (GCDWebServerResponse*)_responseWithContentsOfDirectory:(NSString*)path;
+@end
+
+
+@implementation CDVLocalWebServer
+
+- (void) pluginInitialize {
+
+    BOOL useLocalWebServer = NO;
+    BOOL requirementsOK = NO;
+    NSString* indexPage = @"index.html";
+    NSString* appBasePath = @"www";
+    NSUInteger port = 80;
+
+    // check the content tag src
+    CDVViewController* vc = (CDVViewController*)self.viewController;
+    NSURL* startPageUrl = [NSURL URLWithString:vc.startPage];
+    if (startPageUrl != nil) {
+        if ([[startPageUrl scheme] isEqualToString:@"http"] && [[startPageUrl host] isEqualToString:@"localhost"]) {
+            port = [[startPageUrl port] unsignedIntegerValue];
+            useLocalWebServer = YES;
+        }
+    }
+
+    requirementsOK = [self checkRequirements];
+    if (!requirementsOK) {
+        useLocalWebServer = NO;
+        NSString* alternateContentSrc = [self.commandDelegate.settings cordovaSettingForKey:@"AlternateContentSrc"];
+        vc.startPage = alternateContentSrc? alternateContentSrc : indexPage;
+    }
+
+    // check setting
+#if TARGET_IPHONE_SIMULATOR
+    if (useLocalWebServer) {
+        NSNumber* startOnSimulatorSetting = [[self.commandDelegate settings] objectForKey:[@"CordovaLocalWebServerStartOnSimulator" lowercaseString]];
+        if (startOnSimulatorSetting) {
+            useLocalWebServer = [startOnSimulatorSetting boolValue];
+        }
+    }
+#endif
+    
+    if (port == 0) {
+        // CB-9096 - actually test for an available port, and set it explicitly
+        port = [self _availablePort];
+    }
+
+    NSString* authToken = [NSString stringWithFormat:@"cdvToken=%@", [[NSProcessInfo processInfo] globallyUniqueString]];
+
+    self.server = [[GCDWebServer alloc] init];
+    [GCDWebServer setLogLevel:kGCDWebServerLoggingLevel_Error];
+
+    if (useLocalWebServer) {
+        [self addAppFileSystemHandler:authToken basePath:[NSString stringWithFormat:@"/%@/", appBasePath] indexPage:indexPage];
+
+        // add after server is started to get the true port
+        [self addFileSystemHandlers:authToken];
+        [self addErrorSystemHandler:authToken];
+        
+        // handlers must be added before server starts
+        [self.server startWithPort:port bonjourName:nil];
+
+        // Update the startPage (supported in cordova-ios 3.7.0, see https://issues.apache.org/jira/browse/CB-7857)
+		vc.startPage = [NSString stringWithFormat:@"http://localhost:%lu/%@/%@?%@", (unsigned long)self.server.port, appBasePath, indexPage, authToken];
+
+    } else {
+        if (requirementsOK) {
+            NSString* error = [NSString stringWithFormat:@"WARNING: CordovaLocalWebServer: <content> tag src is not http://localhost[:port] (is %@).", vc.startPage];
+            NSLog(@"%@", error);
+
+            [self addErrorSystemHandler:authToken];
+            
+            // handlers must be added before server starts
+            [self.server startWithPort:port bonjourName:nil];
+
+            vc.startPage = [self createErrorUrl:error authToken:authToken];
+        } else {
+            GWS_LOG_ERROR(@"%@ stopped, failed requirements check.", [self.server class]);
+        }
+    }
+}
+
+- (NSUInteger) _availablePort
+{
+    struct sockaddr_in addr4;
+    bzero(&addr4, sizeof(addr4));
+    addr4.sin_len = sizeof(addr4);
+    addr4.sin_family = AF_INET;
+    addr4.sin_port = 0; // set to 0 and bind to find available port
+    addr4.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    int listeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (bind(listeningSocket, (const void*)&addr4, sizeof(addr4)) == 0) {
+        struct sockaddr addr;
+        socklen_t addrlen = sizeof(addr);
+        if (getsockname(listeningSocket, &addr, &addrlen) == 0) {
+            struct sockaddr_in* sockaddr = (struct sockaddr_in*)&addr;
+            close(listeningSocket);
+            return ntohs(sockaddr->sin_port);
+        }
+    }
+    
+    return 0;
+}
+
+- (BOOL) checkRequirements
+{
+    NSString* pluginName = @"CDVWKWebViewEngine";
+
+    BOOL hasWkWebView = NSClassFromString(@"WKWebView") != nil;
+    BOOL wkEnginePlugin = [[self.commandDelegate.settings cordovaSettingForKey:@"CordovaWebViewEngine"] isEqualToString:pluginName];
+
+    if (!hasWkWebView) {
+        NSLog(@"[ERROR] %@: WKWebView class not found in the current runtime version.", [self class]);
+    }
+
+    if (!wkEnginePlugin) {
+        NSLog(@"[ERROR] %@: CordovaWebViewEngine preference must be %@", [self class], pluginName);
+    }
+
+    return hasWkWebView && wkEnginePlugin;
+}
+
+- (NSString*) createErrorUrl:(NSString*)error authToken:(NSString*)authToken
+{
+    return [NSString stringWithFormat:@"http://localhost:%lu/%@/%@?%@", (unsigned long)self.server.port, ERROR_PATH, [error stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], authToken];
+}
+
+-  (void) addFileSystemHandlers:(NSString*)authToken
+{
+    [self addLocalFileSystemHandler:authToken];
+    [self addAssetLibraryFileSystemHandler:authToken];
+
+    SEL sel = NSSelectorFromString(@"setUrlTransformer:");
+    __weak __typeof(self) weakSelf = self;
+
+    if ([self.commandDelegate respondsToSelector:sel]) {
+        NSURL* (^urlTransformer)(NSURL*) = ^NSURL* (NSURL* urlToTransform) {
+            NSURL* localServerURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%lu", (unsigned long)weakSelf.server.port]];
+            
+            NSURL* transformedUrl = urlToTransform;
+
+            NSString* localhostUrlString = [NSString stringWithFormat:@"http://localhost:%lu", (unsigned long)[localServerURL.port unsignedIntegerValue]];
+
+            if ([[urlToTransform scheme] isEqualToString:ASSETS_LIBRARY_PATH]) {
+                transformedUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@/%@%@",
+                        localhostUrlString,
+                        ASSETS_LIBRARY_PATH,
+                        urlToTransform.host,
+                        urlToTransform.path
+                        ]];
+
+            } else if ([[urlToTransform scheme] isEqualToString:@"file"]) {
+                transformedUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@%@",
+                       localhostUrlString,
+                        LOCAL_FILESYSTEM_PATH,
+                       urlToTransform.path
+                        ]];
+            }
+
+            return transformedUrl;
+        };
+
+        ((void (*)(id, SEL, id))objc_msgSend)(self.commandDelegate, sel, urlTransformer);
+
+    } else {
+        NSLog(@"WARNING: CDVPlugin's commandDelegate is missing a urlTransformer property. The local web server can't set it to transform file and asset-library urls");
+    }
+}
+
+- (void) addFileSystemHandler:(GCDWebServerAsyncProcessBlock)processRequestForResponseBlock basePath:(NSString*)basePath authToken:(NSString*)authToken cacheAge:(NSUInteger)cacheAge
+{
+    GCDWebServerMatchBlock matchBlock = ^GCDWebServerRequest *(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) {
+
+        if (![requestMethod isEqualToString:@"GET"]) {
+            return nil;
+        }
+        if (![urlPath hasPrefix:basePath]) {
+            return nil;
+        }
+        return [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery];
+    };
+
+    GCDWebServerAsyncProcessBlock asyncProcessBlock = ^void (GCDWebServerRequest* request, GCDWebServerCompletionBlock complete) {
+
+        //check if it is a request from localhost
+        NSString *host = [request.headers objectForKey:@"Host"];
+        if (host==nil || [host hasPrefix:@"localhost"] == NO ) {
+            complete([GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"FORBIDDEN"]);
+            return;
+        }
+
+        //check if the querystring or the cookie has the token
+        BOOL hasToken = (request.URL.query && [request.URL.query containsString:authToken]);
+        NSString *cookie = [request.headers objectForKey:@"Cookie"];
+        BOOL hasCookie = (cookie && [cookie containsString:authToken]);
+        if (!hasToken && !hasCookie) {
+            complete([GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"FORBIDDEN"]);
+            return;
+        }
+
+        processRequestForResponseBlock(request, ^void(GCDWebServerResponse* response){
+            if (response) {
+                response.cacheControlMaxAge = cacheAge;
+            } else {
+                response = [GCDWebServerResponse responseWithStatusCode:kGCDWebServerHTTPStatusCode_NotFound];
+            }
+
+            if (hasToken && !hasCookie) {
+                //set cookie
+                [response setValue:[NSString stringWithFormat:@"%@;path=/", authToken] forAdditionalHeader:@"Set-Cookie"];
+            }
+            complete(response);
+        });
+    };
+
+    [self.server addHandlerWithMatchBlock:matchBlock asyncProcessBlock:asyncProcessBlock];
+}
+
+- (void) addAppFileSystemHandler:(NSString*)authToken basePath:(NSString*)basePath indexPage:(NSString*)indexPage
+{
+    BOOL allowRangeRequests = YES;
+
+    NSString* directoryPath = [[self.commandDelegate pathForResource:indexPage] stringByDeletingLastPathComponent];
+;
+
+    GCDWebServerAsyncProcessBlock processRequestBlock = ^void (GCDWebServerRequest* request, GCDWebServerCompletionBlock complete) {
+
+        NSString* filePath = [directoryPath stringByAppendingPathComponent:[request.path substringFromIndex:basePath.length]];
+        NSString* fileType = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:NULL] fileType];
+        GCDWebServerResponse* response = nil;
+
+        if (fileType) {
+            if ([fileType isEqualToString:NSFileTypeDirectory]) {
+                if (indexPage) {
+                    NSString* indexPath = [filePath stringByAppendingPathComponent:indexPage];
+                    NSString* indexType = [[[NSFileManager defaultManager] attributesOfItemAtPath:indexPath error:NULL] fileType];
+                    if ([indexType isEqualToString:NSFileTypeRegular]) {
+                        complete([GCDWebServerFileResponse responseWithFile:indexPath]);
+                    }
+                }
+                response = [self.server _responseWithContentsOfDirectory:filePath];
+            } else if ([fileType isEqualToString:NSFileTypeRegular]) {
+                if (allowRangeRequests) {
+                    response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange];
+                    [response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
+                } else {
+                    response = [GCDWebServerFileResponse responseWithFile:filePath];
+                }
+            }
+        }
+
+        complete(response);
+    };
+
+    [self addFileSystemHandler:processRequestBlock basePath:basePath authToken:authToken cacheAge:0];
+}
+
+- (void) addLocalFileSystemHandler:(NSString*)authToken
+{
+    NSString* basePath = [NSString stringWithFormat:@"/%@/", LOCAL_FILESYSTEM_PATH];
+    BOOL allowRangeRequests = YES;
+
+    GCDWebServerAsyncProcessBlock processRequestBlock = ^void (GCDWebServerRequest* request, GCDWebServerCompletionBlock complete) {
+
+        NSString* filePath = [request.path substringFromIndex:basePath.length];
+        NSString* fileType = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:NULL] fileType];
+        GCDWebServerResponse* response = nil;
+
+        if (fileType && [fileType isEqualToString:NSFileTypeRegular]) {
+            if (allowRangeRequests) {
+                response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange];
+                [response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"];
+            } else {
+                response = [GCDWebServerFileResponse responseWithFile:filePath];
+            }
+        }
+
+        complete(response);
+    };
+
+    [self addFileSystemHandler:processRequestBlock basePath:basePath authToken:authToken cacheAge:0];
+}
+
+- (void) addAssetLibraryFileSystemHandler:(NSString*)authToken
+{
+    NSString* basePath = [NSString stringWithFormat:@"/%@/", ASSETS_LIBRARY_PATH];
+
+    GCDWebServerAsyncProcessBlock processRequestBlock = ^void (GCDWebServerRequest* request, GCDWebServerCompletionBlock complete) {
+
+        NSURL* assetUrl = [NSURL URLWithString:[NSString stringWithFormat:@"assets-library:/%@", [request.path substringFromIndex:basePath.length]]];
+
+        ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
+        [assetsLibrary assetForURL:assetUrl
+                       resultBlock:^(ALAsset* asset) {
+                           if (asset) {
+                               // We have the asset!  Get the data and send it off.
+                               ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
+                               Byte* buffer = (Byte*)malloc([assetRepresentation size]);
+                               NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:[assetRepresentation size] error:nil];
+                               NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
+                               NSString* MIMEType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)[assetRepresentation UTI], kUTTagClassMIMEType);
+
+                               complete([GCDWebServerDataResponse responseWithData:data contentType:MIMEType]);
+                           } else {
+                               complete(nil);
+                           }
+                       }
+                      failureBlock:^(NSError* error) {
+                          NSLog(@"Error: %@", error);
+                          complete(nil);
+                      }
+         ];
+    };
+
+    [self addFileSystemHandler:processRequestBlock basePath:basePath authToken:authToken cacheAge:0];
+}
+
+- (void) addErrorSystemHandler:(NSString*)authToken
+{
+    NSString* basePath = [NSString stringWithFormat:@"/%@/", ERROR_PATH];
+
+    GCDWebServerAsyncProcessBlock processRequestBlock = ^void (GCDWebServerRequest* request, GCDWebServerCompletionBlock complete) {
+
+        NSString* errorString = [request.path substringFromIndex:basePath.length]; // error string is from the url path
+        NSString* html = [NSString stringWithFormat:@"<h1 style='margin-top:40px; font-size:6vw'>ERROR</h1><h2 style='font-size:3vw'>%@</h2>", errorString];
+        GCDWebServerResponse* response = [GCDWebServerDataResponse responseWithHTML:html];
+        complete(response);
+    };
+
+    [self addFileSystemHandler:processRequestBlock basePath:basePath authToken:authToken cacheAge:0];
+}
+
+
+@end

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/src/ios/GCDWebServer/.gitignore
----------------------------------------------------------------------
diff --git a/src/ios/GCDWebServer/.gitignore b/src/ios/GCDWebServer/.gitignore
new file mode 100644
index 0000000..d7d4abb
--- /dev/null
+++ b/src/ios/GCDWebServer/.gitignore
@@ -0,0 +1,6 @@
+.DS_Store
+xcuserdata
+project.xcworkspace
+
+Tests/Payload
+Carthage/Build

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/src/ios/GCDWebServer/.travis.yml
----------------------------------------------------------------------
diff --git a/src/ios/GCDWebServer/.travis.yml b/src/ios/GCDWebServer/.travis.yml
new file mode 100644
index 0000000..05cfcb6
--- /dev/null
+++ b/src/ios/GCDWebServer/.travis.yml
@@ -0,0 +1,3 @@
+language: objective-c
+script: ./Run-Tests.sh
+osx_image: xcode7.1

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/src/ios/GCDWebServer/Frameworks/GCDWebServers.h
----------------------------------------------------------------------
diff --git a/src/ios/GCDWebServer/Frameworks/GCDWebServers.h b/src/ios/GCDWebServer/Frameworks/GCDWebServers.h
new file mode 100644
index 0000000..60f42da
--- /dev/null
+++ b/src/ios/GCDWebServer/Frameworks/GCDWebServers.h
@@ -0,0 +1,52 @@
+/*
+ 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.
+ */
+
+// GCDWebServer Core
+#import <GCDWebServers/GCDWebServer.h>
+#import <GCDWebServers/GCDWebServerConnection.h>
+#import <GCDWebServers/GCDWebServerFunctions.h>
+#import <GCDWebServers/GCDWebServerHTTPStatusCodes.h>
+#import <GCDWebServers/GCDWebServerResponse.h>
+#import <GCDWebServers/GCDWebServerRequest.h>
+
+// GCDWebServer Requests
+#import <GCDWebServers/GCDWebServerDataRequest.h>
+#import <GCDWebServers/GCDWebServerFileRequest.h>
+#import <GCDWebServers/GCDWebServerMultiPartFormRequest.h>
+#import <GCDWebServers/GCDWebServerURLEncodedFormRequest.h>
+
+// GCDWebServer Responses
+#import <GCDWebServers/GCDWebServerDataResponse.h>
+#import <GCDWebServers/GCDWebServerErrorResponse.h>
+#import <GCDWebServers/GCDWebServerFileResponse.h>
+#import <GCDWebServers/GCDWebServerStreamedResponse.h>
+
+// GCDWebUploader
+#import <GCDWebServers/GCDWebUploader.h>
+
+// GCDWebDAVServer
+#import <GCDWebServers/GCDWebDAVServer.h>

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/src/ios/GCDWebServer/Frameworks/Info.plist
----------------------------------------------------------------------
diff --git a/src/ios/GCDWebServer/Frameworks/Info.plist b/src/ios/GCDWebServer/Frameworks/Info.plist
new file mode 100644
index 0000000..537b5cb
--- /dev/null
+++ b/src/ios/GCDWebServer/Frameworks/Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleVersion</key>
+	<string>${BUNDLE_VERSION_STRING}</string>
+	<key>CFBundleShortVersionString</key>
+	<string>${BUNDLE_VERSION_STRING}</string>
+</dict>
+</plist>

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/src/ios/GCDWebServer/Frameworks/Tests.m
----------------------------------------------------------------------
diff --git a/src/ios/GCDWebServer/Frameworks/Tests.m b/src/ios/GCDWebServer/Frameworks/Tests.m
new file mode 100644
index 0000000..b1d69e7
--- /dev/null
+++ b/src/ios/GCDWebServer/Frameworks/Tests.m
@@ -0,0 +1,24 @@
+#import <GCDWebServers/GCDWebServers.h>
+#import <XCTest/XCTest.h>
+
+@interface Tests : XCTestCase
+@end
+
+@implementation Tests
+
+- (void)testWebServer {
+  GCDWebServer* server = [[GCDWebServer alloc] init];
+  XCTAssertNotNil(server);
+}
+
+- (void)testDAVServer {
+  GCDWebDAVServer* server = [[GCDWebDAVServer alloc] init];
+  XCTAssertNotNil(server);
+}
+
+- (void)testWebUploader {
+  GCDWebUploader* server = [[GCDWebUploader alloc] init];
+  XCTAssertNotNil(server);
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.h
----------------------------------------------------------------------
diff --git a/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.h b/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.h
new file mode 100644
index 0000000..84914db
--- /dev/null
+++ b/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.h
@@ -0,0 +1,156 @@
+/*
+ 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 GCDWebDAVServer;
+
+/**
+ *  Delegate methods for GCDWebDAVServer.
+ *
+ *  @warning These methods are always called on the main thread in a serialized way.
+ */
+@protocol GCDWebDAVServerDelegate <GCDWebServerDelegate>
+@optional
+
+/**
+ *  This method is called whenever a file has been downloaded.
+ */
+- (void)davServer:(GCDWebDAVServer*)server didDownloadFileAtPath:(NSString*)path;
+
+/**
+ *  This method is called whenever a file has been uploaded.
+ */
+- (void)davServer:(GCDWebDAVServer*)server didUploadFileAtPath:(NSString*)path;
+
+/**
+ *  This method is called whenever a file or directory has been moved.
+ */
+- (void)davServer:(GCDWebDAVServer*)server didMoveItemFromPath:(NSString*)fromPath toPath:(NSString*)toPath;
+
+/**
+ *  This method is called whenever a file or directory has been copied.
+ */
+- (void)davServer:(GCDWebDAVServer*)server didCopyItemFromPath:(NSString*)fromPath toPath:(NSString*)toPath;
+
+/**
+ *  This method is called whenever a file or directory has been deleted.
+ */
+- (void)davServer:(GCDWebDAVServer*)server didDeleteItemAtPath:(NSString*)path;
+
+/**
+ *  This method is called whenever a directory has been created.
+ */
+- (void)davServer:(GCDWebDAVServer*)server didCreateDirectoryAtPath:(NSString*)path;
+
+@end
+
+/**
+ *  The GCDWebDAVServer subclass of GCDWebServer implements a class 1 compliant
+ *  WebDAV server. It is also partially class 2 compliant but only when the
+ *  client is the OS X WebDAV implementation (so it can work with the OS X Finder).
+ *
+ *  See the README.md file for more information about the features of GCDWebDAVServer.
+ */
+@interface GCDWebDAVServer : GCDWebServer
+
+/**
+ *  Returns the upload directory as specified when the server was initialized.
+ */
+@property(nonatomic, readonly) NSString* uploadDirectory;
+
+/**
+ *  Sets the delegate for the server.
+ */
+@property(nonatomic, assign) id<GCDWebDAVServerDelegate> 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;
+
+/**
+ *  This method is the designated initializer for the class.
+ */
+- (instancetype)initWithUploadDirectory:(NSString*)path;
+
+@end
+
+/**
+ *  Hooks to customize the behavior of GCDWebDAVServer.
+ *
+ *  @warning These methods can be called on any GCD thread.
+ */
+@interface GCDWebDAVServer (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 copied.
+ *
+ *  The default implementation returns YES.
+ */
+- (BOOL)shouldCopyItemFromPath:(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/dfe33643/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.m
----------------------------------------------------------------------
diff --git a/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.m b/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.m
new file mode 100644
index 0000000..33025d4
--- /dev/null
+++ b/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.m
@@ -0,0 +1,701 @@
+/*
+ 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 GCDWebDAVServer requires ARC
+#endif
+
+// WebDAV specifications: http://webdav.org/specs/rfc4918.html
+
+// Requires "HEADER_SEARCH_PATHS = $(SDKROOT)/usr/include/libxml2" in Xcode build settings
+#import <libxml/parser.h>
+
+#import "GCDWebDAVServer.h"
+
+#import "GCDWebServerFunctions.h"
+
+#import "GCDWebServerDataRequest.h"
+#import "GCDWebServerFileRequest.h"
+
+#import "GCDWebServerDataResponse.h"
+#import "GCDWebServerErrorResponse.h"
+#import "GCDWebServerFileResponse.h"
+
+#define kXMLParseOptions (XML_PARSE_NONET | XML_PARSE_RECOVER | XML_PARSE_NOBLANKS | XML_PARSE_COMPACT | XML_PARSE_NOWARNING | XML_PARSE_NOERROR)
+
+typedef NS_ENUM(NSInteger, DAVProperties) {
+  kDAVProperty_ResourceType = (1 << 0),
+  kDAVProperty_CreationDate = (1 << 1),
+  kDAVProperty_LastModified = (1 << 2),
+  kDAVProperty_ContentLength = (1 << 3),
+  kDAVAllProperties = kDAVProperty_ResourceType | kDAVProperty_CreationDate | kDAVProperty_LastModified | kDAVProperty_ContentLength
+};
+
+@interface GCDWebDAVServer () {
+@private
+  NSString* _uploadDirectory;
+  NSArray* _allowedExtensions;
+  BOOL _allowHidden;
+}
+@end
+
+@implementation GCDWebDAVServer (Methods)
+
+// Must match implementation in GCDWebUploader
+- (BOOL)_checkSandboxedPath:(NSString*)path {
+  return [[path stringByStandardizingPath] hasPrefix:_uploadDirectory];
+}
+
+- (BOOL)_checkFileExtension:(NSString*)fileName {
+  if (_allowedExtensions && ![_allowedExtensions containsObject:[[fileName pathExtension] lowercaseString]]) {
+    return NO;
+  }
+  return YES;
+}
+
+static inline BOOL _IsMacFinder(GCDWebServerRequest* request) {
+  NSString* userAgentHeader = [request.headers objectForKey:@"User-Agent"];
+  return ([userAgentHeader hasPrefix:@"WebDAVFS/"] || [userAgentHeader hasPrefix:@"WebDAVLib/"]);  // OS X WebDAV client
+}
+
+- (GCDWebServerResponse*)performOPTIONS:(GCDWebServerRequest*)request {
+  GCDWebServerResponse* response = [GCDWebServerResponse response];
+  if (_IsMacFinder(request)) {
+    [response setValue:@"1, 2" forAdditionalHeader:@"DAV"];  // Classes 1 and 2
+  } else {
+    [response setValue:@"1" forAdditionalHeader:@"DAV"];  // Class 1
+  }
+  return response;
+}
+
+- (GCDWebServerResponse*)performGET:(GCDWebServerRequest*)request {
+  NSString* relativePath = request.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:@"Downlading item name \"%@\" is not allowed", itemName];
+  }
+  
+  // Because HEAD requests are mapped to GET ones, we need to handle directories but it's OK to return nothing per http://webdav.org/specs/rfc4918.html#rfc.section.9.4
+  if (isDirectory) {
+    return [GCDWebServerResponse response];
+  }
+  
+  if ([self.delegate respondsToSelector:@selector(davServer:didDownloadFileAtPath:)]) {
+    dispatch_async(dispatch_get_main_queue(), ^{
+      [self.delegate davServer:self didDownloadFileAtPath:absolutePath];
+    });
+  }
+    
+  if ([request hasByteRange]) {
+    return [GCDWebServerFileResponse responseWithFile:absolutePath byteRange:request.byteRange];
+  }
+    
+  return [GCDWebServerFileResponse responseWithFile:absolutePath];
+}
+
+- (GCDWebServerResponse*)performPUT:(GCDWebServerFileRequest*)request {
+  if ([request hasByteRange]) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Range uploads not supported"];
+  }
+  
+  NSString* relativePath = request.path;
+  NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
+  if (![self _checkSandboxedPath:absolutePath]) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
+  }
+  BOOL isDirectory;
+  if (![[NSFileManager defaultManager] fileExistsAtPath:[absolutePath stringByDeletingLastPathComponent] isDirectory:&isDirectory] || !isDirectory) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Conflict message:@"Missing intermediate collection(s) for \"%@\"", relativePath];
+  }
+  
+  BOOL existing = [[NSFileManager defaultManager] fileExistsAtPath:absolutePath isDirectory:&isDirectory];
+  if (existing && isDirectory) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_MethodNotAllowed message:@"PUT not allowed on existing collection \"%@\"", relativePath];
+  }
+  
+  NSString* fileName = [absolutePath lastPathComponent];
+  if (([fileName hasPrefix:@"."] && !_allowHidden) || ![self _checkFileExtension:fileName]) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Uploading file name \"%@\" is not allowed", fileName];
+  }
+  
+  if (![self shouldUploadFileAtPath:absolutePath withTemporaryFile:request.temporaryPath]) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Uploading file to \"%@\" is not permitted", relativePath];
+  }
+  
+  [[NSFileManager defaultManager] removeItemAtPath:absolutePath error:NULL];
+  NSError* error = nil;
+  if (![[NSFileManager defaultManager] moveItemAtPath:request.temporaryPath toPath:absolutePath error:&error]) {
+    return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed moving uploaded file to \"%@\"", relativePath];
+  }
+  
+  if ([self.delegate respondsToSelector:@selector(davServer:didUploadFileAtPath:)]) {
+    dispatch_async(dispatch_get_main_queue(), ^{
+      [self.delegate davServer:self didUploadFileAtPath:absolutePath];
+    });
+  }
+  return [GCDWebServerResponse responseWithStatusCode:(existing ? kGCDWebServerHTTPStatusCode_NoContent : kGCDWebServerHTTPStatusCode_Created)];
+}
+
+- (GCDWebServerResponse*)performDELETE:(GCDWebServerRequest*)request {
+  NSString* depthHeader = [request.headers objectForKey:@"Depth"];
+  if (depthHeader && ![depthHeader isEqualToString:@"infinity"]) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Unsupported 'Depth' header: %@", depthHeader];
+  }
+  
+  NSString* relativePath = request.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(davServer:didDeleteItemAtPath:)]) {
+    dispatch_async(dispatch_get_main_queue(), ^{
+      [self.delegate davServer:self didDeleteItemAtPath:absolutePath];
+    });
+  }
+  return [GCDWebServerResponse responseWithStatusCode:kGCDWebServerHTTPStatusCode_NoContent];
+}
+
+- (GCDWebServerResponse*)performMKCOL:(GCDWebServerDataRequest*)request {
+  if ([request hasBody] && (request.contentLength > 0)) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_UnsupportedMediaType message:@"Unexpected request body for MKCOL method"];
+  }
+  
+  NSString* relativePath = request.path;
+  NSString* absolutePath = [_uploadDirectory stringByAppendingPathComponent:relativePath];
+  if (![self _checkSandboxedPath:absolutePath]) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", relativePath];
+  }
+  BOOL isDirectory;
+  if (![[NSFileManager defaultManager] fileExistsAtPath:[absolutePath stringByDeletingLastPathComponent] isDirectory:&isDirectory] || !isDirectory) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Conflict message:@"Missing intermediate collection(s) for \"%@\"", 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];
+  }
+#ifdef __GCDWEBSERVER_ENABLE_TESTING__
+  NSString* creationDateHeader = [request.headers objectForKey:@"X-GCDWebServer-CreationDate"];
+  if (creationDateHeader) {
+    NSDate* date = GCDWebServerParseISO8601(creationDateHeader);
+    if (!date || ![[NSFileManager defaultManager] setAttributes:@{NSFileCreationDate: date} ofItemAtPath:absolutePath error:&error]) {
+      return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed setting creation date for directory \"%@\"", relativePath];
+    }
+  }
+#endif
+  
+  if ([self.delegate respondsToSelector:@selector(davServer:didCreateDirectoryAtPath:)]) {
+    dispatch_async(dispatch_get_main_queue(), ^{
+      [self.delegate davServer:self didCreateDirectoryAtPath:absolutePath];
+    });
+  }
+  return [GCDWebServerResponse responseWithStatusCode:kGCDWebServerHTTPStatusCode_Created];
+}
+
+- (GCDWebServerResponse*)performCOPY:(GCDWebServerRequest*)request isMove:(BOOL)isMove {
+  if (!isMove) {
+    NSString* depthHeader = [request.headers objectForKey:@"Depth"];  // TODO: Support "Depth: 0"
+    if (depthHeader && ![depthHeader isEqualToString:@"infinity"]) {
+      return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Unsupported 'Depth' header: %@", depthHeader];
+    }
+  }
+  
+  NSString* srcRelativePath = request.path;
+  NSString* srcAbsolutePath = [_uploadDirectory stringByAppendingPathComponent:srcRelativePath];
+  if (![self _checkSandboxedPath:srcAbsolutePath]) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", srcRelativePath];
+  }
+  
+  NSString* dstRelativePath = [request.headers objectForKey:@"Destination"];
+  NSRange range = [dstRelativePath rangeOfString:[request.headers objectForKey:@"Host"]];
+  if ((dstRelativePath == nil) || (range.location == NSNotFound)) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Malformed 'Destination' header: %@", dstRelativePath];
+  }
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+  dstRelativePath = [[dstRelativePath substringFromIndex:(range.location + range.length)] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+#pragma clang diagnostic pop
+  NSString* dstAbsolutePath = [_uploadDirectory stringByAppendingPathComponent:dstRelativePath];
+  if (![self _checkSandboxedPath:dstAbsolutePath]) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_NotFound message:@"\"%@\" does not exist", srcRelativePath];
+  }
+  
+  BOOL isDirectory;
+  if (![[NSFileManager defaultManager] fileExistsAtPath:[dstAbsolutePath stringByDeletingLastPathComponent] isDirectory:&isDirectory] || !isDirectory) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Conflict message:@"Invalid destination \"%@\"", dstRelativePath];
+  }
+  
+  NSString* itemName = [dstAbsolutePath lastPathComponent];
+  if ((!_allowHidden && [itemName hasPrefix:@"."]) || (!isDirectory && ![self _checkFileExtension:itemName])) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"%@ to item name \"%@\" is not allowed", isMove ? @"Moving" : @"Copying", itemName];
+  }
+  
+  NSString* overwriteHeader = [request.headers objectForKey:@"Overwrite"];
+  BOOL existing = [[NSFileManager defaultManager] fileExistsAtPath:dstAbsolutePath];
+  if (existing && ((isMove && ![overwriteHeader isEqualToString:@"T"]) || (!isMove && [overwriteHeader isEqualToString:@"F"]))) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_PreconditionFailed message:@"Destination \"%@\" already exists", dstRelativePath];
+  }
+  
+  if (isMove) {
+    if (![self shouldMoveItemFromPath:srcAbsolutePath toPath:dstAbsolutePath]) {
+      return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Moving \"%@\" to \"%@\" is not permitted", srcRelativePath, dstRelativePath];
+    }
+  } else {
+    if (![self shouldCopyItemFromPath:srcAbsolutePath toPath:dstAbsolutePath]) {
+      return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Copying \"%@\" to \"%@\" is not permitted", srcRelativePath, dstRelativePath];
+    }
+  }
+  
+  NSError* error = nil;
+  if (isMove) {
+    [[NSFileManager defaultManager] removeItemAtPath:dstAbsolutePath error:NULL];
+    if (![[NSFileManager defaultManager] moveItemAtPath:srcAbsolutePath toPath:dstAbsolutePath error:&error]) {
+      return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden underlyingError:error message:@"Failed copying \"%@\" to \"%@\"", srcRelativePath, dstRelativePath];
+    }
+  } else {
+    if (![[NSFileManager defaultManager] copyItemAtPath:srcAbsolutePath toPath:dstAbsolutePath error:&error]) {
+      return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden underlyingError:error message:@"Failed copying \"%@\" to \"%@\"", srcRelativePath, dstRelativePath];
+    }
+  }
+  
+  if (isMove) {
+    if ([self.delegate respondsToSelector:@selector(davServer:didMoveItemFromPath:toPath:)]) {
+      dispatch_async(dispatch_get_main_queue(), ^{
+        [self.delegate davServer:self didMoveItemFromPath:srcAbsolutePath toPath:dstAbsolutePath];
+      });
+    }
+  } else {
+    if ([self.delegate respondsToSelector:@selector(davServer:didCopyItemFromPath:toPath:)]) {
+      dispatch_async(dispatch_get_main_queue(), ^{
+        [self.delegate davServer:self didCopyItemFromPath:srcAbsolutePath toPath:dstAbsolutePath];
+      });
+    }
+  }
+  
+  return [GCDWebServerResponse responseWithStatusCode:(existing ? kGCDWebServerHTTPStatusCode_NoContent : kGCDWebServerHTTPStatusCode_Created)];
+}
+
+static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name) {
+  while (child) {
+    if ((child->type == XML_ELEMENT_NODE) && !xmlStrcmp(child->name, name)) {
+      return child;
+    }
+    child = child->next;
+  }
+  return NULL;
+}
+
+- (void)_addPropertyResponseForItem:(NSString*)itemPath resource:(NSString*)resourcePath properties:(DAVProperties)properties xmlString:(NSMutableString*)xmlString {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+  CFStringRef escapedPath = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)resourcePath, NULL, CFSTR("<&>?+"), kCFStringEncodingUTF8);
+#pragma clang diagnostic pop
+  if (escapedPath) {
+    NSDictionary* attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:itemPath error:NULL];
+    NSString* type = [attributes objectForKey:NSFileType];
+    BOOL isFile = [type isEqualToString:NSFileTypeRegular];
+    BOOL isDirectory = [type isEqualToString:NSFileTypeDirectory];
+    if ((isFile && [self _checkFileExtension:itemPath]) || isDirectory) {
+      [xmlString appendString:@"<D:response>"];
+      [xmlString appendFormat:@"<D:href>%@</D:href>", escapedPath];
+      [xmlString appendString:@"<D:propstat>"];
+      [xmlString appendString:@"<D:prop>"];
+      
+      if (properties & kDAVProperty_ResourceType) {
+        if (isDirectory) {
+          [xmlString appendString:@"<D:resourcetype><D:collection/></D:resourcetype>"];
+        } else {
+          [xmlString appendString:@"<D:resourcetype/>"];
+        }
+      }
+      
+      if ((properties & kDAVProperty_CreationDate) && [attributes objectForKey:NSFileCreationDate]) {
+        [xmlString appendFormat:@"<D:creationdate>%@</D:creationdate>", GCDWebServerFormatISO8601([attributes fileCreationDate])];
+      }
+      
+      if ((properties & kDAVProperty_LastModified) && isFile && [attributes objectForKey:NSFileModificationDate]) {  // Last modification date is not useful for directories as it changes implicitely and 'Last-Modified' header is not provided for directories anyway
+        [xmlString appendFormat:@"<D:getlastmodified>%@</D:getlastmodified>", GCDWebServerFormatRFC822([attributes fileModificationDate])];
+      }
+      
+      if ((properties & kDAVProperty_ContentLength) && !isDirectory && [attributes objectForKey:NSFileSize]) {
+        [xmlString appendFormat:@"<D:getcontentlength>%llu</D:getcontentlength>", [attributes fileSize]];
+      }
+      
+      [xmlString appendString:@"</D:prop>"];
+      [xmlString appendString:@"<D:status>HTTP/1.1 200 OK</D:status>"];
+      [xmlString appendString:@"</D:propstat>"];
+      [xmlString appendString:@"</D:response>\n"];
+    }
+    CFRelease(escapedPath);
+  } else {
+    [self logError:@"Failed escaping path: %@", itemPath];
+  }
+}
+
+- (GCDWebServerResponse*)performPROPFIND:(GCDWebServerDataRequest*)request {
+  NSInteger depth;
+  NSString* depthHeader = [request.headers objectForKey:@"Depth"];
+  if ([depthHeader isEqualToString:@"0"]) {
+    depth = 0;
+  } else if ([depthHeader isEqualToString:@"1"]) {
+    depth = 1;
+  } else {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Unsupported 'Depth' header: %@", depthHeader];  // TODO: Return 403 / propfind-finite-depth for "infinity" depth
+  }
+  
+  DAVProperties properties = 0;
+  if (request.data.length) {
+    BOOL success = YES;
+    xmlDocPtr document = xmlReadMemory(request.data.bytes, (int)request.data.length, NULL, NULL, kXMLParseOptions);
+    if (document) {
+      xmlNodePtr rootNode = _XMLChildWithName(document->children, (const xmlChar*)"propfind");
+      xmlNodePtr allNode = rootNode ? _XMLChildWithName(rootNode->children, (const xmlChar*)"allprop") : NULL;
+      xmlNodePtr propNode = rootNode ? _XMLChildWithName(rootNode->children, (const xmlChar*)"prop") : NULL;
+      if (allNode) {
+        properties = kDAVAllProperties;
+      } else if (propNode) {
+        xmlNodePtr node = propNode->children;
+        while (node) {
+          if (!xmlStrcmp(node->name, (const xmlChar*)"resourcetype")) {
+            properties |= kDAVProperty_ResourceType;
+          } else if (!xmlStrcmp(node->name, (const xmlChar*)"creationdate")) {
+            properties |= kDAVProperty_CreationDate;
+          } else if (!xmlStrcmp(node->name, (const xmlChar*)"getlastmodified")) {
+            properties |= kDAVProperty_LastModified;
+          } else if (!xmlStrcmp(node->name, (const xmlChar*)"getcontentlength")) {
+            properties |= kDAVProperty_ContentLength;
+          } else {
+            [self logWarning:@"Unknown DAV property requested \"%s\"", node->name];
+          }
+          node = node->next;
+        }
+      } else {
+        success = NO;
+      }
+      xmlFreeDoc(document);
+    } else {
+      success = NO;
+    }
+    if (!success) {
+      NSString* string = [[NSString alloc] initWithData:request.data encoding:NSUTF8StringEncoding];
+      return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Invalid DAV properties:\n%@", string];
+    }
+  } else {
+    properties = kDAVAllProperties;
+  }
+  
+  NSString* relativePath = request.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:@"Retrieving properties for item name \"%@\" is not allowed", itemName];
+  }
+  
+  NSArray* items = nil;
+  if (isDirectory) {
+    NSError* error = nil;
+    items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:absolutePath error:&error];
+    if (items == nil) {
+      return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed listing directory \"%@\"", relativePath];
+    }
+  }
+  
+  NSMutableString* xmlString = [NSMutableString stringWithString:@"<?xml version=\"1.0\" encoding=\"utf-8\" ?>"];
+  [xmlString appendString:@"<D:multistatus xmlns:D=\"DAV:\">\n"];
+  if (![relativePath hasPrefix:@"/"]) {
+    relativePath = [@"/" stringByAppendingString:relativePath];
+  }
+  [self _addPropertyResponseForItem:absolutePath resource:relativePath properties:properties xmlString:xmlString];
+  if (depth == 1) {
+    if (![relativePath hasSuffix:@"/"]) {
+      relativePath = [relativePath stringByAppendingString:@"/"];
+    }
+    for (NSString* item in items) {
+      if (_allowHidden || ![item hasPrefix:@"."]) {
+        [self _addPropertyResponseForItem:[absolutePath stringByAppendingPathComponent:item] resource:[relativePath stringByAppendingString:item] properties:properties xmlString:xmlString];
+      }
+    }
+  }
+  [xmlString appendString:@"</D:multistatus>"];
+  
+  GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithData:[xmlString dataUsingEncoding:NSUTF8StringEncoding]
+                                                                      contentType:@"application/xml; charset=\"utf-8\""];
+  response.statusCode = kGCDWebServerHTTPStatusCode_MultiStatus;
+  return response;
+}
+
+- (GCDWebServerResponse*)performLOCK:(GCDWebServerDataRequest*)request {
+  if (!_IsMacFinder(request)) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_MethodNotAllowed message:@"LOCK method only allowed for Mac Finder"];
+  }
+  
+  NSString* relativePath = request.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* depthHeader = [request.headers objectForKey:@"Depth"];
+  NSString* timeoutHeader = [request.headers objectForKey:@"Timeout"];
+  NSString* scope = nil;
+  NSString* type = nil;
+  NSString* owner = nil;
+  NSString* token = nil;
+  BOOL success = YES;
+  xmlDocPtr document = xmlReadMemory(request.data.bytes, (int)request.data.length, NULL, NULL, kXMLParseOptions);
+  if (document) {
+    xmlNodePtr node = _XMLChildWithName(document->children, (const xmlChar*)"lockinfo");
+    if (node) {
+      xmlNodePtr scopeNode = _XMLChildWithName(node->children, (const xmlChar*)"lockscope");
+      if (scopeNode && scopeNode->children && scopeNode->children->name) {
+        scope = [NSString stringWithUTF8String:(const char*)scopeNode->children->name];
+      }
+      xmlNodePtr typeNode = _XMLChildWithName(node->children, (const xmlChar*)"locktype");
+      if (typeNode && typeNode->children && typeNode->children->name) {
+        type = [NSString stringWithUTF8String:(const char*)typeNode->children->name];
+      }
+      xmlNodePtr ownerNode = _XMLChildWithName(node->children, (const xmlChar*)"owner");
+      if (ownerNode) {
+        ownerNode = _XMLChildWithName(ownerNode->children, (const xmlChar*)"href");
+        if (ownerNode && ownerNode->children && ownerNode->children->content) {
+          owner = [NSString stringWithUTF8String:(const char*)ownerNode->children->content];
+        }
+      }
+    } else {
+      success = NO;
+    }
+    xmlFreeDoc(document);
+  } else {
+    success = NO;
+  }
+  if (!success) {
+    NSString* string = [[NSString alloc] initWithData:request.data encoding:NSUTF8StringEncoding];
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Invalid DAV properties:\n%@", string];
+  }
+  
+  if (![scope isEqualToString:@"exclusive"] || ![type isEqualToString:@"write"] || ![depthHeader isEqualToString:@"0"]) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Locking request \"%@/%@/%@\" for \"%@\" is not allowed", scope, type, depthHeader, relativePath];
+  }
+  
+  NSString* itemName = [absolutePath lastPathComponent];
+  if ((!_allowHidden && [itemName hasPrefix:@"."]) || (!isDirectory && ![self _checkFileExtension:itemName])) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Locking item name \"%@\" is not allowed", itemName];
+  }
+  
+#ifdef __GCDWEBSERVER_ENABLE_TESTING__
+  NSString* lockTokenHeader = [request.headers objectForKey:@"X-GCDWebServer-LockToken"];
+  if (lockTokenHeader) {
+    token = lockTokenHeader;
+  }
+#endif
+  if (!token) {
+    CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
+    CFStringRef string = CFUUIDCreateString(kCFAllocatorDefault, uuid);
+    token = [NSString stringWithFormat:@"urn:uuid:%@", (__bridge NSString*)string];
+    CFRelease(string);
+    CFRelease(uuid);
+  }
+  
+  NSMutableString* xmlString = [NSMutableString stringWithString:@"<?xml version=\"1.0\" encoding=\"utf-8\" ?>"];
+  [xmlString appendString:@"<D:prop xmlns:D=\"DAV:\">\n"];
+  [xmlString appendString:@"<D:lockdiscovery>\n<D:activelock>\n"];
+  [xmlString appendFormat:@"<D:locktype><D:%@/></D:locktype>\n", type];
+  [xmlString appendFormat:@"<D:lockscope><D:%@/></D:lockscope>\n", scope];
+  [xmlString appendFormat:@"<D:depth>%@</D:depth>\n", depthHeader];
+  if (owner) {
+    [xmlString appendFormat:@"<D:owner><D:href>%@</D:href></D:owner>\n", owner];
+  }
+  if (timeoutHeader) {
+    [xmlString appendFormat:@"<D:timeout>%@</D:timeout>\n", timeoutHeader];
+  }
+  [xmlString appendFormat:@"<D:locktoken><D:href>%@</D:href></D:locktoken>\n", token];
+  NSString* lockroot = [@"http://" stringByAppendingString:[[request.headers objectForKey:@"Host"] stringByAppendingString:[@"/" stringByAppendingString:relativePath]]];
+  [xmlString appendFormat:@"<D:lockroot><D:href>%@</D:href></D:lockroot>\n", lockroot];
+  [xmlString appendString:@"</D:activelock>\n</D:lockdiscovery>\n"];
+  [xmlString appendString:@"</D:prop>"];
+  
+  [self logVerbose:@"WebDAV pretending to lock \"%@\"", relativePath];
+  GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithData:[xmlString dataUsingEncoding:NSUTF8StringEncoding]
+                                                                      contentType:@"application/xml; charset=\"utf-8\""];
+  return response;
+}
+
+- (GCDWebServerResponse*)performUNLOCK:(GCDWebServerRequest*)request {
+  if (!_IsMacFinder(request)) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_MethodNotAllowed message:@"UNLOCK method only allowed for Mac Finder"];
+  }
+  
+  NSString* relativePath = request.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* tokenHeader = [request.headers objectForKey:@"Lock-Token"];
+  if (!tokenHeader.length) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_BadRequest message:@"Missing 'Lock-Token' header"];
+  }
+  
+  NSString* itemName = [absolutePath lastPathComponent];
+  if ((!_allowHidden && [itemName hasPrefix:@"."]) || (!isDirectory && ![self _checkFileExtension:itemName])) {
+    return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_Forbidden message:@"Unlocking item name \"%@\" is not allowed", itemName];
+  }
+  
+  [self logVerbose:@"WebDAV pretending to unlock \"%@\"", relativePath];
+  return [GCDWebServerResponse responseWithStatusCode:kGCDWebServerHTTPStatusCode_NoContent];
+}
+
+@end
+
+@implementation GCDWebDAVServer
+
+@synthesize uploadDirectory=_uploadDirectory, allowedFileExtensions=_allowedExtensions, allowHiddenItems=_allowHidden;
+
+@dynamic delegate;
+
+- (instancetype)initWithUploadDirectory:(NSString*)path {
+  if ((self = [super init])) {
+    _uploadDirectory = [[path stringByStandardizingPath] copy];
+    GCDWebDAVServer* __unsafe_unretained server = self;
+    
+    // 9.1 PROPFIND method
+    [self addDefaultHandlerForMethod:@"PROPFIND" requestClass:[GCDWebServerDataRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
+      return [server performPROPFIND:(GCDWebServerDataRequest*)request];
+    }];
+    
+    // 9.3 MKCOL Method
+    [self addDefaultHandlerForMethod:@"MKCOL" requestClass:[GCDWebServerDataRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
+      return [server performMKCOL:(GCDWebServerDataRequest*)request];
+    }];
+    
+    // 9.4 GET & HEAD methods
+    [self addDefaultHandlerForMethod:@"GET" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
+      return [server performGET:request];
+    }];
+    
+    // 9.6 DELETE method
+    [self addDefaultHandlerForMethod:@"DELETE" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
+      return [server performDELETE:request];
+    }];
+    
+    // 9.7 PUT method
+    [self addDefaultHandlerForMethod:@"PUT" requestClass:[GCDWebServerFileRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
+      return [server performPUT:(GCDWebServerFileRequest*)request];
+    }];
+    
+    // 9.8 COPY method
+    [self addDefaultHandlerForMethod:@"COPY" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
+      return [server performCOPY:request isMove:NO];
+    }];
+    
+    // 9.9 MOVE method
+    [self addDefaultHandlerForMethod:@"MOVE" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
+      return [server performCOPY:request isMove:YES];
+    }];
+    
+    // 9.10 LOCK method
+    [self addDefaultHandlerForMethod:@"LOCK" requestClass:[GCDWebServerDataRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
+      return [server performLOCK:(GCDWebServerDataRequest*)request];
+    }];
+    
+    // 9.11 UNLOCK method
+    [self addDefaultHandlerForMethod:@"UNLOCK" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
+      return [server performUNLOCK:request];
+    }];
+    
+    // 10.1 OPTIONS method / DAV Header
+    [self addDefaultHandlerForMethod:@"OPTIONS" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
+      return [server performOPTIONS:request];
+    }];
+    
+  }
+  return self;
+}
+
+@end
+
+@implementation GCDWebDAVServer (Subclassing)
+
+- (BOOL)shouldUploadFileAtPath:(NSString*)path withTemporaryFile:(NSString*)tempPath {
+  return YES;
+}
+
+- (BOOL)shouldMoveItemFromPath:(NSString*)fromPath toPath:(NSString*)toPath {
+  return YES;
+}
+
+- (BOOL)shouldCopyItemFromPath:(NSString*)fromPath toPath:(NSString*)toPath {
+  return YES;
+}
+
+- (BOOL)shouldDeleteItemAtPath:(NSString*)path {
+  return YES;
+}
+
+- (BOOL)shouldCreateDirectoryAtPath:(NSString*)path {
+  return YES;
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/dfe33643/src/ios/GCDWebServer/GCDWebServer.podspec
----------------------------------------------------------------------
diff --git a/src/ios/GCDWebServer/GCDWebServer.podspec b/src/ios/GCDWebServer/GCDWebServer.podspec
new file mode 100644
index 0000000..901de93
--- /dev/null
+++ b/src/ios/GCDWebServer/GCDWebServer.podspec
@@ -0,0 +1,75 @@
+# http://guides.cocoapods.org/syntax/podspec.html
+# http://guides.cocoapods.org/making/getting-setup-with-trunk.html
+# $ sudo gem update cocoapods
+# (optional) $ pod trunk register {email} {name} --description={computer}
+# $ pod trunk --verbose push
+# DELETE THIS SECTION BEFORE PROCEEDING!
+
+Pod::Spec.new do |s|
+  s.name     = 'GCDWebServer'
+  s.version  = '3.3.3'
+  s.author   =  { 'Pierre-Olivier Latour' => 'info@pol-online.net' }
+  s.license  = { :type => 'BSD', :file => 'LICENSE' }
+  s.homepage = 'https://github.com/swisspol/GCDWebServer'
+  s.summary  = 'Lightweight GCD based HTTP server for OS X & iOS (includes web based uploader & WebDAV server)'
+  
+  s.source   = { :git => 'https://github.com/swisspol/GCDWebServer.git', :tag => s.version.to_s }
+  s.ios.deployment_target = '5.0'
+  s.tvos.deployment_target = '9.0'
+  s.osx.deployment_target = '10.7'
+  s.requires_arc = true
+  
+  s.default_subspec = 'Core'
+  
+  s.subspec 'Core' do |cs|
+    cs.source_files = 'GCDWebServer/**/*.{h,m}'
+    cs.private_header_files = "GCDWebServer/Core/GCDWebServerPrivate.h"
+    cs.requires_arc = true
+    cs.ios.library = 'z'
+    cs.ios.frameworks = 'MobileCoreServices', 'CFNetwork'
+    cs.tvos.library = 'z'
+    cs.tvos.frameworks = 'MobileCoreServices', 'CFNetwork'
+    cs.osx.library = 'z'
+    cs.osx.framework = 'SystemConfiguration'
+  end
+  
+  s.subspec "CocoaLumberjack" do |cs|
+    cs.dependency 'GCDWebServer/Core'
+    cs.dependency 'CocoaLumberjack', '~> 2'
+  end
+  
+  s.subspec 'WebDAV' do |cs|
+    cs.default_subspec = 'Core'
+
+    cs.subspec "Core" do |ccs|
+      ccs.dependency 'GCDWebServer/Core'
+      ccs.source_files = 'GCDWebDAVServer/*.{h,m}'
+      ccs.requires_arc = true
+      ccs.ios.library = 'xml2'
+      ccs.tvos.library = 'xml2'
+      ccs.osx.library = 'xml2'
+      ccs.compiler_flags = '-I$(SDKROOT)/usr/include/libxml2'
+    end
+
+    cs.subspec "CocoaLumberjack" do |cscl|
+      cscl.dependency 'GCDWebServer/WebDAV/Core'
+      cscl.dependency 'GCDWebServer/CocoaLumberjack'
+    end
+  end
+  
+  s.subspec 'WebUploader' do |cs|
+    cs.default_subspec = 'Core'
+
+    cs.subspec "Core" do |ccs|
+      ccs.dependency 'GCDWebServer/Core'
+      ccs.source_files = 'GCDWebUploader/*.{h,m}'
+      ccs.requires_arc = true
+      ccs.resource = "GCDWebUploader/GCDWebUploader.bundle"
+    end
+
+    cs.subspec "CocoaLumberjack" do |cscl|
+      cscl.dependency 'GCDWebServer/WebUploader/Core'
+      cscl.dependency 'GCDWebServer/CocoaLumberjack'
+    end
+  end 
+end


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


Mime
View raw message