Skip to content

Commit

Permalink
Added basic caldav support
Browse files Browse the repository at this point in the history
  • Loading branch information
gedaiu committed Apr 7, 2015
1 parent 0fb9440 commit e8a304e
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 32 deletions.
11 changes: 4 additions & 7 deletions source/vibedav/base.d
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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);

Expand Down
12 changes: 9 additions & 3 deletions source/vibedav/caldav.d
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class DavCalendarBaseResource : DavResource, ICalendarCollectionProperties, IDav

this(IDav dav, URL url, bool forceCreate = false) {
super(dav, url);

this.dav = dav;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.");
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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");
}
2 changes: 1 addition & 1 deletion source/vibedav/davresource.d
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ interface IDavResourceProperties {
@ResourceProperty("creationdate", "DAV:")
SysTime creationDate();

@ResourceProperty("lastmodified", "DAV:")
@ResourceProperty("getlastmodified", "DAV:")
SysTime lastModified();

@ResourceProperty("getetag", "DAV:")
Expand Down
59 changes: 40 additions & 19 deletions source/vibedav/filedav.d
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down Expand Up @@ -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.");
Expand All @@ -161,7 +175,7 @@ abstract class FileDavResourceBase : DavResource {
}

string[] resourceType() {
return ["collection:DAV:"];
return [];
}

override bool isCollection() {
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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";
}
}
}
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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/"));
Expand All @@ -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"));
Expand All @@ -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"));
Expand Down
2 changes: 0 additions & 2 deletions source/vibedav/user.d
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ interface IDavBaseUser {
}
}



interface ICalDavUser : IDavBaseUser {
@property pure {

Expand Down

0 comments on commit e8a304e

Please sign in to comment.