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:42 UTC

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

Merge commit '394cfb12f80de35255a506c0dcbf4a21910e849a'


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugins/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugins/commit/36f1a43e
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugins/tree/36f1a43e
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugins/diff/36f1a43e

Branch: refs/heads/master
Commit: 36f1a43e29c3e49c9c2cab7af6fb3909ddfc74df
Parents: 9f15b12 394cfb1
Author: Andreas Kohn <an...@gmail.com>
Authored: Thu Mar 24 12:42:43 2016 +0100
Committer: Andreas Kohn <an...@gmail.com>
Committed: Thu Mar 24 12:42:43 2016 +0100

----------------------------------------------------------------------
 local-webserver/src/ios/GCDWebServer/.gitignore |    1 +
 .../src/ios/GCDWebServer/.travis.yml            |    1 +
 .../ios/GCDWebServer/Frameworks/GCDWebServers.h |   52 +
 .../src/ios/GCDWebServer/Frameworks/Info.plist  |   22 +
 .../src/ios/GCDWebServer/Frameworks/Tests.m     |   24 +
 .../GCDWebDAVServer/GCDWebDAVServer.h           |    2 +-
 .../GCDWebDAVServer/GCDWebDAVServer.m           |   15 +-
 .../src/ios/GCDWebServer/GCDWebServer.podspec   |   52 +-
 .../GCDWebServer.xcodeproj/project.pbxproj      | 1135 ++++++++++++++++--
 .../xcschemes/GCDWebServers (Mac).xcscheme      |   90 ++
 .../xcschemes/GCDWebServers (iOS).xcscheme      |   89 ++
 .../xcschemes/GCDWebServers (tvOS).xcscheme     |   89 ++
 .../GCDWebServer/Core/GCDWebServer.h            |   59 +-
 .../GCDWebServer/Core/GCDWebServer.m            |  161 ++-
 .../GCDWebServer/Core/GCDWebServerConnection.h  |    2 +-
 .../GCDWebServer/Core/GCDWebServerConnection.m  |   20 +-
 .../GCDWebServer/Core/GCDWebServerFunctions.h   |    2 +-
 .../GCDWebServer/Core/GCDWebServerFunctions.m   |   16 +-
 .../Core/GCDWebServerHTTPStatusCodes.h          |    2 +-
 .../GCDWebServer/Core/GCDWebServerPrivate.h     |   34 +-
 .../GCDWebServer/Core/GCDWebServerRequest.h     |   26 +-
 .../GCDWebServer/Core/GCDWebServerRequest.m     |   27 +-
 .../GCDWebServer/Core/GCDWebServerResponse.h    |    2 +-
 .../GCDWebServer/Core/GCDWebServerResponse.m    |   12 +-
 .../Requests/GCDWebServerDataRequest.h          |    2 +-
 .../Requests/GCDWebServerDataRequest.m          |    6 +-
 .../Requests/GCDWebServerFileRequest.h          |    2 +-
 .../Requests/GCDWebServerFileRequest.m          |   14 +-
 .../Requests/GCDWebServerMultiPartFormRequest.h |    2 +-
 .../Requests/GCDWebServerMultiPartFormRequest.m |   14 +-
 .../GCDWebServerURLEncodedFormRequest.h         |    2 +-
 .../GCDWebServerURLEncodedFormRequest.m         |    2 +-
 .../Responses/GCDWebServerDataResponse.h        |    2 +-
 .../Responses/GCDWebServerDataResponse.m        |    2 +-
 .../Responses/GCDWebServerErrorResponse.h       |    2 +-
 .../Responses/GCDWebServerErrorResponse.m       |    2 +-
 .../Responses/GCDWebServerFileResponse.h        |    2 +-
 .../Responses/GCDWebServerFileResponse.m        |   14 +-
 .../Responses/GCDWebServerStreamedResponse.h    |   15 +-
 .../Responses/GCDWebServerStreamedResponse.m    |    2 +-
 .../GCDWebUploader.bundle/css/index.css         |    2 +-
 .../GCDWebUploader.bundle/index.html            |    4 +-
 .../GCDWebUploader.bundle/js/index.js           |   13 +-
 .../GCDWebUploader/GCDWebUploader.h             |    2 +-
 .../GCDWebUploader/GCDWebUploader.m             |    6 +-
 local-webserver/src/ios/GCDWebServer/Mac/main.m |   41 +-
 local-webserver/src/ios/GCDWebServer/README.md  |  166 +--
 .../src/ios/GCDWebServer/Run-Tests.sh           |   48 +-
 .../Tests/WebDAV-Finder/059-200.response        |  Bin 107049 -> 0 bytes
 .../Tests/WebDAV-Finder/059-206.response        |  Bin 0 -> 8774 bytes
 .../Tests/WebDAV-Finder/062-200.response        |  Bin 116315 -> 0 bytes
 .../Tests/WebDAV-Finder/062-206.response        |  Bin 0 -> 18041 bytes
 .../WebServer-Sample-Movie/001-200.response     |  Bin 1278221 -> 1278221 bytes
 .../WebServer-Sample-Movie/002-206.response     |  Bin 1278274 -> 1278274 bytes
 .../WebServer-Sample-Movie/003-206.response     |  Bin 9265 -> 9265 bytes
 .../WebServer-Sample-Movie/004-206.response     |  Bin 3391644 -> 3391644 bytes
 .../WebServer-Sample-Movie/005-206.response     |  Bin 1173 -> 1173 bytes
 .../src/ios/GCDWebServer/iOS/AppDelegate.h      |    4 +-
 .../src/ios/GCDWebServer/iOS/AppDelegate.m      |   36 +-
 .../AppIcon.appiconset/Contents.json            |   68 ++
 .../iOS/Base.lproj/LaunchScreen.storyboard      |   28 +
 .../GCDWebServer/iOS/Base.lproj/Main.storyboard |   41 +
 .../src/ios/GCDWebServer/iOS/Info.plist         |   12 +-
 .../src/ios/GCDWebServer/iOS/ViewController.h   |   31 +
 .../src/ios/GCDWebServer/iOS/ViewController.m   |   77 ++
 local-webserver/src/ios/GCDWebServer/iOS/main.m |    2 +-
 .../src/ios/GCDWebServer/tvOS/AppDelegate.h     |   32 +
 .../src/ios/GCDWebServer/tvOS/AppDelegate.m     |   36 +
 .../Content.imageset/Contents.json              |   12 +
 .../Back.imagestacklayer/Contents.json          |    6 +
 .../App Icon - Large.imagestack/Contents.json   |   17 +
 .../Content.imageset/Contents.json              |   12 +
 .../Front.imagestacklayer/Contents.json         |    6 +
 .../Content.imageset/Contents.json              |   12 +
 .../Middle.imagestacklayer/Contents.json        |    6 +
 .../Content.imageset/Contents.json              |   12 +
 .../Back.imagestacklayer/Contents.json          |    6 +
 .../App Icon - Small.imagestack/Contents.json   |   17 +
 .../Content.imageset/Contents.json              |   12 +
 .../Front.imagestacklayer/Contents.json         |    6 +
 .../Content.imageset/Contents.json              |   12 +
 .../Middle.imagestacklayer/Contents.json        |    6 +
 .../Contents.json                               |   26 +
 .../Top Shelf Image.imageset/Contents.json      |   12 +
 .../tvOS/Assets.xcassets/Contents.json          |    6 +
 .../LaunchImage.launchimage/Contents.json       |   15 +
 .../tvOS/Base.lproj/Main.storyboard             |   40 +
 .../src/ios/GCDWebServer/tvOS/Info.plist        |   30 +
 .../src/ios/GCDWebServer/tvOS/ViewController.h  |   31 +
 .../src/ios/GCDWebServer/tvOS/ViewController.m  |   77 ++
 .../src/ios/GCDWebServer/tvOS/main.m            |   34 +
 91 files changed, 2708 insertions(+), 374 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/.gitignore
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/.gitignore
index f8bf09a,0000000..d7d4abb
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/.gitignore
+++ b/local-webserver/src/ios/GCDWebServer/.gitignore
@@@ -1,5 -1,0 +1,6 @@@
 +.DS_Store
 +xcuserdata
 +project.xcworkspace
 +
 +Tests/Payload
++Carthage/Build

http://git-wip-us.apache.org/repos/asf/cordova-plugins/blob/36f1a43e/local-webserver/src/ios/GCDWebServer/.travis.yml
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/.travis.yml
index 0bad31e,0000000..05cfcb6
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/.travis.yml
+++ b/local-webserver/src/ios/GCDWebServer/.travis.yml
@@@ -1,2 -1,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/36f1a43e/local-webserver/src/ios/GCDWebServer/Frameworks/GCDWebServers.h
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/Frameworks/GCDWebServers.h
index 0000000,0000000..60f42da
new file mode 100644
--- /dev/null
+++ b/local-webserver/src/ios/GCDWebServer/Frameworks/GCDWebServers.h
@@@ -1,0 -1,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/36f1a43e/local-webserver/src/ios/GCDWebServer/Frameworks/Info.plist
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/Frameworks/Info.plist
index 0000000,0000000..537b5cb
new file mode 100644
--- /dev/null
+++ b/local-webserver/src/ios/GCDWebServer/Frameworks/Info.plist
@@@ -1,0 -1,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/36f1a43e/local-webserver/src/ios/GCDWebServer/Frameworks/Tests.m
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/Frameworks/Tests.m
index 0000000,0000000..b1d69e7
new file mode 100644
--- /dev/null
+++ b/local-webserver/src/ios/GCDWebServer/Frameworks/Tests.m
@@@ -1,0 -1,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/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.h
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.h
index de3b538,0000000..84914db
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.h
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.h
@@@ -1,156 -1,0 +1,156 @@@
 +/*
-  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 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/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.m
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.m
index c7341fa,0000000..33025d4
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.m
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebDAVServer/GCDWebDAVServer.m
@@@ -1,688 -1,0 +1,701 @@@
 +/*
-  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 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/36f1a43e/local-webserver/src/ios/GCDWebServer/GCDWebServer.podspec
----------------------------------------------------------------------
diff --cc local-webserver/src/ios/GCDWebServer/GCDWebServer.podspec
index d713b26,0000000..901de93
mode 100644,000000..100644
--- a/local-webserver/src/ios/GCDWebServer/GCDWebServer.podspec
+++ b/local-webserver/src/ios/GCDWebServer/GCDWebServer.podspec
@@@ -1,49 -1,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 push
++# $ pod trunk --verbose push
 +# DELETE THIS SECTION BEFORE PROCEEDING!
 +
 +Pod::Spec.new do |s|
 +  s.name     = 'GCDWebServer'
-   s.version  = '3.1'
++  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 'WebDAV' do |cs|
++  s.subspec "CocoaLumberjack" do |cs|
 +    cs.dependency 'GCDWebServer/Core'
-     cs.source_files = 'GCDWebDAVServer/*.{h,m}'
-     cs.requires_arc = true
-     cs.ios.library = 'xml2'
-     cs.osx.library = 'xml2'
-     cs.compiler_flags = '-I$(SDKROOT)/usr/include/libxml2'
++    cs.dependency 'CocoaLumberjack', '~> 2'
 +  end
 +  
-   s.subspec 'WebUploader' do |cs|
-     cs.dependency 'GCDWebServer/Core'
-     cs.source_files = 'GCDWebUploader/*.{h,m}'
-     cs.requires_arc = true
-     cs.resource = "GCDWebUploader/GCDWebUploader.bundle"
++  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