Mercurial > hg > orthanc
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 |