Mercurial > hg > orthanc
comparison OrthancFramework/Sources/HttpServer/IWebDavBucket.cpp @ 4246:6c3721ff284c
simplification
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 13 Oct 2020 10:39:47 +0200 |
parents | a38376b80cd1 |
children | 112951171852 |
comparison
equal
deleted
inserted
replaced
4245:c70df925151e | 4246:6c3721ff284c |
---|---|
72 } | 72 } |
73 | 73 |
74 | 74 |
75 void IWebDavBucket::Resource::SetCreationTime(const boost::posix_time::ptime& t) | 75 void IWebDavBucket::Resource::SetCreationTime(const boost::posix_time::ptime& t) |
76 { | 76 { |
77 creationTime_ = t; | 77 if (t.is_special()) |
78 | 78 { |
79 if (!hasModificationTime_) | 79 throw OrthancException(ErrorCode_ParameterOutOfRange, "Not a valid date-time"); |
80 } | |
81 else | |
82 { | |
83 creationTime_ = t; | |
84 | |
85 if (!hasModificationTime_) | |
86 { | |
87 modificationTime_ = t; | |
88 } | |
89 } | |
90 } | |
91 | |
92 | |
93 void IWebDavBucket::Resource::SetModificationTime(const boost::posix_time::ptime& t) | |
94 { | |
95 if (t.is_special()) | |
96 { | |
97 throw OrthancException(ErrorCode_ParameterOutOfRange, "Not a valid date-time"); | |
98 } | |
99 else | |
80 { | 100 { |
81 modificationTime_ = t; | 101 modificationTime_ = t; |
82 } | 102 hasModificationTime_ = true; |
83 } | 103 } |
84 | 104 } |
85 | 105 |
86 void IWebDavBucket::Resource::SetModificationTime(const boost::posix_time::ptime& t) | 106 |
87 { | 107 static void FormatInternal(pugi::xml_node& node, |
88 modificationTime_ = t; | 108 const std::string& href, |
89 hasModificationTime_ = true; | 109 const std::string& displayName, |
90 } | 110 const boost::posix_time::ptime& creationTime, |
91 | 111 const boost::posix_time::ptime& modificationTime) |
92 | |
93 void IWebDavBucket::Resource::Format(pugi::xml_node& node, | |
94 const std::string& parentPath, | |
95 bool includeDisplayName) const | |
96 { | 112 { |
97 node.set_name("D:response"); | 113 node.set_name("D:response"); |
98 | 114 |
99 std::string s; | 115 node.append_child("D:href").append_child(pugi::node_pcdata).set_value(href.c_str()); |
100 Toolbox::UriEncode(s, AddTrailingSlash(parentPath) + GetName()); | |
101 node.append_child("D:href").append_child(pugi::node_pcdata).set_value(s.c_str()); | |
102 | 116 |
103 pugi::xml_node propstat = node.append_child("D:propstat"); | 117 pugi::xml_node propstat = node.append_child("D:propstat"); |
104 | 118 |
105 static const HttpStatus status = HttpStatus_200_Ok; | 119 static const HttpStatus status = HttpStatus_200_Ok; |
106 s = ("HTTP/1.1 " + boost::lexical_cast<std::string>(status) + " " + | 120 std::string s = ("HTTP/1.1 " + boost::lexical_cast<std::string>(status) + " " + |
107 std::string(EnumerationToString(status))); | 121 std::string(EnumerationToString(status))); |
108 propstat.append_child("D:status").append_child(pugi::node_pcdata).set_value(s.c_str()); | 122 propstat.append_child("D:status").append_child(pugi::node_pcdata).set_value(s.c_str()); |
109 | 123 |
110 pugi::xml_node prop = propstat.append_child("D:prop"); | 124 pugi::xml_node prop = propstat.append_child("D:prop"); |
125 prop.append_child("D:displayname").append_child(pugi::node_pcdata).set_value(displayName.c_str()); | |
111 | 126 |
112 // IMPORTANT: The "Z" suffix is mandatory on Windows >= 7 (it indicates UTC) | 127 // IMPORTANT: The "Z" suffix is mandatory on Windows >= 7 (it indicates UTC) |
113 s = boost::posix_time::to_iso_extended_string(GetCreationTime()) + "Z"; | 128 s = boost::posix_time::to_iso_extended_string(creationTime) + "Z"; |
114 prop.append_child("D:creationdate").append_child(pugi::node_pcdata).set_value(s.c_str()); | 129 prop.append_child("D:creationdate").append_child(pugi::node_pcdata).set_value(s.c_str()); |
115 | 130 |
116 s = boost::posix_time::to_iso_extended_string(GetModificationTime()) + "Z"; | 131 s = boost::posix_time::to_iso_extended_string(modificationTime) + "Z"; |
117 prop.append_child("D:getlastmodified").append_child(pugi::node_pcdata).set_value(s.c_str()); | 132 prop.append_child("D:getlastmodified").append_child(pugi::node_pcdata).set_value(s.c_str()); |
118 | 133 |
119 #if 0 | 134 #if 0 |
120 // Maybe used by davfs2 | 135 // Maybe used by davfs2 |
121 prop.append_child("D:quota-available-bytes"); | 136 prop.append_child("D:quota-available-bytes"); |
134 lockentry.append_child("D:lockscope").append_child("D:shared"); | 149 lockentry.append_child("D:lockscope").append_child("D:shared"); |
135 lockentry.append_child("D:locktype").append_child("D:write"); | 150 lockentry.append_child("D:locktype").append_child("D:write"); |
136 #endif | 151 #endif |
137 } | 152 } |
138 | 153 |
139 | 154 |
140 IWebDavBucket::File::File(const std::string& name) : | 155 IWebDavBucket::File::File(const std::string& name) : |
141 contentLength_(0), | 156 contentLength_(0), |
142 mime_(MimeType_Binary) | 157 mime_(MimeType_Binary) |
143 { | 158 { |
144 if (name.empty()) | 159 if (name.empty()) |
150 SetNameInternal(name); | 165 SetNameInternal(name); |
151 } | 166 } |
152 | 167 |
153 | 168 |
154 void IWebDavBucket::File::Format(pugi::xml_node& node, | 169 void IWebDavBucket::File::Format(pugi::xml_node& node, |
155 const std::string& parentPath, | 170 const std::string& parentPath) const |
156 bool includeDisplayName) const | 171 { |
157 { | 172 std::string href; |
158 Resource::Format(node, parentPath, includeDisplayName); | 173 Toolbox::UriEncode(href, AddTrailingSlash(parentPath) + GetName()); |
174 FormatInternal(node, href, GetName(), GetCreationTime(), GetModificationTime()); | |
159 | 175 |
160 pugi::xml_node prop = node.first_element_by_path("D:propstat/D:prop"); | 176 pugi::xml_node prop = node.first_element_by_path("D:propstat/D:prop"); |
161 prop.append_child("D:resourcetype"); | 177 prop.append_child("D:resourcetype"); |
162 | 178 |
163 std::string s = boost::lexical_cast<std::string>(contentLength_); | 179 std::string s = boost::lexical_cast<std::string>(contentLength_); |
164 prop.append_child("D:getcontentlength").append_child(pugi::node_pcdata).set_value(s.c_str()); | 180 prop.append_child("D:getcontentlength").append_child(pugi::node_pcdata).set_value(s.c_str()); |
165 | 181 |
166 s = EnumerationToString(mime_); | 182 s = EnumerationToString(mime_); |
167 prop.append_child("D:getcontenttype").append_child(pugi::node_pcdata).set_value(s.c_str()); | 183 prop.append_child("D:getcontenttype").append_child(pugi::node_pcdata).set_value(s.c_str()); |
168 | |
169 prop.append_child("D:displayname").append_child(pugi::node_pcdata).set_value(GetName().c_str()); | |
170 } | 184 } |
171 | 185 |
172 | 186 |
173 void IWebDavBucket::Folder::Format(pugi::xml_node& node, | 187 void IWebDavBucket::Folder::Format(pugi::xml_node& node, |
174 const std::string& parentPath, | 188 const std::string& parentPath) const |
175 bool includeDisplayName) const | 189 { |
176 { | 190 std::string href; |
177 Resource::Format(node, parentPath, includeDisplayName); | 191 Toolbox::UriEncode(href, AddTrailingSlash(parentPath) + GetName()); |
192 FormatInternal(node, href, GetName(), GetCreationTime(), GetModificationTime()); | |
178 | 193 |
179 pugi::xml_node prop = node.first_element_by_path("D:propstat/D:prop"); | 194 pugi::xml_node prop = node.first_element_by_path("D:propstat/D:prop"); |
180 prop.append_child("D:resourcetype").append_child("D:collection"); | 195 prop.append_child("D:resourcetype").append_child("D:collection"); |
181 | 196 |
182 //prop.append_child("D:getcontenttype").append_child(pugi::node_pcdata).set_value("httpd/unix-directory"); | 197 //prop.append_child("D:getcontenttype").append_child(pugi::node_pcdata).set_value("httpd/unix-directory"); |
183 | |
184 prop.append_child("D:displayname").append_child(pugi::node_pcdata).set_value(GetName().c_str()); | |
185 } | 198 } |
186 | 199 |
187 | 200 |
188 IWebDavBucket::Collection::~Collection() | 201 IWebDavBucket::Collection::~Collection() |
189 { | 202 { |
207 } | 220 } |
208 } | 221 } |
209 | 222 |
210 | 223 |
211 void IWebDavBucket::Collection::Format(std::string& target, | 224 void IWebDavBucket::Collection::Format(std::string& target, |
212 const std::string& parentPath, | 225 const std::string& parentPath) const |
213 bool includeDisplayName) const | |
214 { | 226 { |
215 pugi::xml_document doc; | 227 pugi::xml_document doc; |
216 | 228 |
217 pugi::xml_node root = doc.append_child("D:multistatus"); | 229 pugi::xml_node root = doc.append_child("D:multistatus"); |
218 root.append_attribute("xmlns:D").set_value("DAV:"); | 230 root.append_attribute("xmlns:D").set_value("DAV:"); |
219 | 231 |
232 { | |
233 pugi::xml_node self = root.append_child(); | |
234 | |
235 std::string folder; | |
236 size_t lastSlash = parentPath.rfind('/'); | |
237 if (lastSlash == std::string::npos) | |
238 { | |
239 folder = parentPath; | |
240 } | |
241 else | |
242 { | |
243 folder = parentPath.substr(lastSlash + 1); | |
244 } | |
245 | |
246 std::string href; | |
247 Toolbox::UriEncode(href, AddTrailingSlash(parentPath)); | |
248 FormatInternal(self, href, folder, GetNow(), GetNow()); | |
249 | |
250 pugi::xml_node prop = self.first_element_by_path("D:propstat/D:prop"); | |
251 prop.append_child("D:resourcetype").append_child("D:collection"); | |
252 } | |
253 | |
220 for (std::list<Resource*>::const_iterator | 254 for (std::list<Resource*>::const_iterator |
221 it = resources_.begin(); it != resources_.end(); ++it) | 255 it = resources_.begin(); it != resources_.end(); ++it) |
222 { | 256 { |
223 assert(*it != NULL); | 257 assert(*it != NULL); |
224 pugi::xml_node n = root.append_child(); | 258 pugi::xml_node n = root.append_child(); |
225 (*it)->Format(n, parentPath, includeDisplayName); | 259 (*it)->Format(n, parentPath); |
226 } | 260 } |
227 | 261 |
228 pugi::xml_node decl = doc.prepend_child(pugi::node_declaration); | 262 pugi::xml_node decl = doc.prepend_child(pugi::node_declaration); |
229 decl.append_attribute("version").set_value("1.0"); | 263 decl.append_attribute("version").set_value("1.0"); |
230 decl.append_attribute("encoding").set_value("UTF-8"); | 264 decl.append_attribute("encoding").set_value("UTF-8"); |