# HG changeset patch # User Sebastien Jodogne # Date 1602259824 -7200 # Node ID 64f57c9d5f7939f0f294e141417eef54b87b7931 # Parent 5cfa6ba75dfc73f63c045cb155b64e0be2892d40 configuration options for webdav diff -r 5cfa6ba75dfc -r 64f57c9d5f79 OrthancServer/Resources/Configuration.json --- a/OrthancServer/Resources/Configuration.json Fri Oct 09 17:51:06 2020 +0200 +++ b/OrthancServer/Resources/Configuration.json Fri Oct 09 18:10:24 2020 +0200 @@ -85,6 +85,18 @@ // supports the "gzip" and "deflate" HTTP encodings. "HttpCompressionEnabled" : true, + // Enable the publication of the content of the Orthanc server as a + // WebDAV share (new in Orthanc 1.8.0). On the localhost, the WebDAV + // share is mapped as "http://localhost:8042/webdav/". + "WebDavEnabled" : true, + + // Whether to allow deletions through the WebDAV share. This is + // disabled by default to avoid accidental loss of DICOM instances. + "WebDavDeleteAllowed" : false, + + // Whether to allow uploads through the WebDAV share. + "WebDavUploadAllowed" : true, + /** diff -r 5cfa6ba75dfc -r 64f57c9d5f79 OrthancServer/Sources/OrthancWebDav.cpp --- a/OrthancServer/Sources/OrthancWebDav.cpp Fri Oct 09 17:51:06 2020 +0200 +++ b/OrthancServer/Sources/OrthancWebDav.cpp Fri Oct 09 18:10:24 2020 +0200 @@ -1191,7 +1191,7 @@ boost::posix_time::ptime lastModification = GetNow(); - while (that->running_) + while (that->uploadRunning_) { std::unique_ptr obj(that->uploadQueue_.Dequeue(100)); if (obj.get() != NULL) @@ -1223,7 +1223,7 @@ if (uploads_.GetFileContent(mime, content, time, uri)) { DicomInstanceToStore instance; - // instance.SetOrigin(DicomInstanceOrigin_WebDav); + // instance.SetOrigin(DicomInstanceOrigin_WebDav); // TODO instance.SetBuffer(content.c_str(), content.size()); std::string publicId; @@ -1264,11 +1264,13 @@ OrthancWebDav::OrthancWebDav(ServerContext& context, - bool allowDicomDelete) : + bool allowDicomDelete, + bool allowUpload) : context_(context), allowDicomDelete_(allowDicomDelete), + allowUpload_(allowUpload), uploads_(false /* store uploads as temporary files */), - running_(false) + uploadRunning_(false) { patientsTemplates_[ResourceType_Patient] = "{{PatientID}} - {{PatientName}}"; patientsTemplates_[ResourceType_Study] = "{{StudyDate}} - {{StudyDescription}}"; @@ -1301,7 +1303,8 @@ IWebDavBucket::Collection tmp; return GetRootNode(path[0]).ListCollection(tmp, UriComponents(path.begin() + 1, path.end())); } - else if (path[0] == UPLOADS) + else if (allowUpload_ && + path[0] == UPLOADS) { return uploads_.IsExistingFolder(UriComponents(path.begin() + 1, path.end())); } @@ -1321,7 +1324,12 @@ collection.AddResource(new Folder(BY_PATIENTS)); collection.AddResource(new Folder(BY_STUDIES)); collection.AddResource(new Folder(BY_UIDS)); - collection.AddResource(new Folder(UPLOADS)); + + if (allowUpload_) + { + collection.AddResource(new Folder(UPLOADS)); + } + return true; } else if (path[0] == BY_UIDS) @@ -1333,7 +1341,7 @@ if (path.size() == 1) { level = ResourceType_Study; - limit = 100; // TODO + limit = 0; // TODO - Should we limit here? } else if (path.size() == 2) { @@ -1369,7 +1377,8 @@ { return GetRootNode(path[0]).ListCollection(collection, UriComponents(path.begin() + 1, path.end())); } - else if (path[0] == UPLOADS) + else if (allowUpload_ && + path[0] == UPLOADS) { return uploads_.ListCollection(collection, UriComponents(path.begin() + 1, path.end())); } @@ -1449,7 +1458,8 @@ { return GetRootNode(path[0]).GetFileContent(mime, content, modificationTime, UriComponents(path.begin() + 1, path.end())); } - else if (path[0] == UPLOADS) + else if (allowUpload_ && + path[0] == UPLOADS) { return uploads_.GetFileContent(mime, content, modificationTime, UriComponents(path.begin() + 1, path.end())); } @@ -1463,7 +1473,8 @@ bool OrthancWebDav::StoreFile(const std::string& content, const UriComponents& path) { - if (path.size() >= 1 && + if (allowUpload_ && + path.size() >= 1 && path[0] == UPLOADS) { UriComponents subpath(UriComponents(path.begin() + 1, path.end())); @@ -1490,7 +1501,8 @@ bool OrthancWebDav::CreateFolder(const UriComponents& path) { - if (path.size() >= 1 && + if (allowUpload_ && + path.size() >= 1 && path[0] == UPLOADS) { return uploads_.CreateFolder(UriComponents(path.begin() + 1, path.end())); @@ -1553,8 +1565,6 @@ } } - std::cout << "\n\n" << query.Format() << "\n\n"; - DicomDeleteVisitor visitor(context_, level); context_.Apply(visitor, query, ResourceType_Instance, 0 /* since */, 0 /* no limit */); return true; @@ -1577,7 +1587,8 @@ return false; // read-only } } - else if (path[0] == UPLOADS) + else if (allowUpload_ && + path[0] == UPLOADS) { return uploads_.DeleteItem(UriComponents(path.begin() + 1, path.end())); } @@ -1590,14 +1601,14 @@ void OrthancWebDav::Start() { - if (running_) + if (uploadRunning_) { throw OrthancException(ErrorCode_BadSequenceOfCalls); } - else + else if (allowUpload_) { LOG(INFO) << "Starting the WebDAV upload thread"; - running_ = true; + uploadRunning_ = true; uploadThread_ = boost::thread(UploadWorker, this); } } @@ -1605,10 +1616,10 @@ void OrthancWebDav::Stop() { - if (running_) + if (uploadRunning_) { LOG(INFO) << "Stopping the WebDAV upload thread"; - running_ = false; + uploadRunning_ = false; if (uploadThread_.joinable()) { uploadThread_.join(); diff -r 5cfa6ba75dfc -r 64f57c9d5f79 OrthancServer/Sources/OrthancWebDav.h --- a/OrthancServer/Sources/OrthancWebDav.h Fri Oct 09 17:51:06 2020 +0200 +++ b/OrthancServer/Sources/OrthancWebDav.h Fri Oct 09 18:10:24 2020 +0200 @@ -92,6 +92,7 @@ ServerContext& context_; bool allowDicomDelete_; + bool allowUpload_; std::unique_ptr patients_; std::unique_ptr studies_; std::unique_ptr dates_; @@ -100,11 +101,12 @@ WebDavStorage uploads_; SharedMessageQueue uploadQueue_; boost::thread uploadThread_; - bool running_; + bool uploadRunning_; public: OrthancWebDav(ServerContext& context, - bool allowDicomDelete); + bool allowDicomDelete, + bool allowUpload); virtual ~OrthancWebDav() { diff -r 5cfa6ba75dfc -r 64f57c9d5f79 OrthancServer/Sources/main.cpp --- a/OrthancServer/Sources/main.cpp Fri Oct 09 17:51:06 2020 +0200 +++ b/OrthancServer/Sources/main.cpp Fri Oct 09 18:10:24 2020 +0200 @@ -1041,6 +1041,16 @@ context.SetExecuteLuaEnabled(false); LOG(WARNING) << "Remote LUA script execution is disabled"; } + + if (lock.GetConfiguration().GetBooleanParameter("WebDavEnabled", true)) + { + const bool allowDelete = lock.GetConfiguration().GetBooleanParameter("WebDavDeleteAllowed", false); + const bool allowUpload = lock.GetConfiguration().GetBooleanParameter("WebDavUploadAllowed", true); + + UriComponents root; + root.push_back("webdav"); + httpServer.Register(root, new OrthancWebDav(context, allowDelete, allowUpload)); + } } MyHttpExceptionFormatter exceptionFormatter(httpDescribeErrors, plugins); @@ -1049,13 +1059,6 @@ httpServer.SetHttpExceptionFormatter(exceptionFormatter); httpServer.Register(context.GetHttpHandler()); - { - UriComponents root; // TODO - root.push_back("a"); - root.push_back("b"); - httpServer.Register(root, new OrthancWebDav(context, true /* allow delete */)); - } - if (httpServer.GetPortNumber() < 1024) { LOG(WARNING) << "The HTTP port is privileged ("