Mercurial > hg > orthanc
changeset 1589:334d3a92ed83
improvements to the ServeFolders plugin
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 26 Aug 2015 17:43:00 +0200 |
parents | b5bc87a7212d |
children | ba0226474e22 |
files | CMakeLists.txt Core/Toolbox.cpp Plugins/Samples/ServeFolders/Plugin.cpp Resources/ErrorCodes.json |
diffstat | 4 files changed, 146 insertions(+), 56 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Wed Aug 26 16:49:46 2015 +0200 +++ b/CMakeLists.txt Wed Aug 26 17:43:00 2015 +0200 @@ -29,6 +29,7 @@ SET(ENABLE_JPEG ON CACHE BOOL "Enable JPEG decompression") SET(ENABLE_JPEG_LOSSLESS ON CACHE BOOL "Enable JPEG-LS (Lossless) decompression") SET(ENABLE_PLUGINS ON CACHE BOOL "Enable plugins") +SET(BUILD_SERVE_FOLDERS ON CACHE BOOL "Build the ServeFolders plugin") # Advanced parameters to fine-tune linking against system libraries SET(USE_SYSTEM_JSONCPP ON CACHE BOOL "Use the system version of JsonCpp") @@ -221,10 +222,6 @@ list(APPEND ORTHANC_UNIT_TESTS_SOURCES UnitTestsSources/PluginsTests.cpp ) - - set(SERVE_FOLDERS_SOURCES - Plugins/Samples/ServeFolders/Plugin.cpp - ) endif() @@ -328,20 +325,7 @@ message(FATAL_ERROR "Error while computing the version information: ${Failure}") endif() - execute_process( - COMMAND - ${PYTHON_EXECUTABLE} ${ORTHANC_ROOT}/Resources/WindowsResources.py - ${ORTHANC_VERSION} ServeFolders ServeFolders.dll "Orthanc plugin to serve additional folders" - ERROR_VARIABLE Failure - OUTPUT_FILE ${AUTOGENERATED_DIR}/ServeFolders.rc - ) - - if (Failure) - message(FATAL_ERROR "Error while computing the version information: ${Failure}") - endif() - list(APPEND ORTHANC_RESOURCES ${AUTOGENERATED_DIR}/Orthanc.rc) - list(APPEND SERVE_FOLDERS_SOURCES ${AUTOGENERATED_DIR}/ServeFolders.rc) endif() @@ -464,15 +448,28 @@ ## Build the "ServeFolders" plugin ##################################################################### -if (ENABLE_PLUGINS) +if (ENABLE_PLUGINS AND BUILD_SERVE_FOLDERS) + execute_process( + COMMAND + ${PYTHON_EXECUTABLE} ${ORTHANC_ROOT}/Resources/WindowsResources.py + ${ORTHANC_VERSION} ServeFolders ServeFolders.dll "Orthanc plugin to serve additional folders" + ERROR_VARIABLE Failure + OUTPUT_FILE ${AUTOGENERATED_DIR}/ServeFolders.rc + ) + + if (Failure) + message(FATAL_ERROR "Error while computing the version information: ${Failure}") + endif() + add_definitions(-DSERVE_FOLDERS_VERSION="${ORTHANC_VERSION}") include_directories(${CMAKE_SOURCE_DIR}/Plugins/Include) - add_library( - ServeFolders SHARED - ${SERVE_FOLDERS_SOURCES} + add_library(ServeFolders SHARED + ${BOOST_SOURCES} ${JSONCPP_SOURCES} + Plugins/Samples/ServeFolders/Plugin.cpp + ${AUTOGENERATED_DIR}/ServeFolders.rc ) set_target_properties(
--- a/Core/Toolbox.cpp Wed Aug 26 16:49:46 2015 +0200 +++ b/Core/Toolbox.cpp Wed Aug 26 17:43:00 2015 +0200 @@ -208,6 +208,12 @@ void Toolbox::ReadFile(std::string& content, const std::string& path) { + if (!boost::filesystem::is_regular_file(path)) + { + LOG(ERROR) << "The path does not point to a regular file: " << path; + throw OrthancException(ErrorCode_RegularFileExpected); + } + boost::filesystem::ifstream f; f.open(path, std::ifstream::in | std::ifstream::binary); if (!f.good())
--- a/Plugins/Samples/ServeFolders/Plugin.cpp Wed Aug 26 16:49:46 2015 +0200 +++ b/Plugins/Samples/ServeFolders/Plugin.cpp Wed Aug 26 17:43:00 2015 +0200 @@ -22,11 +22,8 @@ #include <json/reader.h> #include <json/value.h> -#include <string.h> -#include <stdio.h> -#include <fstream> -#include <algorithm> -#include <sys/stat.h> +#include <boost/filesystem.hpp> + static OrthancPluginContext* context_ = NULL; static std::map<std::string, std::string> folders_; @@ -136,6 +133,80 @@ } + +static bool LookupFolder(std::string& folder, + OrthancPluginRestOutput* output, + const OrthancPluginHttpRequest* request) +{ + const std::string uri = request->groups[0]; + + std::map<std::string, std::string>::const_iterator found = folders_.find(uri); + if (found == folders_.end()) + { + std::string s = "Unknown URI in plugin server-folders: " + uri; + OrthancPluginLogError(context_, s.c_str()); + OrthancPluginSendHttpStatusCode(context_, output, 404); + return false; + } + else + { + folder = found->second; + return true; + } +} + + +static int32_t IndexCallback(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) +{ + namespace fs = boost::filesystem; + + if (request->method != OrthancPluginHttpMethod_Get) + { + OrthancPluginSendMethodNotAllowed(context_, output, "GET"); + return 0; + } + + std::string folder; + if (LookupFolder(folder, output, request)) + { + std::string baseUri = "/" + std::string(request->groups[0]); + + if (fs::is_regular_file(fs::path(folder) / "index.html")) + { + std::string s = baseUri + "/index.html"; + OrthancPluginRedirect(context_, output, s.c_str()); + } + else + { + std::string s; + s += "<html>\n"; + s += " <body>\n"; + s += " <ul>\n"; + + fs::directory_iterator end; + for (fs::directory_iterator it(folder) ; it != end; ++it) + { + if (fs::is_regular_file(it->status())) + { + std::string f = it->path().filename().string(); + s += " <li><a href=\"" + baseUri + "/" + f + "\">" + f + "</a></li>"; + } + } + + s += " </ul>\n"; + s += " </body>\n"; + s += "</html>\n"; + + OrthancPluginAnswerBuffer(context_, output, s.c_str(), s.size(), "text/html"); + } + } + + return 0; +} + + static int32_t FolderCallback(OrthancPluginRestOutput* output, const char* url, const OrthancPluginHttpRequest* request) @@ -146,32 +217,27 @@ return 0; } - const std::string uri = request->groups[0]; - const std::string item = request->groups[1]; + std::string folder; - std::map<std::string, std::string>::const_iterator found = folders_.find(uri); - if (found == folders_.end()) + if (LookupFolder(folder, output, request)) { - std::string s = "Unknown URI in plugin server-folders: " + uri; - OrthancPluginLogError(context_, s.c_str()); - OrthancPluginSendHttpStatusCode(context_, output, 404); - return 0; - } + const std::string item = request->groups[1]; + + std::string path = folder + "/" + item; + const char* mime = GetMimeType(path); - std::string path = found->second + "/" + item; - const char* mime = GetMimeType(path); - - std::string s; - if (ReadFile(s, path)) - { - const char* resource = s.size() ? s.c_str() : NULL; - OrthancPluginAnswerBuffer(context_, output, resource, s.size(), mime); - } - else - { - std::string s = "Inexistent file in served folder: " + path; - OrthancPluginLogError(context_, s.c_str()); - OrthancPluginSendHttpStatusCode(context_, output, 404); + std::string s; + if (ReadFile(s, path)) + { + const char* resource = s.size() ? s.c_str() : NULL; + OrthancPluginAnswerBuffer(context_, output, resource, s.size(), mime); + } + else + { + std::string s = "Inexistent file in served folder: " + path; + OrthancPluginLogError(context_, s.c_str()); + OrthancPluginSendHttpStatusCode(context_, output, 404); + } } return 0; @@ -200,7 +266,7 @@ for (std::map<std::string, std::string>::const_iterator it = folders_.begin(); it != folders_.end(); ++it) { - s += "<li><a href=\"" + it->first + "/index.html\">" + it->first + "</li>\n"; + s += "<li><a href=\"/" + it->first + "\">" + it->first + "</li>\n"; } s += "</ul>\n"; @@ -214,7 +280,6 @@ } - extern "C" { ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) @@ -266,7 +331,7 @@ { std::string baseUri = *it; - // Remove the heading and trailing slashes if any + // Remove the heading and trailing slashes in the root URI, if any while (!baseUri.empty() && *baseUri.begin() == '/') { @@ -285,11 +350,28 @@ return -1; } - const std::string path = configuration["ServeFolders"][*it].asString(); - const std::string regex = "/(" + baseUri + ")/(.*)"; + // Check whether the source folder exists and is indeed a directory + const std::string folder = configuration["ServeFolders"][*it].asString(); + if (!boost::filesystem::is_directory(folder)) + { + std::string msg = "Trying and serve an inexistent folder: " + folder; + OrthancPluginLogError(context_, msg.c_str()); + return -1; + } + + folders_[baseUri] = folder; - OrthancPluginRegisterRestCallback(context, regex.c_str(), FolderCallback); - folders_[baseUri] = path; + // Register the callback to serve the index of the folder + { + const std::string regex = "/(" + baseUri + ")"; + OrthancPluginRegisterRestCallback(context, regex.c_str(), IndexCallback); + } + + // Register the callback to serve the folder + { + const std::string regex = "/(" + baseUri + ")/(.*)"; + OrthancPluginRegisterRestCallback(context, regex.c_str(), FolderCallback); + } } OrthancPluginRegisterRestCallback(context, INDEX_URI, ListServedFolders);
--- a/Resources/ErrorCodes.json Wed Aug 26 16:49:46 2015 +0200 +++ b/Resources/ErrorCodes.json Wed Aug 26 17:43:00 2015 +0200 @@ -157,6 +157,11 @@ "Code": 27, "Name": "UnknownDicomTag", "Description": "Unknown DICOM tag" + }, + { + "Code": 28, + "Name": "RegularFileExpected", + "Description": "The path does not point to a regular file" },