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