comparison Plugins/Samples/ServeFolders/Plugin.cpp @ 2958:bb7a66efbeb1

OrthancPlugins::SetGlobalContext() in OrthancPluginCppWrapper
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 04 Dec 2018 16:31:29 +0100
parents 878b59270859
children 4e43e67f8ecf
comparison
equal deleted inserted replaced
2957:ccf61f6e22ef 2958:bb7a66efbeb1
31 # error The macro HAS_ORTHANC_EXCEPTION must be set to 0 to compile this plugin 31 # error The macro HAS_ORTHANC_EXCEPTION must be set to 0 to compile this plugin
32 #endif 32 #endif
33 33
34 34
35 35
36 static OrthancPluginContext* context_ = NULL;
37 static std::map<std::string, std::string> extensions_; 36 static std::map<std::string, std::string> extensions_;
38 static std::map<std::string, std::string> folders_; 37 static std::map<std::string, std::string> folders_;
39 static const char* INDEX_URI = "/app/plugin-serve-folders.html"; 38 static const char* INDEX_URI = "/app/plugin-serve-folders.html";
40 static bool allowCache_ = false; 39 static bool allowCache_ = false;
41 static bool generateETag_ = true; 40 static bool generateETag_ = true;
44 static void SetHttpHeaders(OrthancPluginRestOutput* output) 43 static void SetHttpHeaders(OrthancPluginRestOutput* output)
45 { 44 {
46 if (!allowCache_) 45 if (!allowCache_)
47 { 46 {
48 // http://stackoverflow.com/a/2068407/881731 47 // http://stackoverflow.com/a/2068407/881731
49 OrthancPluginSetHttpHeader(context_, output, "Cache-Control", "no-cache, no-store, must-revalidate"); 48 OrthancPluginContext* context = OrthancPlugins::GetGlobalContext();
50 OrthancPluginSetHttpHeader(context_, output, "Pragma", "no-cache"); 49 OrthancPluginSetHttpHeader(context, output, "Cache-Control", "no-cache, no-store, must-revalidate");
51 OrthancPluginSetHttpHeader(context_, output, "Expires", "0"); 50 OrthancPluginSetHttpHeader(context, output, "Pragma", "no-cache");
51 OrthancPluginSetHttpHeader(context, output, "Expires", "0");
52 } 52 }
53 } 53 }
54 54
55 55
56 static void RegisterDefaultExtensions() 56 static void RegisterDefaultExtensions()
87 { 87 {
88 return found->second; 88 return found->second;
89 } 89 }
90 else 90 else
91 { 91 {
92 OrthancPlugins::LogWarning(context_, "ServeFolders: Unknown MIME type for extension \"" + extension + "\""); 92 OrthancPlugins::LogWarning("ServeFolders: Unknown MIME type for extension \"" + extension + "\"");
93 return "application/octet-stream"; 93 return "application/octet-stream";
94 } 94 }
95 } 95 }
96 96
97 97
102 const std::string uri = request->groups[0]; 102 const std::string uri = request->groups[0];
103 103
104 std::map<std::string, std::string>::const_iterator found = folders_.find(uri); 104 std::map<std::string, std::string>::const_iterator found = folders_.find(uri);
105 if (found == folders_.end()) 105 if (found == folders_.end())
106 { 106 {
107 OrthancPlugins::LogError(context_, "Unknown URI in plugin server-folders: " + uri); 107 OrthancPlugins::LogError("Unknown URI in plugin server-folders: " + uri);
108 OrthancPluginSendHttpStatusCode(context_, output, 404); 108 OrthancPluginSendHttpStatusCode(OrthancPlugins::GetGlobalContext(), output, 404);
109 return false; 109 return false;
110 } 110 }
111 else 111 else
112 { 112 {
113 folder = found->second; 113 folder = found->second;
121 size_t size, 121 size_t size,
122 const std::string& mime) 122 const std::string& mime)
123 { 123 {
124 if (generateETag_) 124 if (generateETag_)
125 { 125 {
126 OrthancPlugins::OrthancString md5(context_); 126 OrthancPlugins::OrthancString md5;
127 md5.Assign(OrthancPluginComputeMd5(context_, content, size)); 127 md5.Assign(OrthancPluginComputeMd5(OrthancPlugins::GetGlobalContext(), content, size));
128 128
129 std::string etag = "\"" + std::string(md5.GetContent()) + "\""; 129 std::string etag = "\"" + std::string(md5.GetContent()) + "\"";
130 OrthancPluginSetHttpHeader(context_, output, "ETag", etag.c_str()); 130 OrthancPluginSetHttpHeader(OrthancPlugins::GetGlobalContext(), output, "ETag", etag.c_str());
131 } 131 }
132 132
133 SetHttpHeaders(output); 133 SetHttpHeaders(output);
134 OrthancPluginAnswerBuffer(context_, output, content, size, mime.c_str()); 134 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, content, size, mime.c_str());
135 } 135 }
136 136
137 137
138 void ServeFolder(OrthancPluginRestOutput* output, 138 void ServeFolder(OrthancPluginRestOutput* output,
139 const char* url, 139 const char* url,
141 { 141 {
142 namespace fs = boost::filesystem; 142 namespace fs = boost::filesystem;
143 143
144 if (request->method != OrthancPluginHttpMethod_Get) 144 if (request->method != OrthancPluginHttpMethod_Get)
145 { 145 {
146 OrthancPluginSendMethodNotAllowed(context_, output, "GET"); 146 OrthancPluginSendMethodNotAllowed(OrthancPlugins::GetGlobalContext(), output, "GET");
147 return; 147 return;
148 } 148 }
149 149
150 std::string folder; 150 std::string folder;
151 151
196 else 196 else
197 { 197 {
198 std::string path = folder + "/" + item.string(); 198 std::string path = folder + "/" + item.string();
199 std::string mime = GetMimeType(path); 199 std::string mime = GetMimeType(path);
200 200
201 OrthancPlugins::MemoryBuffer content(context_); 201 OrthancPlugins::MemoryBuffer content;
202 202
203 try 203 try
204 { 204 {
205 content.ReadFile(path); 205 content.ReadFile(path);
206 } 206 }
207 catch (...) 207 catch (...)
208 { 208 {
209 ORTHANC_PLUGINS_THROW_EXCEPTION(InexistentFile); 209 ORTHANC_PLUGINS_THROW_EXCEPTION(InexistentFile);
210 } 210 }
211 211
212 boost::posix_time::ptime lastModification = boost::posix_time::from_time_t(fs::last_write_time(path)); 212 boost::posix_time::ptime lastModification =
213 boost::posix_time::from_time_t(fs::last_write_time(path));
213 std::string t = boost::posix_time::to_iso_string(lastModification); 214 std::string t = boost::posix_time::to_iso_string(lastModification);
214 OrthancPluginSetHttpHeader(context_, output, "Last-Modified", t.c_str()); 215 OrthancPluginSetHttpHeader(OrthancPlugins::GetGlobalContext(),
216 output, "Last-Modified", t.c_str());
215 217
216 Answer(output, content.GetData(), content.GetSize(), mime); 218 Answer(output, content.GetData(), content.GetSize(), mime);
217 } 219 }
218 } 220 }
219 } 221 }
223 const char* url, 225 const char* url,
224 const OrthancPluginHttpRequest* request) 226 const OrthancPluginHttpRequest* request)
225 { 227 {
226 if (request->method != OrthancPluginHttpMethod_Get) 228 if (request->method != OrthancPluginHttpMethod_Get)
227 { 229 {
228 OrthancPluginSendMethodNotAllowed(context_, output, "GET"); 230 OrthancPluginSendMethodNotAllowed(OrthancPlugins::GetGlobalContext(), output, "GET");
229 return; 231 return;
230 } 232 }
231 233
232 std::string s = "<html><body><h1>Additional folders served by Orthanc</h1>\n"; 234 std::string s = "<html><body><h1>Additional folders served by Orthanc</h1>\n";
233 235
256 258
257 static void ConfigureFolders(const Json::Value& folders) 259 static void ConfigureFolders(const Json::Value& folders)
258 { 260 {
259 if (folders.type() != Json::objectValue) 261 if (folders.type() != Json::objectValue)
260 { 262 {
261 OrthancPlugins::LogError(context_, "The list of folders to be served is badly formatted (must be a JSON object)"); 263 OrthancPlugins::LogError("The list of folders to be served is badly formatted (must be a JSON object)");
262 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 264 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
263 } 265 }
264 266
265 Json::Value::Members members = folders.getMemberNames(); 267 Json::Value::Members members = folders.getMemberNames();
266 268
268 for (Json::Value::Members::const_iterator 270 for (Json::Value::Members::const_iterator
269 it = members.begin(); it != members.end(); ++it) 271 it = members.begin(); it != members.end(); ++it)
270 { 272 {
271 if (folders[*it].type() != Json::stringValue) 273 if (folders[*it].type() != Json::stringValue)
272 { 274 {
273 OrthancPlugins::LogError(context_, "The folder to be served \"" + *it + 275 OrthancPlugins::LogError("The folder to be served \"" + *it +
274 "\" must be associated with a string value (its mapped URI)"); 276 "\" must be associated with a string value (its mapped URI)");
275 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 277 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
276 } 278 }
277 279
278 std::string baseUri = *it; 280 std::string baseUri = *it;
290 baseUri.resize(baseUri.size() - 1); 292 baseUri.resize(baseUri.size() - 1);
291 } 293 }
292 294
293 if (baseUri.empty()) 295 if (baseUri.empty())
294 { 296 {
295 OrthancPlugins::LogError(context_, "The URI of a folder to be served cannot be empty"); 297 OrthancPlugins::LogError("The URI of a folder to be served cannot be empty");
296 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 298 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
297 } 299 }
298 300
299 // Check whether the source folder exists and is indeed a directory 301 // Check whether the source folder exists and is indeed a directory
300 const std::string folder = folders[*it].asString(); 302 const std::string folder = folders[*it].asString();
301 if (!boost::filesystem::is_directory(folder)) 303 if (!boost::filesystem::is_directory(folder))
302 { 304 {
303 OrthancPlugins::LogError(context_, "Trying and serve an inexistent folder: " + folder); 305 OrthancPlugins::LogError("Trying and serve an inexistent folder: " + folder);
304 ORTHANC_PLUGINS_THROW_EXCEPTION(InexistentFile); 306 ORTHANC_PLUGINS_THROW_EXCEPTION(InexistentFile);
305 } 307 }
306 308
307 folders_[baseUri] = folder; 309 folders_[baseUri] = folder;
308 310
309 // Register the callback to serve the folder 311 // Register the callback to serve the folder
310 { 312 {
311 const std::string regex = "/(" + baseUri + ")/(.*)"; 313 const std::string regex = "/(" + baseUri + ")/(.*)";
312 OrthancPlugins::RegisterRestCallback<ServeFolder>(context_, regex.c_str(), true); 314 OrthancPlugins::RegisterRestCallback<ServeFolder>(regex.c_str(), true);
313 } 315 }
314 } 316 }
315 } 317 }
316 318
317 319
318 static void ConfigureExtensions(const Json::Value& extensions) 320 static void ConfigureExtensions(const Json::Value& extensions)
319 { 321 {
320 if (extensions.type() != Json::objectValue) 322 if (extensions.type() != Json::objectValue)
321 { 323 {
322 OrthancPlugins::LogError(context_, "The list of extensions is badly formatted (must be a JSON object)"); 324 OrthancPlugins::LogError("The list of extensions is badly formatted (must be a JSON object)");
323 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 325 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
324 } 326 }
325 327
326 Json::Value::Members members = extensions.getMemberNames(); 328 Json::Value::Members members = extensions.getMemberNames();
327 329
328 for (Json::Value::Members::const_iterator 330 for (Json::Value::Members::const_iterator
329 it = members.begin(); it != members.end(); ++it) 331 it = members.begin(); it != members.end(); ++it)
330 { 332 {
331 if (extensions[*it].type() != Json::stringValue) 333 if (extensions[*it].type() != Json::stringValue)
332 { 334 {
333 OrthancPlugins::LogError(context_, "The file extension \"" + *it + 335 OrthancPlugins::LogError("The file extension \"" + *it +
334 "\" must be associated with a string value (its MIME type)"); 336 "\" must be associated with a string value (its MIME type)");
335 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat); 337 ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
336 } 338 }
337 339
338 const std::string& mime = extensions[*it].asString(); 340 const std::string& mime = extensions[*it].asString();
347 349
348 extensions_[name] = mime; 350 extensions_[name] = mime;
349 351
350 if (mime.empty()) 352 if (mime.empty())
351 { 353 {
352 OrthancPlugins::LogWarning(context_, "ServeFolders: Removing MIME type for file extension \"." + name + "\""); 354 OrthancPlugins::LogWarning("ServeFolders: Removing MIME type for file extension \"." +
355 name + "\"");
353 } 356 }
354 else 357 else
355 { 358 {
356 OrthancPlugins::LogWarning(context_, "ServeFolders: Associating file extension \"." + name + 359 OrthancPlugins::LogWarning("ServeFolders: Associating file extension \"." + name +
357 "\" with MIME type \"" + mime + "\""); 360 "\" with MIME type \"" + mime + "\"");
358 } 361 }
359 } 362 }
360 } 363 }
361 364
363 static void ReadConfiguration() 366 static void ReadConfiguration()
364 { 367 {
365 OrthancPlugins::OrthancConfiguration configuration; 368 OrthancPlugins::OrthancConfiguration configuration;
366 369
367 { 370 {
368 OrthancPlugins::OrthancConfiguration globalConfiguration(context_); 371 OrthancPlugins::OrthancConfiguration globalConfiguration;
369 globalConfiguration.GetSection(configuration, "ServeFolders"); 372 globalConfiguration.GetSection(configuration, "ServeFolders");
370 } 373 }
371 374
372 if (!configuration.IsSection("Folders")) 375 if (!configuration.IsSection("Folders"))
373 { 376 {
382 bool tmp; 385 bool tmp;
383 386
384 if (configuration.LookupBooleanValue(tmp, "AllowCache")) 387 if (configuration.LookupBooleanValue(tmp, "AllowCache"))
385 { 388 {
386 allowCache_ = tmp; 389 allowCache_ = tmp;
387 OrthancPlugins::LogWarning(context_, "ServeFolders: Requesting the HTTP client to " + 390 OrthancPlugins::LogWarning("ServeFolders: Requesting the HTTP client to " +
388 std::string(tmp ? "enable" : "disable") + 391 std::string(tmp ? "enable" : "disable") +
389 " its caching mechanism"); 392 " its caching mechanism");
390 } 393 }
391 394
392 if (configuration.LookupBooleanValue(tmp, "GenerateETag")) 395 if (configuration.LookupBooleanValue(tmp, "GenerateETag"))
393 { 396 {
394 generateETag_ = tmp; 397 generateETag_ = tmp;
395 OrthancPlugins::LogWarning(context_, "ServeFolders: The computation of an ETag for the served resources is " + 398 OrthancPlugins::LogWarning("ServeFolders: The computation of an ETag for the "
399 "served resources is " +
396 std::string(tmp ? "enabled" : "disabled")); 400 std::string(tmp ? "enabled" : "disabled"));
397 } 401 }
398 402
399 OrthancPlugins::OrthancConfiguration extensions; 403 OrthancPlugins::OrthancConfiguration extensions;
400 configuration.GetSection(extensions, "Extensions"); 404 configuration.GetSection(extensions, "Extensions");
401 ConfigureExtensions(extensions.GetJson()); 405 ConfigureExtensions(extensions.GetJson());
402 } 406 }
403 407
404 if (folders_.empty()) 408 if (folders_.empty())
405 { 409 {
406 OrthancPlugins::LogWarning(context_, "ServeFolders: Empty configuration file: No additional folder will be served!"); 410 OrthancPlugins::LogWarning("ServeFolders: Empty configuration file: "
411 "No additional folder will be served!");
407 } 412 }
408 } 413 }
409 414
410 415
411 extern "C" 416 extern "C"
412 { 417 {
413 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) 418 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context)
414 { 419 {
415 context_ = context; 420 OrthancPlugins::SetGlobalContext(context);
416 421
417 /* Check the version of the Orthanc core */ 422 /* Check the version of the Orthanc core */
418 if (OrthancPluginCheckVersion(context_) == 0) 423 if (OrthancPluginCheckVersion(context) == 0)
419 { 424 {
420 OrthancPlugins::ReportMinimalOrthancVersion(context_, 425 OrthancPlugins::ReportMinimalOrthancVersion(ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER,
421 ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER,
422 ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, 426 ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER,
423 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); 427 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER);
424 return -1; 428 return -1;
425 } 429 }
426 430
427 RegisterDefaultExtensions(); 431 RegisterDefaultExtensions();
428 OrthancPluginSetDescription(context_, "Serve additional folders with the HTTP server of Orthanc."); 432 OrthancPluginSetDescription(context, "Serve additional folders with the HTTP server of Orthanc.");
429 OrthancPluginSetRootUri(context, INDEX_URI); 433 OrthancPluginSetRootUri(context, INDEX_URI);
430 OrthancPlugins::RegisterRestCallback<ListServedFolders>(context_, INDEX_URI, true); 434 OrthancPlugins::RegisterRestCallback<ListServedFolders>(INDEX_URI, true);
431 435
432 try 436 try
433 { 437 {
434 ReadConfiguration(); 438 ReadConfiguration();
435 } 439 }
436 catch (OrthancPlugins::PluginException& e) 440 catch (OrthancPlugins::PluginException& e)
437 { 441 {
438 OrthancPlugins::LogError(context_, "Error while initializing the ServeFolders plugin: " + 442 OrthancPlugins::LogError("Error while initializing the ServeFolders plugin: " +
439 std::string(e.What(context_))); 443 std::string(e.What(context)));
440 } 444 }
441 445
442 return 0; 446 return 0;
443 } 447 }
444 448