diff --git a/source/vibedav/base.d b/source/vibedav/base.d index a427153..5a0259c 100644 --- a/source/vibedav/base.d +++ b/source/vibedav/base.d @@ -285,14 +285,14 @@ abstract class DavBase : IDav { void put(DavRequest request, DavResponse response) { DavResource resource = getOrCreateResource(request.url, response.statusCode); - DavStorage.locks.check(request.url, request.ifCondition); resource.setContent(request.stream, request.contentLength); DavStorage.locks.setETag(resource.url, resource.eTag); - response.statusCode = HTTPStatus.created; + response.statusCode = HTTPStatus.created;writeln("1"); + response.flush; } @@ -315,11 +315,8 @@ abstract class DavBase : IDav { if(request.contentLength > 0) throw new DavException(HTTPStatus.unsupportedMediaType, "Body must be empty"); - try auto resource = getResource(request.url.parentURL); - - catch (DavException e) - if(e.status == HTTPStatus.notFound) - throw new DavException(HTTPStatus.conflict, "Missing parent"); + if(!exists(request.url.parentURL)) + throw new DavException(HTTPStatus.conflict, "Missing parent"); DavStorage.locks.check(request.url, ifHeader); diff --git a/source/vibedav/caldav.d b/source/vibedav/caldav.d index d8cf9ef..2f79b3c 100644 --- a/source/vibedav/caldav.d +++ b/source/vibedav/caldav.d @@ -68,6 +68,7 @@ class DavCalendarBaseResource : DavResource, ICalendarCollectionProperties, IDav this(IDav dav, URL url, bool forceCreate = false) { super(dav, url); + this.dav = dav; } @@ -151,7 +152,7 @@ class DavFileBaseCalendarResource : DavCalendarBaseResource { filePath = dav.filePath(url); nativePath = filePath.toNativeString(); - if(!nativePath.exists) + if(!forceCreate && !nativePath.exists) throw new DavException(HTTPStatus.notFound, "File not found."); href = path.toString; @@ -188,6 +189,9 @@ class FileDavCalendarCollection : DavFileBaseCalendarResource { this(IFileDav dav, URL url, bool forceCreate = false) { super(dav, url, forceCreate); + if(forceCreate && !nativePath.exists) + nativePath.mkdirRecurse; + if(!nativePath.isDir) throw new DavException(HTTPStatus.internalServerError, nativePath ~ ": Path must be a folder."); } @@ -233,8 +237,11 @@ class FileDavCalendarResource : DavFileBaseCalendarResource { this(IFileDav dav, URL url, bool forceCreate = false) { super(dav, url, forceCreate); - if(nativePath.isDir) + if(!forceCreate && nativePath.isDir) throw new DavException(HTTPStatus.internalServerError, nativePath ~ ": Path must be a file."); + + if(forceCreate && !nativePath.exists) + File(nativePath, "w"); } @property { @@ -316,6 +323,5 @@ unittest { auto dav = new FileDav!T; auto res = T.Get(dav, URL("http://127.0.0.1/admin")); - writeln("res.type ", res.type); assert(res.type == "FileDavCalendarCollection"); } diff --git a/source/vibedav/davresource.d b/source/vibedav/davresource.d index b2a2c47..3dc69bb 100644 --- a/source/vibedav/davresource.d +++ b/source/vibedav/davresource.d @@ -238,7 +238,7 @@ interface IDavResourceProperties { @ResourceProperty("creationdate", "DAV:") SysTime creationDate(); - @ResourceProperty("lastmodified", "DAV:") + @ResourceProperty("getlastmodified", "DAV:") SysTime lastModified(); @ResourceProperty("getetag", "DAV:") diff --git a/source/vibedav/filedav.d b/source/vibedav/filedav.d index 546f550..0ce2f58 100644 --- a/source/vibedav/filedav.d +++ b/source/vibedav/filedav.d @@ -36,12 +36,20 @@ import std.algorithm.comparison : max; import tested: testName = name; string stripSlashes(string path) { + return path.stripBeginSlashes.stripEndSlasshes; +} + +string stripBeginSlashes(string path) { if(path.length > 0 && path[0] == '/') path = path[1..$]; if(path.length > 1 && path[0..2] == "./") path = path[2..$]; + return path; +} + +string stripEndSlasshes(string path) { if(path.length > 0 && path[path.length-1] == '/') path = path[0..$-1]; @@ -139,7 +147,13 @@ abstract class FileDavResourceBase : DavResource { path.normalize; filePath = dav.filePath(url); - nativePath = filePath.toNativeString(); + + auto nPath = filePath.toNativeString(); + + if(nPath == "") + nativePath = "./"; + else + nativePath = nPath; if(!forceCreate && !nativePath.exists) throw new DavException(HTTPStatus.notFound, "File not found."); @@ -161,7 +175,7 @@ abstract class FileDavResourceBase : DavResource { } string[] resourceType() { - return ["collection:DAV:"]; + return []; } override bool isCollection() { @@ -194,11 +208,11 @@ class FileDavCollection : FileDavResourceBase { this(IFileDav dav, URL url, bool forceCreate = false) { super(dav, url, forceCreate); - if(nativePath.exists && !nativePath.isDir) - throw new DavException(HTTPStatus.internalServerError, nativePath ~ ": Path must be a folder."); - if(forceCreate && !nativePath.exists) nativePath.mkdirRecurse; + + if(nativePath.exists && !nativePath.isDir) + throw new DavException(HTTPStatus.internalServerError, nativePath ~ ": Path must be a folder."); } override bool[string] getChildren() { @@ -251,8 +265,14 @@ class FileDavCollection : FileDavResourceBase { return 0; } - override nothrow string type() { - return "FileDavCollection"; + override { + string[] resourceType() { + return ["collection:DAV:"]; + } + + nothrow string type() { + return "FileDavCollection"; + } } } } @@ -270,16 +290,16 @@ class FileDavResource : FileDavResourceBase { File(nativePath, "w"); } - override bool[string] getChildren() { - return getFolderContent!"*"(nativePath, dav.rootFile, dav.rootUrl); - } + override { + bool[string] getChildren() { + return getFolderContent!"*"(nativePath, dav.rootFile, dav.rootUrl); + } - override void remove() { - super.remove; - nativePath.remove; - } + void remove() { + super.remove; + nativePath.remove; + } - override { void setContent(const ubyte[] content) { std.stdio.write(nativePath, content); } @@ -366,6 +386,7 @@ class FileDavResourceFactory(T...) if(T.length >= 5) { DavResource Get(IFileDav dav, const URL url, IDavUser user = null) { DavResource res; Path path = FilePath(url); + res = GetResourceOrCollection!(T[2..$])(dav, url, path); if(res is null) @@ -464,7 +485,7 @@ class FileDavResourceFactory(T...) if(T.length >= 5) { return otherRes; } - if(localScore > score) + if(localScore > score || (score == 0 && List[0] == "")) return start / 3; return -1; @@ -503,7 +524,7 @@ unittest { alias T = FileDavResourceFactory!( "", "test", - "test", FileDavCollection, FileDavResource); + "", FileDavCollection, FileDavResource); auto dav = new FileDav!T; auto res = T.Get(dav, URL("http://127.0.0.1/")); @@ -517,7 +538,7 @@ unittest { alias T = FileDavResourceFactory!( "", "test", - "test", FileDavCollection, FileDavResource); + "", FileDavCollection, FileDavResource); auto dav = new FileDav!T; auto res = T.CreateCollection(dav, URL("http://127.0.0.1/newCollection")); @@ -535,7 +556,7 @@ unittest { alias T = FileDavResourceFactory!( "", "test", - "test", FileDavCollection, FileDavResource); + "", FileDavCollection, FileDavResource); auto dav = new FileDav!T; auto res = T.CreateResource(dav, URL("http://127.0.0.1/newResource.txt")); diff --git a/source/vibedav/user.d b/source/vibedav/user.d index bf8ee89..f204424 100644 --- a/source/vibedav/user.d +++ b/source/vibedav/user.d @@ -44,8 +44,6 @@ interface IDavBaseUser { } } - - interface ICalDavUser : IDavBaseUser { @property pure {