浏览代码

#35 More work on unit tests

Pierre-Olivier Latour 11 年之前
父节点
当前提交
a28ac82ba2
共有 100 个文件被更改,包括 1063 次插入96 次删除
  1. 2 0
      CGDWebServer/GCDWebServer.h
  2. 116 91
      CGDWebServer/GCDWebServer.m
  3. 16 0
      CGDWebServer/GCDWebServerFileRequest.m
  4. 15 0
      GCDWebDAVServer/GCDWebDAVServer.m
  5. 2 0
      GCDWebServer.xcodeproj/project.pbxproj
  6. 13 5
      Run-Tests.sh
  7. 6 0
      Tests/WebDAV-Cyberduck/001-200.response
  8. 6 0
      Tests/WebDAV-Cyberduck/001-HEAD.request
  9. 14 0
      Tests/WebDAV-Cyberduck/002-207.response
  10. 10 0
      Tests/WebDAV-Cyberduck/002-PROPFIND.request
  11. 12 0
      Tests/WebDAV-Cyberduck/003-207.response
  12. 10 0
      Tests/WebDAV-Cyberduck/003-PROPFIND.request
  13. 13 0
      Tests/WebDAV-Cyberduck/004-207.response
  14. 10 0
      Tests/WebDAV-Cyberduck/004-PROPFIND.request
  15. 6 0
      Tests/WebDAV-Cyberduck/005-200.response
  16. 6 0
      Tests/WebDAV-Cyberduck/005-HEAD.request
  17. 7 0
      Tests/WebDAV-Cyberduck/006-404.response
  18. 6 0
      Tests/WebDAV-Cyberduck/006-HEAD.request
  19. 6 0
      Tests/WebDAV-Cyberduck/007-201.response
  20. 8 0
      Tests/WebDAV-Cyberduck/007-COPY.request
  21. 15 0
      Tests/WebDAV-Cyberduck/008-207.response
  22. 10 0
      Tests/WebDAV-Cyberduck/008-PROPFIND.request
  23. 6 0
      Tests/WebDAV-Cyberduck/009-200.response
  24. 6 0
      Tests/WebDAV-Cyberduck/009-HEAD.request
  25. 二进制
      Tests/WebDAV-Cyberduck/010-200.response
  26. 6 0
      Tests/WebDAV-Cyberduck/010-GET.request
  27. 13 0
      Tests/WebDAV-Cyberduck/011-207.response
  28. 10 0
      Tests/WebDAV-Cyberduck/011-PROPFIND.request
  29. 6 0
      Tests/WebDAV-Cyberduck/012-204.response
  30. 6 0
      Tests/WebDAV-Cyberduck/012-DELETE.request
  31. 6 0
      Tests/WebDAV-Cyberduck/013-204.response
  32. 6 0
      Tests/WebDAV-Cyberduck/013-DELETE.request
  33. 6 0
      Tests/WebDAV-Cyberduck/014-204.response
  34. 6 0
      Tests/WebDAV-Cyberduck/014-DELETE.request
  35. 14 0
      Tests/WebDAV-Cyberduck/015-207.response
  36. 10 0
      Tests/WebDAV-Cyberduck/015-PROPFIND.request
  37. 6 0
      Tests/WebDAV-Cyberduck/016-201.response
  38. 8 0
      Tests/WebDAV-Cyberduck/016-MOVE.request
  39. 14 0
      Tests/WebDAV-Cyberduck/017-207.response
  40. 10 0
      Tests/WebDAV-Cyberduck/017-PROPFIND.request
  41. 6 0
      Tests/WebDAV-Cyberduck/018-201.response
  42. 8 0
      Tests/WebDAV-Cyberduck/018-MOVE.request
  43. 13 0
      Tests/WebDAV-Cyberduck/019-207.response
  44. 10 0
      Tests/WebDAV-Cyberduck/019-PROPFIND.request
  45. 13 0
      Tests/WebDAV-Cyberduck/020-207.response
  46. 10 0
      Tests/WebDAV-Cyberduck/020-PROPFIND.request
  47. 6 0
      Tests/WebDAV-Cyberduck/021-200.response
  48. 6 0
      Tests/WebDAV-Cyberduck/021-HEAD.request
  49. 7 0
      Tests/WebDAV-Cyberduck/022-404.response
  50. 6 0
      Tests/WebDAV-Cyberduck/022-HEAD.request
  51. 6 0
      Tests/WebDAV-Cyberduck/023-201.response
  52. 11 0
      Tests/WebDAV-Cyberduck/023-PUT.request
  53. 14 0
      Tests/WebDAV-Cyberduck/024-207.response
  54. 10 0
      Tests/WebDAV-Cyberduck/024-PROPFIND.request
  55. 6 0
      Tests/WebDAV-Cyberduck/025-201.response
  56. 8 0
      Tests/WebDAV-Cyberduck/025-MKCOL.request
  57. 15 0
      Tests/WebDAV-Cyberduck/026-207.response
  58. 10 0
      Tests/WebDAV-Cyberduck/026-PROPFIND.request
  59. 11 0
      Tests/WebDAV-Cyberduck/027-207.response
  60. 10 0
      Tests/WebDAV-Cyberduck/027-PROPFIND.request
  61. 6 0
      Tests/WebDAV-Cyberduck/028-201.response
  62. 8 0
      Tests/WebDAV-Cyberduck/028-MOVE.request
  63. 6 0
      Tests/WebDAV-Cyberduck/029-201.response
  64. 8 0
      Tests/WebDAV-Cyberduck/029-MOVE.request
  65. 13 0
      Tests/WebDAV-Cyberduck/030-207.response
  66. 10 0
      Tests/WebDAV-Cyberduck/030-PROPFIND.request
  67. 13 0
      Tests/WebDAV-Cyberduck/031-207.response
  68. 10 0
      Tests/WebDAV-Cyberduck/031-PROPFIND.request
  69. 13 0
      Tests/WebDAV-Cyberduck/032-207.response
  70. 10 0
      Tests/WebDAV-Cyberduck/032-PROPFIND.request
  71. 6 0
      Tests/WebDAV-Cyberduck/033-204.response
  72. 6 0
      Tests/WebDAV-Cyberduck/033-DELETE.request
  73. 6 0
      Tests/WebDAV-Cyberduck/034-204.response
  74. 6 0
      Tests/WebDAV-Cyberduck/034-DELETE.request
  75. 6 0
      Tests/WebDAV-Cyberduck/035-204.response
  76. 6 0
      Tests/WebDAV-Cyberduck/035-DELETE.request
  77. 12 0
      Tests/WebDAV-Cyberduck/036-207.response
  78. 10 0
      Tests/WebDAV-Cyberduck/036-PROPFIND.request
  79. 7 0
      Tests/WebDAV-Finder/001-200.response
  80. 7 0
      Tests/WebDAV-Finder/001-OPTIONS.request
  81. 7 0
      Tests/WebDAV-Finder/002-200.response
  82. 7 0
      Tests/WebDAV-Finder/002-OPTIONS.request
  83. 7 0
      Tests/WebDAV-Finder/003-200.response
  84. 7 0
      Tests/WebDAV-Finder/003-OPTIONS.request
  85. 11 0
      Tests/WebDAV-Finder/004-207.response
  86. 18 0
      Tests/WebDAV-Finder/004-PROPFIND.request
  87. 11 0
      Tests/WebDAV-Finder/005-207.response
  88. 18 0
      Tests/WebDAV-Finder/005-PROPFIND.request
  89. 11 0
      Tests/WebDAV-Finder/006-207.response
  90. 18 0
      Tests/WebDAV-Finder/006-PROPFIND.request
  91. 11 0
      Tests/WebDAV-Finder/007-207.response
  92. 18 0
      Tests/WebDAV-Finder/007-PROPFIND.request
  93. 11 0
      Tests/WebDAV-Finder/008-207.response
  94. 18 0
      Tests/WebDAV-Finder/008-PROPFIND.request
  95. 11 0
      Tests/WebDAV-Finder/009-207.response
  96. 18 0
      Tests/WebDAV-Finder/009-PROPFIND.request
  97. 11 0
      Tests/WebDAV-Finder/010-207.response
  98. 18 0
      Tests/WebDAV-Finder/010-PROPFIND.request
  99. 11 0
      Tests/WebDAV-Finder/011-207.response
  100. 18 0
      Tests/WebDAV-Finder/011-PROPFIND.request

+ 2 - 0
CGDWebServer/GCDWebServer.h

@@ -85,6 +85,8 @@ NSDate* GCDWebServerParseISO8601(NSString* string);
 #if !TARGET_OS_IPHONE
 @property(nonatomic, getter=isRecordingEnabled) BOOL recordingEnabled;  // Creates files in the current directory containing the raw data for all requests and responses (directory most NOT contain prior recordings)
 - (BOOL)runWithPort:(NSUInteger)port;  // Starts then automatically stops on SIGINT i.e. Ctrl-C (use on main thread only)
+#endif
+#ifdef __GCDWEBSERVER_ENABLE_TESTING__
 - (NSInteger)runTestsInDirectory:(NSString*)path withPort:(NSUInteger)port;  // Returns number of failed tests or -1 if server failed to start
 #endif
 @end

+ 116 - 91
CGDWebServer/GCDWebServer.m

@@ -622,45 +622,56 @@ static void _NetServiceClientCallBack(CFNetServiceRef service, CFStreamError* er
   return success;
 }
 
-static CFHTTPMessageRef _CreateHTTPMessageFromFileDump(NSString* path, BOOL isRequest) {
-  NSData* data = [NSData dataWithContentsOfFile:path];
-  if (data) {
-    CFHTTPMessageRef message = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, isRequest);
-    if (CFHTTPMessageAppendBytes(message, data.bytes, data.length)) {
-      return message;
-    }
-    CFRelease(message);
+#endif
+
+#ifdef __GCDWEBSERVER_ENABLE_TESTING__
+
+static CFHTTPMessageRef _CreateHTTPMessageFromData(NSData* data, BOOL isRequest) {
+  CFHTTPMessageRef message = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, isRequest);
+  if (CFHTTPMessageAppendBytes(message, data.bytes, data.length)) {
+    return message;
   }
+  CFRelease(message);
   return NULL;
 }
 
-static CFHTTPMessageRef _CreateHTTPMessageFromHTTPRequestResponse(CFHTTPMessageRef request) {
+static CFHTTPMessageRef _CreateHTTPMessageFromPerformingRequest(NSData* inData, NSUInteger port) {
   CFHTTPMessageRef response = NULL;
-  CFReadStreamRef stream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request);
-  if (CFReadStreamOpen(stream)) {
-    CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
-    CFDataSetLength(data, 256 * 1024);
-    CFIndex length = 0;
-    while (1) {
-      CFIndex result = CFReadStreamRead(stream, CFDataGetMutableBytePtr(data) + length, CFDataGetLength(data) - length);
-      if (result <= 0) {
-        break;
-      }
-      length += result;
-      if (length >= CFDataGetLength(data)) {
-        CFDataSetLength(data, 2 * CFDataGetLength(data));
-      }
-    }
-    if (CFReadStreamGetStatus(stream) == kCFStreamStatusAtEnd) {
-      response = (CFHTTPMessageRef)CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader);
-      if (response) {
-        CFDataSetLength(data, length);
-        CFHTTPMessageSetBody(response, data);
+  int httpSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (httpSocket > 0) {
+    struct sockaddr_in addr4;
+    bzero(&addr4, sizeof(addr4));
+    addr4.sin_len = sizeof(port);
+    addr4.sin_family = AF_INET;
+    addr4.sin_port = htons(8080);
+    addr4.sin_addr.s_addr = htonl(INADDR_ANY);
+    if (connect(httpSocket, (void*)&addr4, sizeof(addr4)) == 0) {
+      if (write(httpSocket, inData.bytes, inData.length) == (ssize_t)inData.length) {
+        NSMutableData* outData = [[NSMutableData alloc] initWithLength:(256 * 1024)];
+        NSUInteger length = 0;
+        while (1) {
+          ssize_t result = read(httpSocket, (char*)outData.mutableBytes + length, outData.length - length);
+          if (result < 0) {
+            length = NSNotFound;
+            break;
+          } else if (result == 0) {
+            break;
+          }
+          length += result;
+          if (length >= outData.length) {
+            outData.length = 2 * outData.length;
+          }
+        }
+        if (length != NSNotFound) {
+          outData.length = length;
+          response = _CreateHTTPMessageFromData(outData, NO);
+        } else {
+          DNOT_REACHED();
+        }
+        ARC_RELEASE(outData);
       }
     }
-    CFRelease(data);
-    CFReadStreamClose(stream);
-    CFRelease(stream);
+    close(httpSocket);
   }
   return response;
 }
@@ -675,6 +686,7 @@ static void _LogResult(NSString* format, ...) {
 }
 
 - (NSInteger)runTestsInDirectory:(NSString*)path withPort:(NSUInteger)port {
+  NSArray* ignoredHeaders = @[@"Date", @"Etag"];  // Dates are always different by definition and ETags depend on file system node IDs
   NSInteger result = -1;
   if ([self startWithPort:port bonjourName:nil]) {
     
@@ -687,72 +699,85 @@ static void _LogResult(NSString* format, ...) {
       @autoreleasepool {
         NSString* index = [[requestFile componentsSeparatedByString:@"-"] firstObject];
         BOOL success = NO;
-        CFHTTPMessageRef request = _CreateHTTPMessageFromFileDump([path stringByAppendingPathComponent:requestFile], YES);
-        if (request) {
-          _LogResult(@"[%i] %@ %@", (int)[index integerValue], ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestMethod(request)), [ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestURL(request)) path]);
-          NSString* prefix = [index stringByAppendingString:@"-"];
-          for (NSString* responseFile in files) {
-            if ([responseFile hasPrefix:prefix] && [responseFile hasSuffix:@".response"]) {
-              CFHTTPMessageRef expectedResponse = _CreateHTTPMessageFromFileDump([path stringByAppendingPathComponent:responseFile], NO);
-              if (expectedResponse) {
-                CFHTTPMessageRef actualResponse = _CreateHTTPMessageFromHTTPRequestResponse(request);
-                if (actualResponse) {
-                  success = YES;
-                  
-                  CFIndex expectedStatusCode = CFHTTPMessageGetResponseStatusCode(expectedResponse);
-                  CFIndex actualStatusCode = CFHTTPMessageGetResponseStatusCode(actualResponse);
-                  if (actualStatusCode != expectedStatusCode) {
-                    _LogResult(@"  Status code not matching:\n    Expected: %i\n      Actual: %i", (int)expectedStatusCode, (int)actualStatusCode);
-                    success = NO;
-                  }
-                  
-                  NSDictionary* expectedHeaders = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(expectedResponse));
-                  NSDictionary* actualHeaders = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(actualResponse));
-                  for (NSString* expectedHeader in expectedHeaders) {
-                    if ([expectedHeader isEqualToString:@"Date"]) {
-                      continue;
-                    }
-                    NSString* expectedValue = [expectedHeaders objectForKey:expectedHeader];
-                    NSString* actualValue = [actualHeaders objectForKey:expectedHeader];
-                    if (![actualValue isEqualToString:expectedValue]) {
-                      _LogResult(@"  Header '%@' not matching:\n    Expected: \"%@\"\n      Actual: \"%@\"", expectedHeader, expectedValue, actualValue);
-                      success = NO;
-                    }
-                  }
-                  for (NSString* actualHeader in actualHeaders) {
-                    if (![expectedHeaders objectForKey:actualHeader]) {
-                      _LogResult(@"  Header '%@' not matching:\n    Expected: \"%@\"\n      Actual: \"%@\"", actualHeader, nil, [actualHeaders objectForKey:actualHeader]);
-                      success = NO;
-                    }
-                  }
-                  
-                  NSData* expectedBody = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyBody(expectedResponse));
-                  NSData* actualBody = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyBody(actualResponse));
-                  if (![actualBody isEqualToData:expectedBody]) {
-                    _LogResult(@"  Bodies not matching:\n    Expected: %lu bytes\n      Actual: %lu bytes", (unsigned long)expectedBody.length, (unsigned long)actualBody.length);
-                    success = NO;
-                    
-                    if (_IsTextContentType([expectedHeaders objectForKey:@"Content-Type"])) {
-                      NSString* expectedPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[[NSProcessInfo processInfo] globallyUniqueString] stringByAppendingPathExtension:@"txt"]];
-                      NSString* actualPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[[NSProcessInfo processInfo] globallyUniqueString] stringByAppendingPathExtension:@"txt"]];
-                      if ([expectedBody writeToFile:expectedPath atomically:YES] && [actualBody writeToFile:actualPath atomically:YES]) {
-                        NSTask* task = [[NSTask alloc] init];
-                        [task setLaunchPath:@"/usr/bin/opendiff"];
-                        [task setArguments:@[expectedPath, actualPath]];
-                        [task launch];
-                        ARC_RELEASE(task);
+        NSData* requestData = [NSData dataWithContentsOfFile:[path stringByAppendingPathComponent:requestFile]];
+        if (requestData) {
+          CFHTTPMessageRef request = _CreateHTTPMessageFromData(requestData, YES);
+          if (request) {
+            NSString* requestMethod = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestMethod(request));
+            NSURL* requestURL = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyRequestURL(request));
+            _LogResult(@"[%i] %@ %@", (int)[index integerValue], requestMethod, requestURL.path);
+            NSString* prefix = [index stringByAppendingString:@"-"];
+            for (NSString* responseFile in files) {
+              if ([responseFile hasPrefix:prefix] && [responseFile hasSuffix:@".response"]) {
+                NSData* responseData = [NSData dataWithContentsOfFile:[path stringByAppendingPathComponent:responseFile]];
+                if (responseData) {
+                CFHTTPMessageRef expectedResponse = _CreateHTTPMessageFromData(responseData, NO);
+                  if (expectedResponse) {
+                    CFHTTPMessageRef actualResponse = _CreateHTTPMessageFromPerformingRequest(requestData, port);
+                    if (actualResponse) {
+                      success = YES;
+                      
+                      CFIndex expectedStatusCode = CFHTTPMessageGetResponseStatusCode(expectedResponse);
+                      CFIndex actualStatusCode = CFHTTPMessageGetResponseStatusCode(actualResponse);
+                      if (actualStatusCode != expectedStatusCode) {
+                        _LogResult(@"  Status code not matching:\n    Expected: %i\n      Actual: %i", (int)expectedStatusCode, (int)actualStatusCode);
+                        success = NO;
+                      }
+                      
+                      NSDictionary* expectedHeaders = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(expectedResponse));
+                      NSDictionary* actualHeaders = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyAllHeaderFields(actualResponse));
+                      for (NSString* expectedHeader in expectedHeaders) {
+                        if ([ignoredHeaders containsObject:expectedHeader]) {
+                          continue;
+                        }
+                        NSString* expectedValue = [expectedHeaders objectForKey:expectedHeader];
+                        NSString* actualValue = [actualHeaders objectForKey:expectedHeader];
+                        if (![actualValue isEqualToString:expectedValue]) {
+                          _LogResult(@"  Header '%@' not matching:\n    Expected: \"%@\"\n      Actual: \"%@\"", expectedHeader, expectedValue, actualValue);
+                          success = NO;
+                        }
+                      }
+                      for (NSString* actualHeader in actualHeaders) {
+                        if (![expectedHeaders objectForKey:actualHeader]) {
+                          _LogResult(@"  Header '%@' not matching:\n    Expected: \"%@\"\n      Actual: \"%@\"", actualHeader, nil, [actualHeaders objectForKey:actualHeader]);
+                          success = NO;
+                        }
                       }
+                      
+                      NSData* expectedBody = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyBody(expectedResponse));
+                      NSData* actualBody = ARC_BRIDGE_RELEASE(CFHTTPMessageCopyBody(actualResponse));
+                      if (![actualBody isEqualToData:expectedBody]) {
+                        _LogResult(@"  Bodies not matching:\n    Expected: %lu bytes\n      Actual: %lu bytes", (unsigned long)expectedBody.length, (unsigned long)actualBody.length);
+                        success = NO;
+#ifndef NDEBUG
+                        if (_IsTextContentType([expectedHeaders objectForKey:@"Content-Type"])) {
+                          NSString* expectedPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[[NSProcessInfo processInfo] globallyUniqueString] stringByAppendingPathExtension:@"txt"]];
+                          NSString* actualPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[[NSProcessInfo processInfo] globallyUniqueString] stringByAppendingPathExtension:@"txt"]];
+                          if ([expectedBody writeToFile:expectedPath atomically:YES] && [actualBody writeToFile:actualPath atomically:YES]) {
+                            NSTask* task = [[NSTask alloc] init];
+                            [task setLaunchPath:@"/usr/bin/opendiff"];
+                            [task setArguments:@[expectedPath, actualPath]];
+                            [task launch];
+                            ARC_RELEASE(task);
+                          }
+                        }
+#endif
+                      }
+                      
+                      CFRelease(actualResponse);
                     }
+                    CFRelease(expectedResponse);
                   }
-                  
-                  CFRelease(actualResponse);
+                } else {
+                  DNOT_REACHED();
                 }
-                CFRelease(expectedResponse);
+                break;
               }
-              break;
             }
+            CFRelease(request);
           }
-          CFRelease(request);
+        } else {
+          DNOT_REACHED();
         }
         _LogResult(@"");
         if (!success) {

+ 16 - 0
CGDWebServer/GCDWebServerFileRequest.m

@@ -78,6 +78,22 @@ static inline NSError* _MakePosixError(int code) {
     *error = _MakePosixError(errno);
     return NO;
   }
+#ifdef __GCDWEBSERVER_ENABLE_TESTING__
+  NSString* creationDateHeader = [self.headers objectForKey:@"X-GCDWebServer-CreationDate"];
+  if (creationDateHeader) {
+    NSDate* date = GCDWebServerParseISO8601(creationDateHeader);
+    if (!date || ![[NSFileManager defaultManager] setAttributes:@{NSFileCreationDate: date} ofItemAtPath:_temporaryPath error:error]) {
+      return NO;
+    }
+  }
+  NSString* modifiedDateHeader = [self.headers objectForKey:@"X-GCDWebServer-ModifiedDate"];
+  if (modifiedDateHeader) {
+    NSDate* date = GCDWebServerParseRFC822(modifiedDateHeader);
+    if (!date || ![[NSFileManager defaultManager] setAttributes:@{NSFileModificationDate: date} ofItemAtPath:_temporaryPath error:error]) {
+      return NO;
+    }
+  }
+#endif
   return YES;
 }
 

+ 15 - 0
GCDWebDAVServer/GCDWebDAVServer.m

@@ -214,6 +214,15 @@ static inline BOOL _IsMacFinder(GCDWebServerRequest* request) {
   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 ([_delegate respondsToSelector:@selector(davServer:didCreateDirectoryAtPath:)]) {
     dispatch_async(dispatch_get_main_queue(), ^{
@@ -519,6 +528,12 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
     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);

+ 2 - 0
GCDWebServer.xcodeproj/project.pbxproj

@@ -461,6 +461,7 @@
 			buildSettings = {
 				CLANG_ENABLE_OBJC_ARC = YES;
 				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = __GCDWEBSERVER_ENABLE_TESTING__;
 				HEADER_SEARCH_PATHS = "$(SDKROOT)/usr/include/libxml2";
 				ONLY_ACTIVE_ARCH = YES;
 				WARNING_CFLAGS = (
@@ -488,6 +489,7 @@
 			buildSettings = {
 				CLANG_ENABLE_OBJC_ARC = YES;
 				GCC_PREPROCESSOR_DEFINITIONS = NDEBUG;
+				GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = __GCDWEBSERVER_ENABLE_TESTING__;
 				GCC_TREAT_WARNINGS_AS_ERRORS = YES;
 				HEADER_SEARCH_PATHS = "$(SDKROOT)/usr/include/libxml2";
 				WARNING_CFLAGS = "-Wall";

+ 13 - 5
Run-Tests.sh

@@ -2,18 +2,20 @@
 
 TARGET="GCDWebServer (Mac)"
 CONFIGURATION="Release"
-PAYLOAD_ZIP="Tests/Payload.zip"
-PAYLOAD_DIR="/tmp/payload"
 
 MRC_BUILD_DIR="/tmp/GCDWebServer-MRC"
 MRC_PRODUCT="$MRC_BUILD_DIR/$CONFIGURATION/GCDWebServer"
 ARC_BUILD_DIR="/tmp/GCDWebServer-ARC"
 ARC_PRODUCT="$ARC_BUILD_DIR/$CONFIGURATION/GCDWebServer"
 
+PAYLOAD_ZIP="Tests/Payload.zip"
+PAYLOAD_DIR="/tmp/GCDWebServer"
+
 function runTests {
   rm -rf "$PAYLOAD_DIR"
   ditto -x -k "$PAYLOAD_ZIP" "$PAYLOAD_DIR"
-  logLevel=2 $1 -root "$PAYLOAD_DIR" -tests "$2"
+  find "$PAYLOAD_DIR" -type d -exec SetFile -d "1/1/2014" -m "1/1/2014" '{}' \;  # ZIP archives do not preserve directories dates
+  logLevel=2 $1 -mode "$2" -root "$PAYLOAD_DIR/Payload" -tests "$3"
 }
 
 # Build in manual memory management mode
@@ -25,8 +27,14 @@ rm -rf "ARC_BUILD_DIR"
 xcodebuild -target "$TARGET" -configuration "$CONFIGURATION" build "SYMROOT=$ARC_BUILD_DIR" "CLANG_ENABLE_OBJC_ARC=YES" > /dev/null
 
 # Run tests
-runTests $MRC_PRODUCT "WebServer"
-runTests $ARC_PRODUCT "WebServer"
+runTests $MRC_PRODUCT "webServer" "Tests/WebServer"
+runTests $ARC_PRODUCT "webServer" "Tests/WebServer"
+runTests $MRC_PRODUCT "webDAV" "Tests/WebDAV-Transmit"
+runTests $ARC_PRODUCT "webDAV" "Tests/WebDAV-Transmit"
+runTests $MRC_PRODUCT "webDAV" "Tests/WebDAV-Cyberduck"
+runTests $ARC_PRODUCT "webDAV" "Tests/WebDAV-Cyberduck"
+runTests $MRC_PRODUCT "webDAV" "Tests/WebDAV-Finder"
+runTests $ARC_PRODUCT "webDAV" "Tests/WebDAV-Finder"
 
 # Done
 echo "\nAll tests completed successfully!"

+ 6 - 0
Tests/WebDAV-Cyberduck/001-200.response

@@ -0,0 +1,6 @@
+HTTP/1.1 200 OK
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:52:42 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/001-HEAD.request

@@ -0,0 +1,6 @@
+HEAD / HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 14 - 0
Tests/WebDAV-Cyberduck/002-207.response

@@ -0,0 +1,14 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 1106
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:52:42 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Copy.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/images</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/002-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND / HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 12 - 0
Tests/WebDAV-Cyberduck/003-207.response

@@ -0,0 +1,12 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 700
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:52:47 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/PDF%20Reports/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports/Apple%20Economic%20Impact%20on%20Cupertino.pdf</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2013-05-01T12:01:13+00:00</D:creationdate><D:getlastmodified>Wed, 01 May 2013 12:01:13 GMT</D:getlastmodified><D:getcontentlength>181952</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/003-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND /PDF%20Reports/ HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 13 - 0
Tests/WebDAV-Cyberduck/004-207.response

@@ -0,0 +1,13 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 998
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:52:47 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/images/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/images/capable_green_ipad_l.png</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T21:46:56+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 21:46:56 GMT</D:getlastmodified><D:getcontentlength>116066</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/images/hero_mba_11.jpg</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T21:51:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 21:51:14 GMT</D:getlastmodified><D:getcontentlength>106799</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/004-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND /images/ HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 6 - 0
Tests/WebDAV-Cyberduck/005-200.response

@@ -0,0 +1,6 @@
+HTTP/1.1 200 OK
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:52:51 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/005-HEAD.request

@@ -0,0 +1,6 @@
+HEAD / HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 7 - 0
Tests/WebDAV-Cyberduck/006-404.response

@@ -0,0 +1,7 @@
+HTTP/1.1 404 Not Found
+Content-Length: 204
+Content-Type: text/html; charset=utf-8
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:52:51 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/006-HEAD.request

@@ -0,0 +1,6 @@
+HEAD /Copy%20%284%3A11%3A14%2C%209%3A52%20PM%29.txt HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 6 - 0
Tests/WebDAV-Cyberduck/007-201.response

@@ -0,0 +1,6 @@
+HTTP/1.1 201 Created
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:52:51 GMT
+

+ 8 - 0
Tests/WebDAV-Cyberduck/007-COPY.request

@@ -0,0 +1,8 @@
+COPY /Copy.txt HTTP/1.1
+Destination: http://localhost:8080/Copy%20%284%3A11%3A14%2C%209%3A52%20PM%29.txt
+Overwrite: T
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 15 - 0
Tests/WebDAV-Cyberduck/008-207.response

@@ -0,0 +1,15 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 1448
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:52:51 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Copy%20(4:11:14,%209:52%20PM).txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Copy.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/images</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/008-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND / HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 6 - 0
Tests/WebDAV-Cyberduck/009-200.response

@@ -0,0 +1,6 @@
+HTTP/1.1 200 OK
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:52:59 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/009-HEAD.request

@@ -0,0 +1,6 @@
+HEAD / HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

二进制
Tests/WebDAV-Cyberduck/010-200.response


+ 6 - 0
Tests/WebDAV-Cyberduck/010-GET.request

@@ -0,0 +1,6 @@
+GET /images/capable_green_ipad_l.png HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 13 - 0
Tests/WebDAV-Cyberduck/011-207.response

@@ -0,0 +1,13 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 998
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:07 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/images/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/images/capable_green_ipad_l.png</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T21:46:56+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 21:46:56 GMT</D:getlastmodified><D:getcontentlength>116066</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/images/hero_mba_11.jpg</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T21:51:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 21:51:14 GMT</D:getlastmodified><D:getcontentlength>106799</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/011-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND /images/ HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 6 - 0
Tests/WebDAV-Cyberduck/012-204.response

@@ -0,0 +1,6 @@
+HTTP/1.1 204 No Content
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:07 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/012-DELETE.request

@@ -0,0 +1,6 @@
+DELETE /images/capable_green_ipad_l.png HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 6 - 0
Tests/WebDAV-Cyberduck/013-204.response

@@ -0,0 +1,6 @@
+HTTP/1.1 204 No Content
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:07 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/013-DELETE.request

@@ -0,0 +1,6 @@
+DELETE /images/hero_mba_11.jpg HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 6 - 0
Tests/WebDAV-Cyberduck/014-204.response

@@ -0,0 +1,6 @@
+HTTP/1.1 204 No Content
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:07 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/014-DELETE.request

@@ -0,0 +1,6 @@
+DELETE /images/ HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 14 - 0
Tests/WebDAV-Cyberduck/015-207.response

@@ -0,0 +1,14 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 1214
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:07 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Copy%20(4:11:14,%209:52%20PM).txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Copy.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/015-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND / HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 6 - 0
Tests/WebDAV-Cyberduck/016-201.response

@@ -0,0 +1,6 @@
+HTTP/1.1 201 Created
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:13 GMT
+

+ 8 - 0
Tests/WebDAV-Cyberduck/016-MOVE.request

@@ -0,0 +1,8 @@
+MOVE /Copy%20%284%3A11%3A14%2C%209%3A52%20PM%29.txt HTTP/1.1
+Destination: http://localhost:8080/Test.txt
+Overwrite: T
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 14 - 0
Tests/WebDAV-Cyberduck/017-207.response

@@ -0,0 +1,14 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 1189
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:13 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Copy.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Test.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/017-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND / HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 6 - 0
Tests/WebDAV-Cyberduck/018-201.response

@@ -0,0 +1,6 @@
+HTTP/1.1 201 Created
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:14 GMT
+

+ 8 - 0
Tests/WebDAV-Cyberduck/018-MOVE.request

@@ -0,0 +1,8 @@
+MOVE /Test.txt HTTP/1.1
+Destination: http://localhost:8080/PDF%20Reports/Test.txt
+Overwrite: T
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 13 - 0
Tests/WebDAV-Cyberduck/019-207.response

@@ -0,0 +1,13 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 872
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:14 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Copy.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/019-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND / HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 13 - 0
Tests/WebDAV-Cyberduck/020-207.response

@@ -0,0 +1,13 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 1031
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:14 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/PDF%20Reports/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports/Apple%20Economic%20Impact%20on%20Cupertino.pdf</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2013-05-01T12:01:13+00:00</D:creationdate><D:getlastmodified>Wed, 01 May 2013 12:01:13 GMT</D:getlastmodified><D:getcontentlength>181952</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports/Test.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/020-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND /PDF%20Reports/ HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 6 - 0
Tests/WebDAV-Cyberduck/021-200.response

@@ -0,0 +1,6 @@
+HTTP/1.1 200 OK
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:22 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/021-HEAD.request

@@ -0,0 +1,6 @@
+HEAD / HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 7 - 0
Tests/WebDAV-Cyberduck/022-404.response

@@ -0,0 +1,7 @@
+HTTP/1.1 404 Not Found
+Content-Length: 190
+Content-Type: text/html; charset=utf-8
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:22 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/022-HEAD.request

@@ -0,0 +1,6 @@
+HEAD /Test%20File.txt HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 6 - 0
Tests/WebDAV-Cyberduck/023-201.response

@@ -0,0 +1,6 @@
+HTTP/1.1 201 Created
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:22 GMT
+

+ 11 - 0
Tests/WebDAV-Cyberduck/023-PUT.request

@@ -0,0 +1,11 @@
+PUT /Test%20File.txt HTTP/1.1
+Content-Length: 21
+Content-Type: text/plain
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+X-GCDWebServer-CreationDate: 2014-04-12T04:53:22+00:00
+X-GCDWebServer-ModifiedDate: Sat, 12 Apr 2014 04:53:22 GMT
+
+Nothing to see here!

+ 14 - 0
Tests/WebDAV-Cyberduck/024-207.response

@@ -0,0 +1,14 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 1195
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:22 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Copy.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Test%20File.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-12T04:53:22+00:00</D:creationdate><D:getlastmodified>Sat, 12 Apr 2014 04:53:22 GMT</D:getlastmodified><D:getcontentlength>21</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/024-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND / HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 6 - 0
Tests/WebDAV-Cyberduck/025-201.response

@@ -0,0 +1,6 @@
+HTTP/1.1 201 Created
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:35 GMT
+

+ 8 - 0
Tests/WebDAV-Cyberduck/025-MKCOL.request

@@ -0,0 +1,8 @@
+MKCOL /Text%20Files/ HTTP/1.1
+Content-Length: 0
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+X-GCDWebServer-CreationDate: 2014-04-12T04:53:35+00:00
+

+ 15 - 0
Tests/WebDAV-Cyberduck/026-207.response

@@ -0,0 +1,15 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 1435
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:35 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Copy.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Test%20File.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-12T04:53:22+00:00</D:creationdate><D:getlastmodified>Sat, 12 Apr 2014 04:53:22 GMT</D:getlastmodified><D:getcontentlength>21</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Text%20Files</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-04-12T04:53:35+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/026-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND / HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 11 - 0
Tests/WebDAV-Cyberduck/027-207.response

@@ -0,0 +1,11 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 327
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:36 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/Text%20Files/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-04-12T04:53:35+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/027-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND /Text%20Files/ HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 6 - 0
Tests/WebDAV-Cyberduck/028-201.response

@@ -0,0 +1,6 @@
+HTTP/1.1 201 Created
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:39 GMT
+

+ 8 - 0
Tests/WebDAV-Cyberduck/028-MOVE.request

@@ -0,0 +1,8 @@
+MOVE /Test%20File.txt HTTP/1.1
+Destination: http://localhost:8080/Text%20Files/Test%20File.txt
+Overwrite: T
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 6 - 0
Tests/WebDAV-Cyberduck/029-201.response

@@ -0,0 +1,6 @@
+HTTP/1.1 201 Created
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:39 GMT
+

+ 8 - 0
Tests/WebDAV-Cyberduck/029-MOVE.request

@@ -0,0 +1,8 @@
+MOVE /Copy.txt HTTP/1.1
+Destination: http://localhost:8080/Text%20Files/Copy.txt
+Overwrite: T
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 13 - 0
Tests/WebDAV-Cyberduck/030-207.response

@@ -0,0 +1,13 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 795
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:39 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Text%20Files</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-04-12T04:53:35+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/030-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND / HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 13 - 0
Tests/WebDAV-Cyberduck/031-207.response

@@ -0,0 +1,13 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 993
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:39 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/Text%20Files/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-04-12T04:53:35+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Text%20Files/Copy.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Text%20Files/Test%20File.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-12T04:53:22+00:00</D:creationdate><D:getlastmodified>Sat, 12 Apr 2014 04:53:22 GMT</D:getlastmodified><D:getcontentlength>21</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/031-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND /Text%20Files/ HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 13 - 0
Tests/WebDAV-Cyberduck/032-207.response

@@ -0,0 +1,13 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 1031
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:44 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/PDF%20Reports/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports/Apple%20Economic%20Impact%20on%20Cupertino.pdf</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2013-05-01T12:01:13+00:00</D:creationdate><D:getlastmodified>Wed, 01 May 2013 12:01:13 GMT</D:getlastmodified><D:getcontentlength>181952</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/PDF%20Reports/Test.txt</D:href><D:propstat><D:prop><D:resourcetype/><D:creationdate>2014-04-10T11:10:14+00:00</D:creationdate><D:getlastmodified>Thu, 10 Apr 2014 11:10:14 GMT</D:getlastmodified><D:getcontentlength>271</D:getcontentlength></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/032-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND /PDF%20Reports/ HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 6 - 0
Tests/WebDAV-Cyberduck/033-204.response

@@ -0,0 +1,6 @@
+HTTP/1.1 204 No Content
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:44 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/033-DELETE.request

@@ -0,0 +1,6 @@
+DELETE /PDF%20Reports/Apple%20Economic%20Impact%20on%20Cupertino.pdf HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 6 - 0
Tests/WebDAV-Cyberduck/034-204.response

@@ -0,0 +1,6 @@
+HTTP/1.1 204 No Content
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:44 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/034-DELETE.request

@@ -0,0 +1,6 @@
+DELETE /PDF%20Reports/Test.txt HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 6 - 0
Tests/WebDAV-Cyberduck/035-204.response

@@ -0,0 +1,6 @@
+HTTP/1.1 204 No Content
+Cache-Control: no-cache
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:44 GMT
+

+ 6 - 0
Tests/WebDAV-Cyberduck/035-DELETE.request

@@ -0,0 +1,6 @@
+DELETE /PDF%20Reports/ HTTP/1.1
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+

+ 12 - 0
Tests/WebDAV-Cyberduck/036-207.response

@@ -0,0 +1,12 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 554
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 04:53:44 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+<D:response><D:href>/Text%20Files</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-04-12T04:53:35+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 10 - 0
Tests/WebDAV-Cyberduck/036-PROPFIND.request

@@ -0,0 +1,10 @@
+PROPFIND / HTTP/1.1
+Depth: 1
+Content-Type: text/xml; charset=utf-8
+Content-Length: 99
+Host: localhost:8080
+Connection: Keep-Alive
+User-Agent: Cyberduck/4.4.3 (Mac OS X/10.9.2) (x86_64)
+Accept-Encoding: gzip,deflate
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><propfind xmlns="DAV:"><allprop/></propfind>

+ 7 - 0
Tests/WebDAV-Finder/001-200.response

@@ -0,0 +1,7 @@
+HTTP/1.1 200 OK
+Cache-Control: no-cache
+DAV: 1, 2
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 05:10:55 GMT
+

+ 7 - 0
Tests/WebDAV-Finder/001-OPTIONS.request

@@ -0,0 +1,7 @@
+OPTIONS / HTTP/1.1
+Host: localhost:8080
+Accept: */*
+Content-Length: 0
+Connection: close
+User-Agent: WebDAVLib/1.3
+

+ 7 - 0
Tests/WebDAV-Finder/002-200.response

@@ -0,0 +1,7 @@
+HTTP/1.1 200 OK
+Cache-Control: no-cache
+DAV: 1, 2
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 05:10:55 GMT
+

+ 7 - 0
Tests/WebDAV-Finder/002-OPTIONS.request

@@ -0,0 +1,7 @@
+OPTIONS / HTTP/1.1
+Host: localhost:8080
+Accept: */*
+Content-Length: 0
+Connection: close
+User-Agent: WebDAVLib/1.3
+

+ 7 - 0
Tests/WebDAV-Finder/003-200.response

@@ -0,0 +1,7 @@
+HTTP/1.1 200 OK
+Cache-Control: no-cache
+DAV: 1, 2
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 05:10:55 GMT
+

+ 7 - 0
Tests/WebDAV-Finder/003-OPTIONS.request

@@ -0,0 +1,7 @@
+OPTIONS / HTTP/1.1
+Host: localhost:8080
+Accept: */*
+Content-Length: 0
+Connection: keep-alive
+User-Agent: WebDAVFS/3.0.1 (03018000) Darwin/13.1.0 (x86_64)
+

+ 11 - 0
Tests/WebDAV-Finder/004-207.response

@@ -0,0 +1,11 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 314
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 05:10:55 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 18 - 0
Tests/WebDAV-Finder/004-PROPFIND.request

@@ -0,0 +1,18 @@
+PROPFIND / HTTP/1.1
+Host: localhost:8080
+Content-Type: text/xml
+Depth: 0
+Accept: */*
+User-Agent: WebDAVFS/3.0.1 (03018000) Darwin/13.1.0 (x86_64)
+Content-Length: 179
+Connection: keep-alive
+
+<?xml version="1.0" encoding="utf-8"?>
+<D:propfind xmlns:D="DAV:">
+<D:prop>
+<D:getlastmodified/>
+<D:getcontentlength/>
+<D:creationdate/>
+<D:resourcetype/>
+</D:prop>
+</D:propfind>

+ 11 - 0
Tests/WebDAV-Finder/005-207.response

@@ -0,0 +1,11 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 208
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 05:10:55 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 18 - 0
Tests/WebDAV-Finder/005-PROPFIND.request

@@ -0,0 +1,18 @@
+PROPFIND / HTTP/1.1
+Host: localhost:8080
+Content-Type: text/xml
+Depth: 0
+Accept: */*
+User-Agent: WebDAVFS/3.0.1 (03018000) Darwin/13.1.0 (x86_64)
+Content-Length: 175
+Connection: keep-alive
+
+<?xml version="1.0" encoding="utf-8"?>
+<D:propfind xmlns:D="DAV:">
+<D:prop>
+<D:quota-available-bytes/>
+<D:quota-used-bytes/>
+<D:quota/>
+<D:quotaused/>
+</D:prop>
+</D:propfind>

+ 11 - 0
Tests/WebDAV-Finder/006-207.response

@@ -0,0 +1,11 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 314
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 05:10:55 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 18 - 0
Tests/WebDAV-Finder/006-PROPFIND.request

@@ -0,0 +1,18 @@
+PROPFIND / HTTP/1.1
+Host: localhost:8080
+Content-Type: text/xml
+Depth: 0
+Accept: */*
+User-Agent: WebDAVFS/3.0.1 (03018000) Darwin/13.1.0 (x86_64)
+Content-Length: 179
+Connection: keep-alive
+
+<?xml version="1.0" encoding="utf-8"?>
+<D:propfind xmlns:D="DAV:">
+<D:prop>
+<D:getlastmodified/>
+<D:getcontentlength/>
+<D:creationdate/>
+<D:resourcetype/>
+</D:prop>
+</D:propfind>

+ 11 - 0
Tests/WebDAV-Finder/007-207.response

@@ -0,0 +1,11 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 314
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 05:10:55 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 18 - 0
Tests/WebDAV-Finder/007-PROPFIND.request

@@ -0,0 +1,18 @@
+PROPFIND / HTTP/1.1
+Host: localhost:8080
+Content-Type: text/xml
+Depth: 0
+Accept: */*
+User-Agent: WebDAVFS/3.0.1 (03018000) Darwin/13.1.0 (x86_64)
+Content-Length: 179
+Connection: keep-alive
+
+<?xml version="1.0" encoding="utf-8"?>
+<D:propfind xmlns:D="DAV:">
+<D:prop>
+<D:getlastmodified/>
+<D:getcontentlength/>
+<D:creationdate/>
+<D:resourcetype/>
+</D:prop>
+</D:propfind>

+ 11 - 0
Tests/WebDAV-Finder/008-207.response

@@ -0,0 +1,11 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 314
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 05:10:55 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 18 - 0
Tests/WebDAV-Finder/008-PROPFIND.request

@@ -0,0 +1,18 @@
+PROPFIND / HTTP/1.1
+Host: localhost:8080
+Content-Type: text/xml
+Depth: 0
+Accept: */*
+User-Agent: WebDAVFS/3.0.1 (03018000) Darwin/13.1.0 (x86_64)
+Content-Length: 179
+Connection: keep-alive
+
+<?xml version="1.0" encoding="utf-8"?>
+<D:propfind xmlns:D="DAV:">
+<D:prop>
+<D:getlastmodified/>
+<D:getcontentlength/>
+<D:creationdate/>
+<D:resourcetype/>
+</D:prop>
+</D:propfind>

+ 11 - 0
Tests/WebDAV-Finder/009-207.response

@@ -0,0 +1,11 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 314
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 05:10:55 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 18 - 0
Tests/WebDAV-Finder/009-PROPFIND.request

@@ -0,0 +1,18 @@
+PROPFIND / HTTP/1.1
+Host: localhost:8080
+Content-Type: text/xml
+Depth: 0
+Accept: */*
+User-Agent: WebDAVFS/3.0.1 (03018000) Darwin/13.1.0 (x86_64)
+Content-Length: 179
+Connection: keep-alive
+
+<?xml version="1.0" encoding="utf-8"?>
+<D:propfind xmlns:D="DAV:">
+<D:prop>
+<D:getlastmodified/>
+<D:getcontentlength/>
+<D:creationdate/>
+<D:resourcetype/>
+</D:prop>
+</D:propfind>

+ 11 - 0
Tests/WebDAV-Finder/010-207.response

@@ -0,0 +1,11 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 314
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 05:10:55 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 18 - 0
Tests/WebDAV-Finder/010-PROPFIND.request

@@ -0,0 +1,18 @@
+PROPFIND / HTTP/1.1
+Host: localhost:8080
+Content-Type: text/xml
+Depth: 0
+Accept: */*
+User-Agent: WebDAVFS/3.0.1 (03018000) Darwin/13.1.0 (x86_64)
+Content-Length: 179
+Connection: keep-alive
+
+<?xml version="1.0" encoding="utf-8"?>
+<D:propfind xmlns:D="DAV:">
+<D:prop>
+<D:getlastmodified/>
+<D:getcontentlength/>
+<D:creationdate/>
+<D:resourcetype/>
+</D:prop>
+</D:propfind>

+ 11 - 0
Tests/WebDAV-Finder/011-207.response

@@ -0,0 +1,11 @@
+HTTP/1.1 207 Multi-Status
+Cache-Control: no-cache
+Content-Length: 314
+Content-Type: application/xml; charset="utf-8"
+Connection: Close
+Server: GCDWebDAVServer
+Date: Sat, 12 Apr 2014 05:10:55 GMT
+
+<?xml version="1.0" encoding="utf-8" ?><D:multistatus xmlns:D="DAV:">
+<D:response><D:href>/</D:href><D:propstat><D:prop><D:resourcetype><D:collection/></D:resourcetype><D:creationdate>2014-01-01T09:01:00+00:00</D:creationdate></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response>
+</D:multistatus>

+ 18 - 0
Tests/WebDAV-Finder/011-PROPFIND.request

@@ -0,0 +1,18 @@
+PROPFIND / HTTP/1.1
+Host: localhost:8080
+Content-Type: text/xml
+Depth: 0
+Accept: */*
+User-Agent: WebDAVFS/3.0.1 (03018000) Darwin/13.1.0 (x86_64)
+Content-Length: 179
+Connection: keep-alive
+
+<?xml version="1.0" encoding="utf-8"?>
+<D:propfind xmlns:D="DAV:">
+<D:prop>
+<D:getlastmodified/>
+<D:getcontentlength/>
+<D:creationdate/>
+<D:resourcetype/>
+</D:prop>
+</D:propfind>

部分文件因为文件数量过多而无法显示