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