Mercurial > hg > orthanc
diff OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp @ 4228:c8c0bbaaace3
write access to webdav
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 06 Oct 2020 12:45:11 +0200 |
parents | 7bd5eab3ba25 |
children | b313a0001893 |
line wrap: on
line diff
--- a/OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp Mon Oct 05 10:55:24 2020 +0200 +++ b/OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp Tue Oct 06 12:45:11 2020 +0200 @@ -23,6 +23,7 @@ #include "../PrecompiledHeaders.h" #include "IWebDavBucket.h" +#include "HttpOutput.h" #include "../OrthancException.h" #include "../Toolbox.h" @@ -90,7 +91,7 @@ void IWebDavBucket::Resource::Format(pugi::xml_node& node, - const std::string& parentPath) const + const std::string& parentPath) const { node.set_name("D:response"); @@ -98,8 +99,11 @@ node.append_child("D:href").append_child(pugi::node_pcdata).set_value(s.c_str()); pugi::xml_node propstat = node.append_child("D:propstat"); - propstat.append_child("D:status").append_child(pugi::node_pcdata). - set_value("HTTP/1.1 200 OK"); + + static const HttpStatus status = HttpStatus_200_Ok; + s = ("HTTP/1.1 " + boost::lexical_cast<std::string>(status) + " " + + std::string(EnumerationToString(status))); + propstat.append_child("D:status").append_child(pugi::node_pcdata).set_value(s.c_str()); pugi::xml_node prop = propstat.append_child("D:prop"); @@ -111,6 +115,12 @@ prop.append_child("D:getlastmodified").append_child(pugi::node_pcdata).set_value(s.c_str()); #if 0 + // Maybe used by davfs2 + prop.append_child("D:quota-available-bytes"); + prop.append_child("D:quota-used-bytes"); +#endif + +#if 0 prop.append_child("D:lockdiscovery"); pugi::xml_node lock = prop.append_child("D:supportedlock"); @@ -217,4 +227,84 @@ Toolbox::XmlToString(target, doc); } + + + void IWebDavBucket::AnswerFakedProppatch(HttpOutput& output, + const std::string& uri) + { + /** + * This is a fake implementation. The goal is to make happy the + * WebDAV clients that set properties (such as Windows >= 7). + **/ + + pugi::xml_document doc; + + pugi::xml_node root = doc.append_child("D:multistatus"); + root.append_attribute("xmlns:D").set_value("DAV:"); + + pugi::xml_node response = root.append_child("D:response"); + response.append_child("D:href").append_child(pugi::node_pcdata).set_value(uri.c_str()); + + response.append_child("D:propstat"); + + pugi::xml_node decl = doc.prepend_child(pugi::node_declaration); + decl.append_attribute("version").set_value("1.0"); + decl.append_attribute("encoding").set_value("UTF-8"); + + std::string s; + Toolbox::XmlToString(s, doc); + + output.AddHeader("Content-Type", "application/xml"); + output.SendStatus(HttpStatus_207_MultiStatus, s); + } + + + void IWebDavBucket::AnswerFakedLock(HttpOutput& output, + const std::string& uri) + { + /** + * This is a fake implementation. No lock is actually + * created. The goal is to make happy the WebDAV clients + * that use locking (such as Windows >= 7). + **/ + + pugi::xml_document doc; + + pugi::xml_node root = doc.append_child("D:prop"); + root.append_attribute("xmlns:D").set_value("DAV:"); + + pugi::xml_node activelock = root.append_child("D:lockdiscovery").append_child("D:activelock"); + activelock.append_child("D:locktype").append_child("D:write"); + activelock.append_child("D:lockscope").append_child("D:exclusive"); + activelock.append_child("D:depth").append_child(pugi::node_pcdata).set_value("0"); + activelock.append_child("D:timeout").append_child(pugi::node_pcdata).set_value("Second-3599"); + + activelock.append_child("D:lockroot").append_child("D:href") + .append_child(pugi::node_pcdata).set_value(uri.c_str()); + activelock.append_child("D:owner"); + + std::string token = Toolbox::GenerateUuid(); + boost::erase_all(token, "-"); + token = "opaquelocktoken:0x" + token; + + activelock.append_child("D:locktoken").append_child("D:href"). + append_child(pugi::node_pcdata).set_value(token.c_str()); + + pugi::xml_node decl = doc.prepend_child(pugi::node_declaration); + decl.append_attribute("version").set_value("1.0"); + decl.append_attribute("encoding").set_value("UTF-8"); + + std::string s; + Toolbox::XmlToString(s, doc); + + output.AddHeader("Lock-Token", token); // Necessary for davfs2 + output.AddHeader("Content-Type", "application/xml"); + output.SendStatus(HttpStatus_201_Created, s); + } + + + void IWebDavBucket::AnswerFakedUnlock(HttpOutput& output) + { + output.SendStatus(HttpStatus_204_NoContent); + } }