Mercurial > hg > orthanc
annotate OrthancFramework/Sources/HttpServer/WebDavStorage.cpp @ 4252:f047e2734655
fix webdav
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 15 Oct 2020 17:13:35 +0200 |
parents | c8754c4c1862 |
children | 50b0c69b653a |
rev | line source |
---|---|
4230 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with this program. If not, see | |
19 * <http://www.gnu.org/licenses/>. | |
20 **/ | |
21 | |
22 | |
23 #include "../PrecompiledHeaders.h" | |
24 #include "WebDavStorage.h" | |
25 | |
26 #include "../OrthancException.h" | |
27 #include "../SystemToolbox.h" | |
28 #include "../TemporaryFile.h" | |
29 #include "../Toolbox.h" | |
30 | |
31 namespace Orthanc | |
32 { | |
33 class WebDavStorage::StorageFile : public boost::noncopyable | |
34 { | |
35 private: | |
36 std::unique_ptr<TemporaryFile> file_; | |
37 std::string content_; | |
38 MimeType mime_; | |
39 boost::posix_time::ptime time_; | |
40 | |
41 void Touch() | |
42 { | |
43 time_ = boost::posix_time::second_clock::universal_time(); | |
44 } | |
45 | |
46 public: | |
47 StorageFile() : | |
48 mime_(MimeType_Binary) | |
49 { | |
50 Touch(); | |
51 } | |
52 | |
53 void SetContent(const std::string& content, | |
54 MimeType mime, | |
55 bool isMemory) | |
56 { | |
57 if (isMemory) | |
58 { | |
59 content_ = content; | |
60 file_.reset(); | |
61 } | |
62 else | |
63 { | |
64 content_.clear(); | |
65 file_.reset(new TemporaryFile); | |
66 file_->Write(content); | |
67 } | |
68 | |
69 mime_ = mime; | |
70 Touch(); | |
71 } | |
72 | |
73 MimeType GetMimeType() const | |
74 { | |
75 return mime_; | |
76 } | |
77 | |
78 void GetContent(std::string& target) const | |
79 { | |
80 if (file_.get() == NULL) | |
81 { | |
82 target = content_; | |
83 } | |
84 else | |
85 { | |
86 file_->Read(target); | |
87 } | |
88 } | |
89 | |
90 const boost::posix_time::ptime& GetTime() const | |
91 { | |
92 return time_; | |
93 } | |
94 | |
95 uint64_t GetContentLength() const | |
96 { | |
97 if (file_.get() == NULL) | |
98 { | |
99 return content_.size(); | |
100 } | |
101 else | |
102 { | |
103 return file_->GetFileSize(); | |
104 } | |
105 } | |
106 }; | |
107 | |
108 | |
109 class WebDavStorage::StorageFolder : public boost::noncopyable | |
110 { | |
111 private: | |
112 typedef std::map<std::string, StorageFile*> Files; | |
113 typedef std::map<std::string, StorageFolder*> Subfolders; | |
114 | |
4233
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
115 Files files_; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
116 Subfolders subfolders_; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
117 boost::posix_time::ptime time_; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
118 |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
119 void Touch() |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
120 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
121 time_ = boost::posix_time::second_clock::universal_time(); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
122 } |
4230 | 123 |
124 void CheckName(const std::string& name) | |
125 { | |
126 if (name.empty() || | |
127 name.find('/') != std::string::npos || | |
128 name.find('\\') != std::string::npos || | |
129 name.find('\0') != std::string::npos) | |
130 { | |
131 throw OrthancException(ErrorCode_ParameterOutOfRange, | |
132 "Bad resource name for WebDAV: " + name); | |
133 } | |
134 } | |
135 | |
136 bool IsExisting(const std::string& name) const | |
137 { | |
138 return (files_.find(name) != files_.end() || | |
139 subfolders_.find(name) != subfolders_.end()); | |
140 } | |
141 | |
142 public: | |
4233
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
143 StorageFolder() |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
144 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
145 Touch(); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
146 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
147 |
4230 | 148 ~StorageFolder() |
149 { | |
150 for (Files::iterator it = files_.begin(); it != files_.end(); ++it) | |
151 { | |
152 assert(it->second != NULL); | |
153 delete it->second; | |
154 } | |
155 | |
156 for (Subfolders::iterator it = subfolders_.begin(); it != subfolders_.end(); ++it) | |
157 { | |
158 assert(it->second != NULL); | |
159 delete it->second; | |
160 } | |
161 } | |
162 | |
4239
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
163 size_t GetSize() const |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
164 { |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
165 return files_.size() + subfolders_.size(); |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
166 } |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
167 |
4233
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
168 const boost::posix_time::ptime& GetModificationTime() const |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
169 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
170 return time_; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
171 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
172 |
4230 | 173 const StorageFile* LookupFile(const std::string& name) const |
174 { | |
175 Files::const_iterator found = files_.find(name); | |
176 if (found == files_.end()) | |
177 { | |
178 return NULL; | |
179 } | |
180 else | |
181 { | |
182 assert(found->second != NULL); | |
183 return found->second; | |
184 } | |
185 } | |
186 | |
187 bool CreateSubfolder(const std::string& name) | |
188 { | |
189 CheckName(name); | |
190 | |
191 if (IsExisting(name)) | |
192 { | |
193 LOG(ERROR) << "WebDAV folder already existing: " << name; | |
194 return false; | |
195 } | |
196 else | |
197 { | |
198 subfolders_[name] = new StorageFolder; | |
4233
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
199 Touch(); |
4230 | 200 return true; |
201 } | |
202 } | |
203 | |
204 bool StoreFile(const std::string& name, | |
205 const std::string& content, | |
206 MimeType mime, | |
207 bool isMemory) | |
208 { | |
209 CheckName(name); | |
210 | |
211 if (subfolders_.find(name) != subfolders_.end()) | |
212 { | |
213 LOG(ERROR) << "WebDAV folder already existing: " << name; | |
214 return false; | |
215 } | |
216 | |
217 Files::iterator found = files_.find(name); | |
218 if (found == files_.end()) | |
219 { | |
220 std::unique_ptr<StorageFile> f(new StorageFile); | |
221 f->SetContent(content, mime, isMemory); | |
222 files_[name] = f.release(); | |
223 } | |
224 else | |
225 { | |
226 assert(found->second != NULL); | |
227 found->second->SetContent(content, mime, isMemory); | |
228 } | |
229 | |
4233
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
230 Touch(); |
4230 | 231 return true; |
232 } | |
233 | |
234 StorageFolder* LookupFolder(const std::vector<std::string>& path) | |
235 { | |
236 if (path.empty()) | |
237 { | |
238 return this; | |
239 } | |
240 else | |
241 { | |
242 Subfolders::const_iterator found = subfolders_.find(path[0]); | |
243 if (found == subfolders_.end()) | |
244 { | |
245 return NULL; | |
246 } | |
247 else | |
248 { | |
249 assert(found->second != NULL); | |
250 | |
251 std::vector<std::string> p(path.begin() + 1, path.end()); | |
252 return found->second->LookupFolder(p); | |
253 } | |
254 } | |
255 } | |
256 | |
257 void ListCollection(Collection& collection) const | |
258 { | |
259 for (Files::const_iterator it = files_.begin(); it != files_.end(); ++it) | |
260 { | |
261 assert(it->second != NULL); | |
262 | |
263 std::unique_ptr<File> f(new File(it->first)); | |
264 f->SetContentLength(it->second->GetContentLength()); | |
265 f->SetCreationTime(it->second->GetTime()); | |
266 collection.AddResource(f.release()); | |
267 } | |
268 | |
269 for (Subfolders::const_iterator it = subfolders_.begin(); it != subfolders_.end(); ++it) | |
270 { | |
4233
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
271 std::unique_ptr<Folder> f(new Folder(it->first)); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
272 f->SetModificationTime(it->second->GetModificationTime()); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
273 collection.AddResource(f.release()); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
274 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
275 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
276 |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
277 bool DeleteItem(const std::vector<std::string>& path) |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
278 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
279 if (path.size() == 0) |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
280 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
281 throw OrthancException(ErrorCode_InternalError); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
282 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
283 else if (path.size() == 1) |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
284 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
285 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
286 Files::iterator f = files_.find(path[0]); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
287 if (f != files_.end()) |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
288 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
289 assert(f->second != NULL); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
290 delete f->second; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
291 files_.erase(f); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
292 Touch(); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
293 return true; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
294 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
295 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
296 |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
297 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
298 Subfolders::iterator f = subfolders_.find(path[0]); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
299 if (f != subfolders_.end()) |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
300 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
301 assert(f->second != NULL); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
302 delete f->second; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
303 subfolders_.erase(f); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
304 Touch(); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
305 return true; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
306 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
307 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
308 |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
309 return false; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
310 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
311 else |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
312 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
313 Subfolders::iterator f = subfolders_.find(path[0]); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
314 if (f != subfolders_.end()) |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
315 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
316 assert(f->second != NULL); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
317 |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
318 std::vector<std::string> p(path.begin() + 1, path.end()); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
319 if (f->second->DeleteItem(p)) |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
320 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
321 Touch(); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
322 return true; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
323 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
324 else |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
325 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
326 return false; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
327 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
328 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
329 else |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
330 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
331 return false; |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
332 } |
4230 | 333 } |
334 } | |
4239
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
335 |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
336 |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
337 void RemoveEmptyFolders() |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
338 { |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
339 std::list<std::string> emptyFolders; |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
340 |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
341 for (Subfolders::const_iterator it = subfolders_.begin(); it != subfolders_.end(); ++it) |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
342 { |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
343 assert(it->second != NULL); |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
344 it->second->RemoveEmptyFolders(); |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
345 |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
346 if (it->second->GetSize() == 0) |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
347 { |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
348 assert(it->second != NULL); |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
349 delete it->second; |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
350 |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
351 emptyFolders.push_back(it->first); |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
352 } |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
353 } |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
354 |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
355 for (std::list<std::string>::const_iterator it = emptyFolders.begin(); |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
356 it != emptyFolders.end(); ++it) |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
357 { |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
358 assert(subfolders_.find(*it) != subfolders_.end()); |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
359 subfolders_.erase(*it); |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
360 } |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
361 } |
4230 | 362 }; |
363 | |
364 | |
365 WebDavStorage::StorageFolder* WebDavStorage::LookupParentFolder(const std::vector<std::string>& path) | |
366 { | |
367 if (path.empty()) | |
368 { | |
369 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
370 } | |
371 | |
372 std::vector<std::string> p(path.begin(), path.end() - 1); | |
373 return root_->LookupFolder(p); | |
374 } | |
375 | |
376 | |
377 WebDavStorage::WebDavStorage(bool isMemory) : | |
378 root_(new StorageFolder), | |
379 isMemory_(isMemory) | |
380 { | |
381 } | |
382 | |
383 | |
384 bool WebDavStorage::IsExistingFolder(const std::vector<std::string>& path) | |
385 { | |
386 boost::recursive_mutex::scoped_lock lock(mutex_); | |
387 | |
388 return (root_->LookupFolder(path) != NULL); | |
389 } | |
390 | |
391 | |
392 bool WebDavStorage::ListCollection(Collection& collection, | |
393 const std::vector<std::string>& path) | |
394 { | |
395 boost::recursive_mutex::scoped_lock lock(mutex_); | |
396 | |
397 const StorageFolder* folder = root_->LookupFolder(path); | |
398 if (folder == NULL) | |
399 { | |
400 return false; | |
401 } | |
402 else | |
403 { | |
404 folder->ListCollection(collection); | |
405 return true; | |
406 } | |
407 } | |
408 | |
409 | |
410 bool WebDavStorage::GetFileContent(MimeType& mime, | |
411 std::string& content, | |
412 boost::posix_time::ptime& modificationTime, | |
413 const std::vector<std::string>& path) | |
414 { | |
415 boost::recursive_mutex::scoped_lock lock(mutex_); | |
416 | |
417 const StorageFolder* folder = LookupParentFolder(path); | |
418 if (folder == NULL) | |
419 { | |
420 return false; | |
421 } | |
422 else | |
423 { | |
424 const StorageFile* file = folder->LookupFile(path.back()); | |
425 if (file == NULL) | |
426 { | |
427 return false; | |
428 } | |
429 else | |
430 { | |
431 mime = file->GetMimeType(); | |
432 file->GetContent(content); | |
433 modificationTime = file->GetTime(); | |
434 return true; | |
435 } | |
436 } | |
437 } | |
438 | |
439 | |
440 bool WebDavStorage::StoreFile(const std::string& content, | |
441 const std::vector<std::string>& path) | |
442 { | |
443 boost::recursive_mutex::scoped_lock lock(mutex_); | |
444 | |
445 StorageFolder* folder = LookupParentFolder(path); | |
446 if (folder == NULL) | |
447 { | |
448 LOG(WARNING) << "Inexisting folder in WebDAV: " << Toolbox::FlattenUri(path); | |
449 return false; | |
450 } | |
451 else | |
452 { | |
453 LOG(INFO) << "Storing " << content.size() | |
454 << " bytes in WebDAV bucket: " << Toolbox::FlattenUri(path);; | |
455 | |
456 MimeType mime = SystemToolbox::AutodetectMimeType(path.back()); | |
457 return folder->StoreFile(path.back(), content, mime, isMemory_); | |
458 } | |
459 } | |
460 | |
461 | |
462 bool WebDavStorage::CreateFolder(const std::vector<std::string>& path) | |
463 { | |
464 boost::recursive_mutex::scoped_lock lock(mutex_); | |
465 | |
466 StorageFolder* folder = LookupParentFolder(path); | |
467 if (folder == NULL) | |
468 { | |
469 LOG(WARNING) << "Inexisting folder in WebDAV: " << Toolbox::FlattenUri(path); | |
470 return false; | |
471 } | |
472 else | |
473 { | |
474 LOG(INFO) << "Creating folder in WebDAV bucket: " << Toolbox::FlattenUri(path); | |
475 return folder->CreateSubfolder(path.back()); | |
476 } | |
477 } | |
4232
688435755466
added DELETE in WebDAV, first working virtual filesystem
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4230
diff
changeset
|
478 |
688435755466
added DELETE in WebDAV, first working virtual filesystem
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4230
diff
changeset
|
479 |
688435755466
added DELETE in WebDAV, first working virtual filesystem
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4230
diff
changeset
|
480 bool WebDavStorage::DeleteItem(const std::vector<std::string>& path) |
688435755466
added DELETE in WebDAV, first working virtual filesystem
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4230
diff
changeset
|
481 { |
4233
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
482 if (path.empty()) |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
483 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
484 return false; // Cannot delete the root |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
485 } |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
486 else |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
487 { |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
488 boost::recursive_mutex::scoped_lock lock(mutex_); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
489 |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
490 LOG(INFO) << "Deleting from WebDAV bucket: " << Toolbox::FlattenUri(path); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
491 return root_->DeleteItem(path); |
ca2a55a62c81
implementation of DELETE in class WebDavStorage
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4232
diff
changeset
|
492 } |
4232
688435755466
added DELETE in WebDAV, first working virtual filesystem
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4230
diff
changeset
|
493 } |
4239
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
494 |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
495 |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
496 void WebDavStorage::RemoveEmptyFolders() |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
497 { |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
498 boost::recursive_mutex::scoped_lock lock(mutex_); |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
499 root_->RemoveEmptyFolders(); |
c8754c4c1862
upload DICOM using WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4233
diff
changeset
|
500 } |
4230 | 501 } |