comparison Plugins/Samples/ServeFolders/Plugin.cpp @ 2167:aa2915963531

"Folders" sub-configuration in ServeFolders
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 22 Nov 2016 14:19:42 +0100
parents 700dbb3baac9
children 84033563f7f0
comparison
equal deleted inserted replaced
2166:700dbb3baac9 2167:aa2915963531
79 { 79 {
80 return found->second; 80 return found->second;
81 } 81 }
82 else 82 else
83 { 83 {
84 std::string s = "Unknown MIME type for extension: " + extension; 84 OrthancPlugins::LogWarning(context_, "ServeFolders- Unknown MIME type for extension: " + extension);
85 OrthancPluginLogWarning(context_, s.c_str());
86 return "application/octet-stream"; 85 return "application/octet-stream";
87 } 86 }
88 } 87 }
89 88
90 89
103 return false; 102 return false;
104 } 103 }
105 } 104 }
106 105
107 106
108 static bool ReadConfiguration(Json::Value& configuration,
109 OrthancPluginContext* context)
110 {
111 std::string s;
112
113 {
114 char* tmp = OrthancPluginGetConfiguration(context);
115 if (tmp == NULL)
116 {
117 OrthancPluginLogError(context, "Error while retrieving the configuration from Orthanc");
118 return false;
119 }
120
121 s.assign(tmp);
122 OrthancPluginFreeString(context, tmp);
123 }
124
125 Json::Reader reader;
126 if (reader.parse(s, configuration))
127 {
128 return true;
129 }
130 else
131 {
132 OrthancPluginLogError(context, "Unable to parse the configuration");
133 return false;
134 }
135 }
136
137
138
139 static bool LookupFolder(std::string& folder, 107 static bool LookupFolder(std::string& folder,
140 OrthancPluginRestOutput* output, 108 OrthancPluginRestOutput* output,
141 const OrthancPluginHttpRequest* request) 109 const OrthancPluginHttpRequest* request)
142 { 110 {
143 const std::string uri = request->groups[0]; 111 const std::string uri = request->groups[0];
144 112
145 std::map<std::string, std::string>::const_iterator found = folders_.find(uri); 113 std::map<std::string, std::string>::const_iterator found = folders_.find(uri);
146 if (found == folders_.end()) 114 if (found == folders_.end())
147 { 115 {
148 std::string s = "Unknown URI in plugin server-folders: " + uri; 116 OrthancPlugins::LogError(context_, "Unknown URI in plugin server-folders: " + uri);
149 OrthancPluginLogError(context_, s.c_str());
150 OrthancPluginSendHttpStatusCode(context_, output, 404); 117 OrthancPluginSendHttpStatusCode(context_, output, 404);
151 return false; 118 return false;
152 } 119 }
153 else 120 else
154 { 121 {
241 SetHttpHeaders(output); 208 SetHttpHeaders(output);
242 OrthancPluginAnswerBuffer(context_, output, resource, s.size(), mime.c_str()); 209 OrthancPluginAnswerBuffer(context_, output, resource, s.size(), mime.c_str());
243 } 210 }
244 else 211 else
245 { 212 {
246 std::string s = "Inexistent file in served folder: " + path; 213 OrthancPlugins::LogError(context_, "Inexistent file in served folder: " + path);
247 OrthancPluginLogError(context_, s.c_str());
248 OrthancPluginSendHttpStatusCode(context_, output, 404); 214 OrthancPluginSendHttpStatusCode(context_, output, 404);
249 } 215 }
250 } 216 }
251 } 217 }
252 218
287 253
288 SetHttpHeaders(output); 254 SetHttpHeaders(output);
289 OrthancPluginAnswerBuffer(context_, output, s.c_str(), s.size(), "text/html"); 255 OrthancPluginAnswerBuffer(context_, output, s.c_str(), s.size(), "text/html");
290 256
291 return OrthancPluginErrorCode_Success; 257 return OrthancPluginErrorCode_Success;
258 }
259
260
261 static void ConfigureFolders(const Json::Value& folders)
262 {
263 if (folders.type() != Json::objectValue)
264 {
265 OrthancPlugins::LogError(context_, "The list of folders to be served is badly formatted (must be a JSON object)");
266 throw OrthancPlugins::PluginException(OrthancPluginErrorCode_BadFileFormat);
267 }
268
269 Json::Value::Members members = folders.getMemberNames();
270
271 // Register the callback for each base URI
272 for (Json::Value::Members::const_iterator
273 it = members.begin(); it != members.end(); ++it)
274 {
275 if (folders[*it].type() != Json::stringValue)
276 {
277 OrthancPlugins::LogError(context_, "The folder to be server \"" + *it +
278 "\" must be associated with a string value (its mapped URI)");
279 throw OrthancPlugins::PluginException(OrthancPluginErrorCode_BadFileFormat);
280 }
281
282 std::string baseUri = *it;
283
284 // Remove the heading and trailing slashes in the root URI, if any
285 while (!baseUri.empty() &&
286 *baseUri.begin() == '/')
287 {
288 baseUri = baseUri.substr(1);
289 }
290
291 while (!baseUri.empty() &&
292 *baseUri.rbegin() == '/')
293 {
294 baseUri.resize(baseUri.size() - 1);
295 }
296
297 if (baseUri.empty())
298 {
299 OrthancPlugins::LogError(context_, "The URI of a folder to be served cannot be empty");
300 throw OrthancPlugins::PluginException(OrthancPluginErrorCode_BadFileFormat);
301 }
302
303 // Check whether the source folder exists and is indeed a directory
304 const std::string folder = folders[*it].asString();
305 if (!boost::filesystem::is_directory(folder))
306 {
307 OrthancPlugins::LogError(context_, "Trying and serve an inexistent folder: " + folder);
308 throw OrthancPlugins::PluginException(OrthancPluginErrorCode_InexistentFile);
309 }
310
311 folders_[baseUri] = folder;
312
313 // Register the callback to serve the folder
314 {
315 const std::string regex = "/(" + baseUri + ")/(.*)";
316 OrthancPluginRegisterRestCallback(context_, regex.c_str(), FolderCallback);
317 }
318 }
319 }
320
321
322 static void ReadConfiguration()
323 {
324 OrthancPlugins::OrthancConfiguration configuration;
325
326 {
327 OrthancPlugins::OrthancConfiguration globalConfiguration(context_);
328 globalConfiguration.GetSection(configuration, "ServeFolders");
329 }
330
331 if (!configuration.IsSection("Folders"))
332 {
333 // This is a basic configuration
334 ConfigureFolders(configuration.GetJson());
335 }
336 else
337 {
338 // This is an advanced configuration
339 ConfigureFolders(configuration.GetJson()["Folders"]);
340
341 bool tmp;
342
343 if (configuration.LookupBooleanValue(tmp, "AllowCache"))
344 {
345 allowCache_ = tmp;
346 OrthancPlugins::LogWarning(context_, "ServeFolders- Requesting the HTTP client to " +
347 std::string(allowCache_ ? "enable" : "disable") +
348 " its caching mechanism");
349 }
350 }
351
352 if (folders_.empty())
353 {
354 OrthancPlugins::LogWarning(context_, "ServeFolders- Empty configuration file: No additional folder will be served!");
355 }
292 } 356 }
293 357
294 358
295 extern "C" 359 extern "C"
296 { 360 {
311 return -1; 375 return -1;
312 } 376 }
313 377
314 RegisterDefaultExtensions(); 378 RegisterDefaultExtensions();
315 OrthancPluginSetDescription(context_, "Serve additional folders with the HTTP server of Orthanc."); 379 OrthancPluginSetDescription(context_, "Serve additional folders with the HTTP server of Orthanc.");
316 380 OrthancPluginSetRootUri(context, INDEX_URI);
317 Json::Value configuration; 381 OrthancPluginRegisterRestCallback(context, INDEX_URI, ListServedFolders);
318 if (!ReadConfiguration(configuration, context_)) 382
319 { 383 try
384 {
385 ReadConfiguration();
386 }
387 catch (OrthancPlugins::PluginException& e)
388 {
389 OrthancPlugins::LogError(context, "Error while initializing the ServeFolders plugin: " +
390 std::string(e.GetErrorDescription(context)));
320 return -1; 391 return -1;
321 } 392 }
322 393
323 if (configuration.isMember("ServeFoldersNoCache"))
324 {
325 OrthancPluginLogWarning(context_, "Disabling the cache");
326 allowCache_ = false;
327 }
328
329 if (configuration.isMember("ServeFolders"))
330 {
331 if (configuration["ServeFolders"].type() != Json::objectValue)
332 {
333 OrthancPluginLogError(context_, "The \"ServeFolders\" configuration section is badly formatted (must be a JSON object)");
334 return -1;
335 }
336 }
337 else
338 {
339 OrthancPluginLogWarning(context_, "No section \"ServeFolders\" in your configuration file: "
340 "No additional folder will be served!");
341 configuration["ServeFolders"] = Json::objectValue;
342 }
343
344
345 Json::Value::Members members = configuration["ServeFolders"].getMemberNames();
346
347 // Register the callback for each base URI
348 for (Json::Value::Members::const_iterator
349 it = members.begin(); it != members.end(); ++it)
350 {
351 std::string baseUri = *it;
352
353 // Remove the heading and trailing slashes in the root URI, if any
354 while (!baseUri.empty() &&
355 *baseUri.begin() == '/')
356 {
357 baseUri = baseUri.substr(1);
358 }
359
360 while (!baseUri.empty() &&
361 *baseUri.rbegin() == '/')
362 {
363 baseUri.resize(baseUri.size() - 1);
364 }
365
366 if (baseUri.empty())
367 {
368 OrthancPluginLogError(context_, "The URI of a folder to be served cannot be empty");
369 return -1;
370 }
371
372 // Check whether the source folder exists and is indeed a directory
373 const std::string folder = configuration["ServeFolders"][*it].asString();
374 if (!boost::filesystem::is_directory(folder))
375 {
376 std::string msg = "Trying and serve an inexistent folder: " + folder;
377 OrthancPluginLogError(context_, msg.c_str());
378 return -1;
379 }
380
381 folders_[baseUri] = folder;
382
383 // Register the callback to serve the folder
384 {
385 const std::string regex = "/(" + baseUri + ")/(.*)";
386 OrthancPluginRegisterRestCallback(context, regex.c_str(), FolderCallback);
387 }
388 }
389
390 OrthancPluginRegisterRestCallback(context, INDEX_URI, ListServedFolders);
391 OrthancPluginSetRootUri(context, INDEX_URI);
392
393 return 0; 394 return 0;
394 } 395 }
395 396
396 397
397 ORTHANC_PLUGINS_API void OrthancPluginFinalize() 398 ORTHANC_PLUGINS_API void OrthancPluginFinalize()