(content.GetData()), content.GetSize(), mime);
}
}
}
void ListServedFolders(OrthancPluginRestOutput* output,
const char* url,
const OrthancPluginHttpRequest* request)
{
if (request->method != OrthancPluginHttpMethod_Get)
{
OrthancPluginSendMethodNotAllowed(OrthancPlugins::GetGlobalContext(), output, "GET");
return;
}
std::string s = "Additional folders served by Orthanc
\n";
if (folders_.empty())
{
s += "Empty section ServeFolders in your configuration file: No additional folder is served.
\n";
}
else
{
s += "\n";
for (std::map::const_iterator
it = folders_.begin(); it != folders_.end(); ++it)
{
// The URI is relative to INDEX_URI ("/app/plugin-serve-folders.html")
s += "- first + "/index.html\">" + it->first + "
\n";
}
s += "
\n";
}
s += "\n";
Answer(output, s.c_str(), s.size(), "text/html");
}
static void ConfigureFolders(const Json::Value& folders)
{
if (folders.type() != Json::objectValue)
{
ORTHANC_PLUGINS_LOG_ERROR("The list of folders to be served is badly formatted (must be a JSON object)");
ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
}
Json::Value::Members members = folders.getMemberNames();
// Register the callback for each base URI
for (Json::Value::Members::const_iterator
it = members.begin(); it != members.end(); ++it)
{
if (folders[*it].type() != Json::stringValue)
{
ORTHANC_PLUGINS_LOG_ERROR("The folder to be served \"" + *it +
"\" must be associated with a string value (its mapped URI)");
ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
}
std::string baseUri = *it;
// Remove the heading and trailing slashes in the root URI, if any
while (!baseUri.empty() &&
*baseUri.begin() == '/')
{
baseUri = baseUri.substr(1);
}
while (!baseUri.empty() &&
*baseUri.rbegin() == '/')
{
baseUri.resize(baseUri.size() - 1);
}
if (baseUri.empty())
{
ORTHANC_PLUGINS_LOG_ERROR("The URI of a folder to be served cannot be empty");
ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
}
// Check whether the source folder exists and is indeed a directory
const std::string folder = folders[*it].asString();
if (!boost::filesystem::is_directory(folder))
{
ORTHANC_PLUGINS_LOG_ERROR("Trying to serve an inexistent folder: " + folder);
ORTHANC_PLUGINS_THROW_EXCEPTION(InexistentFile);
}
folders_[baseUri] = folder;
// Register the callback to serve the folder
{
const std::string regex = "/(" + baseUri + ")/(.*)";
OrthancPlugins::RegisterRestCallback(regex.c_str(), true);
}
}
}
static void ConfigureExtensions(const Json::Value& extensions)
{
if (extensions.type() != Json::objectValue)
{
ORTHANC_PLUGINS_LOG_ERROR("The list of extensions is badly formatted (must be a JSON object)");
ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
}
Json::Value::Members members = extensions.getMemberNames();
for (Json::Value::Members::const_iterator
it = members.begin(); it != members.end(); ++it)
{
if (extensions[*it].type() != Json::stringValue)
{
ORTHANC_PLUGINS_LOG_ERROR("The file extension \"" + *it +
"\" must be associated with a string value (its MIME type)");
ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
}
const std::string& mime = extensions[*it].asString();
std::string name = *it;
if (!name.empty() &&
name[0] == '.')
{
name = name.substr(1); // Remove the leading dot "."
}
extensions_[name] = mime;
if (mime.empty())
{
ORTHANC_PLUGINS_LOG_WARNING("ServeFolders: Removing MIME type for file extension \"." +
name + "\"");
}
else
{
ORTHANC_PLUGINS_LOG_WARNING("ServeFolders: Associating file extension \"." + name +
"\" with MIME type \"" + mime + "\"");
}
}
}
static void ReadConfiguration()
{
OrthancPlugins::OrthancConfiguration configuration;
{
OrthancPlugins::OrthancConfiguration globalConfiguration;
globalConfiguration.GetSection(configuration, "ServeFolders");
}
if (!configuration.IsSection("Folders"))
{
// This is a basic configuration
ConfigureFolders(configuration.GetJson());
}
else
{
// This is an advanced configuration
ConfigureFolders(configuration.GetJson()["Folders"]);
bool tmp;
if (configuration.LookupBooleanValue(tmp, "AllowCache"))
{
allowCache_ = tmp;
ORTHANC_PLUGINS_LOG_WARNING("ServeFolders: Requesting the HTTP client to " +
std::string(tmp ? "enable" : "disable") +
" its caching mechanism");
}
if (configuration.LookupBooleanValue(tmp, "GenerateETag"))
{
generateETag_ = tmp;
ORTHANC_PLUGINS_LOG_WARNING("ServeFolders: The computation of an ETag for the served resources is " +
std::string(tmp ? "enabled" : "disabled"));
}
OrthancPlugins::OrthancConfiguration extensions;
configuration.GetSection(extensions, "Extensions");
ConfigureExtensions(extensions.GetJson());
}
if (folders_.empty())
{
ORTHANC_PLUGINS_LOG_WARNING("ServeFolders: Empty configuration file: No additional folder will be served!");
}
}
extern "C"
{
ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context)
{
OrthancPlugins::SetGlobalContext(context, SERVE_FOLDERS_NAME);
/* Check the version of the Orthanc core */
if (OrthancPluginCheckVersion(context) == 0)
{
OrthancPlugins::ReportMinimalOrthancVersion(ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER,
ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER,
ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER);
return -1;
}
RegisterDefaultExtensions();
OrthancPluginSetDescription2(context, SERVE_FOLDERS_NAME, "Serve additional folders with the HTTP server of Orthanc.");
OrthancPluginSetRootUri2(context, SERVE_FOLDERS_NAME, INDEX_URI);
OrthancPlugins::RegisterRestCallback(INDEX_URI, true);
try
{
ReadConfiguration();
}
catch (OrthancPlugins::PluginException& e)
{
ORTHANC_PLUGINS_LOG_ERROR("Error while initializing the ServeFolders plugin: " +
std::string(e.What(context)));
}
return 0;
}
ORTHANC_PLUGINS_API void OrthancPluginFinalize()
{
}
ORTHANC_PLUGINS_API const char* OrthancPluginGetName()
{
return SERVE_FOLDERS_NAME;
}
ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion()
{
return SERVE_FOLDERS_VERSION;
}
}