Mercurial > hg > orthanc
comparison 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 |
comparison
equal
deleted
inserted
replaced
4227:7fff7e683d65 | 4228:c8c0bbaaace3 |
---|---|
21 | 21 |
22 | 22 |
23 #include "../PrecompiledHeaders.h" | 23 #include "../PrecompiledHeaders.h" |
24 #include "IWebDavBucket.h" | 24 #include "IWebDavBucket.h" |
25 | 25 |
26 #include "HttpOutput.h" | |
26 #include "../OrthancException.h" | 27 #include "../OrthancException.h" |
27 #include "../Toolbox.h" | 28 #include "../Toolbox.h" |
28 | 29 |
29 | 30 |
30 static boost::posix_time::ptime GetNow() | 31 static boost::posix_time::ptime GetNow() |
88 hasModificationTime_ = true; | 89 hasModificationTime_ = true; |
89 } | 90 } |
90 | 91 |
91 | 92 |
92 void IWebDavBucket::Resource::Format(pugi::xml_node& node, | 93 void IWebDavBucket::Resource::Format(pugi::xml_node& node, |
93 const std::string& parentPath) const | 94 const std::string& parentPath) const |
94 { | 95 { |
95 node.set_name("D:response"); | 96 node.set_name("D:response"); |
96 | 97 |
97 std::string s = AddTrailingSlash(parentPath) + GetName(); | 98 std::string s = AddTrailingSlash(parentPath) + GetName(); |
98 node.append_child("D:href").append_child(pugi::node_pcdata).set_value(s.c_str()); | 99 node.append_child("D:href").append_child(pugi::node_pcdata).set_value(s.c_str()); |
99 | 100 |
100 pugi::xml_node propstat = node.append_child("D:propstat"); | 101 pugi::xml_node propstat = node.append_child("D:propstat"); |
101 propstat.append_child("D:status").append_child(pugi::node_pcdata). | 102 |
102 set_value("HTTP/1.1 200 OK"); | 103 static const HttpStatus status = HttpStatus_200_Ok; |
104 s = ("HTTP/1.1 " + boost::lexical_cast<std::string>(status) + " " + | |
105 std::string(EnumerationToString(status))); | |
106 propstat.append_child("D:status").append_child(pugi::node_pcdata).set_value(s.c_str()); | |
103 | 107 |
104 pugi::xml_node prop = propstat.append_child("D:prop"); | 108 pugi::xml_node prop = propstat.append_child("D:prop"); |
105 | 109 |
106 // IMPORTANT: The "Z" suffix is mandatory on Windows >= 7 | 110 // IMPORTANT: The "Z" suffix is mandatory on Windows >= 7 |
107 s = boost::posix_time::to_iso_extended_string(GetCreationTime()) + "Z"; | 111 s = boost::posix_time::to_iso_extended_string(GetCreationTime()) + "Z"; |
108 prop.append_child("D:creationdate").append_child(pugi::node_pcdata).set_value(s.c_str()); | 112 prop.append_child("D:creationdate").append_child(pugi::node_pcdata).set_value(s.c_str()); |
109 | 113 |
110 s = boost::posix_time::to_iso_extended_string(GetModificationTime()) + "Z"; | 114 s = boost::posix_time::to_iso_extended_string(GetModificationTime()) + "Z"; |
111 prop.append_child("D:getlastmodified").append_child(pugi::node_pcdata).set_value(s.c_str()); | 115 prop.append_child("D:getlastmodified").append_child(pugi::node_pcdata).set_value(s.c_str()); |
112 | 116 |
117 #if 0 | |
118 // Maybe used by davfs2 | |
119 prop.append_child("D:quota-available-bytes"); | |
120 prop.append_child("D:quota-used-bytes"); | |
121 #endif | |
122 | |
113 #if 0 | 123 #if 0 |
114 prop.append_child("D:lockdiscovery"); | 124 prop.append_child("D:lockdiscovery"); |
115 pugi::xml_node lock = prop.append_child("D:supportedlock"); | 125 pugi::xml_node lock = prop.append_child("D:supportedlock"); |
116 | 126 |
117 pugi::xml_node lockentry = lock.append_child("D:lockentry"); | 127 pugi::xml_node lockentry = lock.append_child("D:lockentry"); |
215 decl.append_attribute("version").set_value("1.0"); | 225 decl.append_attribute("version").set_value("1.0"); |
216 decl.append_attribute("encoding").set_value("UTF-8"); | 226 decl.append_attribute("encoding").set_value("UTF-8"); |
217 | 227 |
218 Toolbox::XmlToString(target, doc); | 228 Toolbox::XmlToString(target, doc); |
219 } | 229 } |
230 | |
231 | |
232 void IWebDavBucket::AnswerFakedProppatch(HttpOutput& output, | |
233 const std::string& uri) | |
234 { | |
235 /** | |
236 * This is a fake implementation. The goal is to make happy the | |
237 * WebDAV clients that set properties (such as Windows >= 7). | |
238 **/ | |
239 | |
240 pugi::xml_document doc; | |
241 | |
242 pugi::xml_node root = doc.append_child("D:multistatus"); | |
243 root.append_attribute("xmlns:D").set_value("DAV:"); | |
244 | |
245 pugi::xml_node response = root.append_child("D:response"); | |
246 response.append_child("D:href").append_child(pugi::node_pcdata).set_value(uri.c_str()); | |
247 | |
248 response.append_child("D:propstat"); | |
249 | |
250 pugi::xml_node decl = doc.prepend_child(pugi::node_declaration); | |
251 decl.append_attribute("version").set_value("1.0"); | |
252 decl.append_attribute("encoding").set_value("UTF-8"); | |
253 | |
254 std::string s; | |
255 Toolbox::XmlToString(s, doc); | |
256 | |
257 output.AddHeader("Content-Type", "application/xml"); | |
258 output.SendStatus(HttpStatus_207_MultiStatus, s); | |
259 } | |
260 | |
261 | |
262 void IWebDavBucket::AnswerFakedLock(HttpOutput& output, | |
263 const std::string& uri) | |
264 { | |
265 /** | |
266 * This is a fake implementation. No lock is actually | |
267 * created. The goal is to make happy the WebDAV clients | |
268 * that use locking (such as Windows >= 7). | |
269 **/ | |
270 | |
271 pugi::xml_document doc; | |
272 | |
273 pugi::xml_node root = doc.append_child("D:prop"); | |
274 root.append_attribute("xmlns:D").set_value("DAV:"); | |
275 | |
276 pugi::xml_node activelock = root.append_child("D:lockdiscovery").append_child("D:activelock"); | |
277 activelock.append_child("D:locktype").append_child("D:write"); | |
278 activelock.append_child("D:lockscope").append_child("D:exclusive"); | |
279 activelock.append_child("D:depth").append_child(pugi::node_pcdata).set_value("0"); | |
280 activelock.append_child("D:timeout").append_child(pugi::node_pcdata).set_value("Second-3599"); | |
281 | |
282 activelock.append_child("D:lockroot").append_child("D:href") | |
283 .append_child(pugi::node_pcdata).set_value(uri.c_str()); | |
284 activelock.append_child("D:owner"); | |
285 | |
286 std::string token = Toolbox::GenerateUuid(); | |
287 boost::erase_all(token, "-"); | |
288 token = "opaquelocktoken:0x" + token; | |
289 | |
290 activelock.append_child("D:locktoken").append_child("D:href"). | |
291 append_child(pugi::node_pcdata).set_value(token.c_str()); | |
292 | |
293 pugi::xml_node decl = doc.prepend_child(pugi::node_declaration); | |
294 decl.append_attribute("version").set_value("1.0"); | |
295 decl.append_attribute("encoding").set_value("UTF-8"); | |
296 | |
297 std::string s; | |
298 Toolbox::XmlToString(s, doc); | |
299 | |
300 output.AddHeader("Lock-Token", token); // Necessary for davfs2 | |
301 output.AddHeader("Content-Type", "application/xml"); | |
302 output.SendStatus(HttpStatus_201_Created, s); | |
303 } | |
304 | |
305 | |
306 void IWebDavBucket::AnswerFakedUnlock(HttpOutput& output) | |
307 { | |
308 output.SendStatus(HttpStatus_204_NoContent); | |
309 } | |
220 } | 310 } |