Mercurial > hg > orthanc
comparison Plugins/Engine/OrthancPlugins.cpp @ 2957:ccf61f6e22ef
New function in the SDK: "OrthancPluginSetHttpErrorDetails()"
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 03 Dec 2018 17:14:55 +0100 |
parents | bfee0b9f3209 |
children | 74a5a7fd6e0e |
comparison
equal
deleted
inserted
replaced
2956:bfee0b9f3209 | 2957:ccf61f6e22ef |
---|---|
317 boost::mutex contextMutex_; | 317 boost::mutex contextMutex_; |
318 ServerContext* context_; | 318 ServerContext* context_; |
319 | 319 |
320 | 320 |
321 public: | 321 public: |
322 class PluginHttpOutput : public boost::noncopyable | |
323 { | |
324 private: | |
325 HttpOutput& output_; | |
326 std::auto_ptr<std::string> errorDetails_; | |
327 | |
328 public: | |
329 PluginHttpOutput(HttpOutput& output) : | |
330 output_(output) | |
331 { | |
332 } | |
333 | |
334 HttpOutput& GetOutput() | |
335 { | |
336 return output_; | |
337 } | |
338 | |
339 void SetErrorDetails(const std::string& details) | |
340 { | |
341 errorDetails_.reset(new std::string(details)); | |
342 } | |
343 | |
344 bool HasErrorDetails() const | |
345 { | |
346 return errorDetails_.get() != NULL; | |
347 } | |
348 | |
349 const std::string& GetErrorDetails() const | |
350 { | |
351 if (errorDetails_.get() == NULL) | |
352 { | |
353 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
354 } | |
355 else | |
356 { | |
357 return *errorDetails_; | |
358 } | |
359 } | |
360 }; | |
361 | |
362 | |
322 class RestCallback : public boost::noncopyable | 363 class RestCallback : public boost::noncopyable |
323 { | 364 { |
324 private: | 365 private: |
325 boost::regex regex_; | 366 boost::regex regex_; |
326 OrthancPluginRestCallback callback_; | 367 OrthancPluginRestCallback callback_; |
327 bool lock_; | 368 bool lock_; |
328 | 369 |
329 OrthancPluginErrorCode InvokeInternal(HttpOutput& output, | 370 OrthancPluginErrorCode InvokeInternal(PluginHttpOutput& output, |
330 const std::string& flatUri, | 371 const std::string& flatUri, |
331 const OrthancPluginHttpRequest& request) | 372 const OrthancPluginHttpRequest& request) |
332 { | 373 { |
333 return callback_(reinterpret_cast<OrthancPluginRestOutput*>(&output), | 374 return callback_(reinterpret_cast<OrthancPluginRestOutput*>(&output), |
334 flatUri.c_str(), | 375 flatUri.c_str(), |
349 { | 390 { |
350 return regex_; | 391 return regex_; |
351 } | 392 } |
352 | 393 |
353 OrthancPluginErrorCode Invoke(boost::recursive_mutex& restCallbackMutex, | 394 OrthancPluginErrorCode Invoke(boost::recursive_mutex& restCallbackMutex, |
354 HttpOutput& output, | 395 PluginHttpOutput& output, |
355 const std::string& flatUri, | 396 const std::string& flatUri, |
356 const OrthancPluginHttpRequest& request) | 397 const OrthancPluginHttpRequest& request) |
357 { | 398 { |
358 if (lock_) | 399 if (lock_) |
359 { | 400 { |
1023 request.headersKeys = &headersKeys[0]; | 1064 request.headersKeys = &headersKeys[0]; |
1024 request.headersValues = &headersValues[0]; | 1065 request.headersValues = &headersValues[0]; |
1025 } | 1066 } |
1026 | 1067 |
1027 assert(callback != NULL); | 1068 assert(callback != NULL); |
1028 OrthancPluginErrorCode error = callback->Invoke(pimpl_->restCallbackMutex_, output, flatUri, request); | 1069 |
1070 PImpl::PluginHttpOutput pluginOutput(output); | |
1071 | |
1072 OrthancPluginErrorCode error = callback->Invoke(pimpl_->restCallbackMutex_, pluginOutput, flatUri, request); | |
1029 | 1073 |
1030 if (error == OrthancPluginErrorCode_Success && | 1074 if (error == OrthancPluginErrorCode_Success && |
1031 output.IsWritingMultipart()) | 1075 output.IsWritingMultipart()) |
1032 { | 1076 { |
1033 output.CloseMultipart(); | 1077 output.CloseMultipart(); |
1038 return true; | 1082 return true; |
1039 } | 1083 } |
1040 else | 1084 else |
1041 { | 1085 { |
1042 GetErrorDictionary().LogError(error, false); | 1086 GetErrorDictionary().LogError(error, false); |
1043 throw OrthancException(static_cast<ErrorCode>(error)); | 1087 |
1088 if (pluginOutput.HasErrorDetails()) | |
1089 { | |
1090 throw OrthancException(static_cast<ErrorCode>(error), pluginOutput.GetErrorDetails()); | |
1091 } | |
1092 else | |
1093 { | |
1094 throw OrthancException(static_cast<ErrorCode>(error)); | |
1095 } | |
1044 } | 1096 } |
1045 } | 1097 } |
1046 | 1098 |
1047 | 1099 |
1048 void OrthancPlugins::SignalStoredInstance(const std::string& instanceId, | 1100 void OrthancPlugins::SignalStoredInstance(const std::string& instanceId, |
1245 void OrthancPlugins::AnswerBuffer(const void* parameters) | 1297 void OrthancPlugins::AnswerBuffer(const void* parameters) |
1246 { | 1298 { |
1247 const _OrthancPluginAnswerBuffer& p = | 1299 const _OrthancPluginAnswerBuffer& p = |
1248 *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters); | 1300 *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters); |
1249 | 1301 |
1250 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | 1302 HttpOutput& translatedOutput = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
1251 translatedOutput->SetContentType(p.mimeType); | 1303 translatedOutput.SetContentType(p.mimeType); |
1252 translatedOutput->Answer(p.answer, p.answerSize); | 1304 translatedOutput.Answer(p.answer, p.answerSize); |
1253 } | 1305 } |
1254 | 1306 |
1255 | 1307 |
1256 void OrthancPlugins::Redirect(const void* parameters) | 1308 void OrthancPlugins::Redirect(const void* parameters) |
1257 { | 1309 { |
1258 const _OrthancPluginOutputPlusArgument& p = | 1310 const _OrthancPluginOutputPlusArgument& p = |
1259 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters); | 1311 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters); |
1260 | 1312 |
1261 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | 1313 HttpOutput& translatedOutput = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
1262 translatedOutput->Redirect(p.argument); | 1314 translatedOutput.Redirect(p.argument); |
1263 } | 1315 } |
1264 | 1316 |
1265 | 1317 |
1266 void OrthancPlugins::SendHttpStatusCode(const void* parameters) | 1318 void OrthancPlugins::SendHttpStatusCode(const void* parameters) |
1267 { | 1319 { |
1268 const _OrthancPluginSendHttpStatusCode& p = | 1320 const _OrthancPluginSendHttpStatusCode& p = |
1269 *reinterpret_cast<const _OrthancPluginSendHttpStatusCode*>(parameters); | 1321 *reinterpret_cast<const _OrthancPluginSendHttpStatusCode*>(parameters); |
1270 | 1322 |
1271 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | 1323 HttpOutput& translatedOutput = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
1272 translatedOutput->SendStatus(static_cast<HttpStatus>(p.status)); | 1324 translatedOutput.SendStatus(static_cast<HttpStatus>(p.status)); |
1273 } | 1325 } |
1274 | 1326 |
1275 | 1327 |
1276 void OrthancPlugins::SendHttpStatus(const void* parameters) | 1328 void OrthancPlugins::SendHttpStatus(const void* parameters) |
1277 { | 1329 { |
1278 const _OrthancPluginSendHttpStatus& p = | 1330 const _OrthancPluginSendHttpStatus& p = |
1279 *reinterpret_cast<const _OrthancPluginSendHttpStatus*>(parameters); | 1331 *reinterpret_cast<const _OrthancPluginSendHttpStatus*>(parameters); |
1280 | 1332 |
1281 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | 1333 HttpOutput& translatedOutput = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
1282 HttpStatus status = static_cast<HttpStatus>(p.status); | 1334 HttpStatus status = static_cast<HttpStatus>(p.status); |
1283 | 1335 |
1284 if (p.bodySize > 0 && p.body != NULL) | 1336 if (p.bodySize > 0 && p.body != NULL) |
1285 { | 1337 { |
1286 translatedOutput->SendStatus(status, p.body, p.bodySize); | 1338 translatedOutput.SendStatus(status, p.body, p.bodySize); |
1287 } | 1339 } |
1288 else | 1340 else |
1289 { | 1341 { |
1290 translatedOutput->SendStatus(status); | 1342 translatedOutput.SendStatus(status); |
1291 } | 1343 } |
1292 } | 1344 } |
1293 | 1345 |
1294 | 1346 |
1295 void OrthancPlugins::SendUnauthorized(const void* parameters) | 1347 void OrthancPlugins::SendUnauthorized(const void* parameters) |
1296 { | 1348 { |
1297 const _OrthancPluginOutputPlusArgument& p = | 1349 const _OrthancPluginOutputPlusArgument& p = |
1298 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters); | 1350 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters); |
1299 | 1351 |
1300 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | 1352 HttpOutput& translatedOutput = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
1301 translatedOutput->SendUnauthorized(p.argument); | 1353 translatedOutput.SendUnauthorized(p.argument); |
1302 } | 1354 } |
1303 | 1355 |
1304 | 1356 |
1305 void OrthancPlugins::SendMethodNotAllowed(const void* parameters) | 1357 void OrthancPlugins::SendMethodNotAllowed(const void* parameters) |
1306 { | 1358 { |
1307 const _OrthancPluginOutputPlusArgument& p = | 1359 const _OrthancPluginOutputPlusArgument& p = |
1308 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters); | 1360 *reinterpret_cast<const _OrthancPluginOutputPlusArgument*>(parameters); |
1309 | 1361 |
1310 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | 1362 HttpOutput& translatedOutput = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
1311 translatedOutput->SendMethodNotAllowed(p.argument); | 1363 translatedOutput.SendMethodNotAllowed(p.argument); |
1312 } | 1364 } |
1313 | 1365 |
1314 | 1366 |
1315 void OrthancPlugins::SetCookie(const void* parameters) | 1367 void OrthancPlugins::SetCookie(const void* parameters) |
1316 { | 1368 { |
1317 const _OrthancPluginSetHttpHeader& p = | 1369 const _OrthancPluginSetHttpHeader& p = |
1318 *reinterpret_cast<const _OrthancPluginSetHttpHeader*>(parameters); | 1370 *reinterpret_cast<const _OrthancPluginSetHttpHeader*>(parameters); |
1319 | 1371 |
1320 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | 1372 HttpOutput& translatedOutput = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
1321 translatedOutput->SetCookie(p.key, p.value); | 1373 translatedOutput.SetCookie(p.key, p.value); |
1322 } | 1374 } |
1323 | 1375 |
1324 | 1376 |
1325 void OrthancPlugins::SetHttpHeader(const void* parameters) | 1377 void OrthancPlugins::SetHttpHeader(const void* parameters) |
1326 { | 1378 { |
1327 const _OrthancPluginSetHttpHeader& p = | 1379 const _OrthancPluginSetHttpHeader& p = |
1328 *reinterpret_cast<const _OrthancPluginSetHttpHeader*>(parameters); | 1380 *reinterpret_cast<const _OrthancPluginSetHttpHeader*>(parameters); |
1329 | 1381 |
1330 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | 1382 HttpOutput& translatedOutput = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
1331 translatedOutput->AddHeader(p.key, p.value); | 1383 translatedOutput.AddHeader(p.key, p.value); |
1384 } | |
1385 | |
1386 | |
1387 void OrthancPlugins::SetHttpErrorDetails(const void* parameters) | |
1388 { | |
1389 const _OrthancPluginSetHttpErrorDetails& p = | |
1390 *reinterpret_cast<const _OrthancPluginSetHttpErrorDetails*>(parameters); | |
1391 | |
1392 PImpl::PluginHttpOutput* output = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output); | |
1393 output->SetErrorDetails(p.details); | |
1332 } | 1394 } |
1333 | 1395 |
1334 | 1396 |
1335 void OrthancPlugins::CompressAndAnswerPngImage(const void* parameters) | 1397 void OrthancPlugins::CompressAndAnswerPngImage(const void* parameters) |
1336 { | 1398 { |
1355 void OrthancPlugins::CompressAndAnswerImage(const void* parameters) | 1417 void OrthancPlugins::CompressAndAnswerImage(const void* parameters) |
1356 { | 1418 { |
1357 const _OrthancPluginCompressAndAnswerImage& p = | 1419 const _OrthancPluginCompressAndAnswerImage& p = |
1358 *reinterpret_cast<const _OrthancPluginCompressAndAnswerImage*>(parameters); | 1420 *reinterpret_cast<const _OrthancPluginCompressAndAnswerImage*>(parameters); |
1359 | 1421 |
1360 HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output); | 1422 HttpOutput& translatedOutput = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
1361 | 1423 |
1362 ImageAccessor accessor; | 1424 ImageAccessor accessor; |
1363 accessor.AssignReadOnly(Plugins::Convert(p.pixelFormat), p.width, p.height, p.pitch, p.buffer); | 1425 accessor.AssignReadOnly(Plugins::Convert(p.pixelFormat), p.width, p.height, p.pitch, p.buffer); |
1364 | 1426 |
1365 std::string compressed; | 1427 std::string compressed; |
1368 { | 1430 { |
1369 case OrthancPluginImageFormat_Png: | 1431 case OrthancPluginImageFormat_Png: |
1370 { | 1432 { |
1371 PngWriter writer; | 1433 PngWriter writer; |
1372 writer.WriteToMemory(compressed, accessor); | 1434 writer.WriteToMemory(compressed, accessor); |
1373 translatedOutput->SetContentType(MimeType_Png); | 1435 translatedOutput.SetContentType(MimeType_Png); |
1374 break; | 1436 break; |
1375 } | 1437 } |
1376 | 1438 |
1377 case OrthancPluginImageFormat_Jpeg: | 1439 case OrthancPluginImageFormat_Jpeg: |
1378 { | 1440 { |
1379 JpegWriter writer; | 1441 JpegWriter writer; |
1380 writer.SetQuality(p.quality); | 1442 writer.SetQuality(p.quality); |
1381 writer.WriteToMemory(compressed, accessor); | 1443 writer.WriteToMemory(compressed, accessor); |
1382 translatedOutput->SetContentType(MimeType_Jpeg); | 1444 translatedOutput.SetContentType(MimeType_Jpeg); |
1383 break; | 1445 break; |
1384 } | 1446 } |
1385 | 1447 |
1386 default: | 1448 default: |
1387 throw OrthancException(ErrorCode_ParameterOutOfRange); | 1449 throw OrthancException(ErrorCode_ParameterOutOfRange); |
1388 } | 1450 } |
1389 | 1451 |
1390 translatedOutput->Answer(compressed); | 1452 translatedOutput.Answer(compressed); |
1391 } | 1453 } |
1392 | 1454 |
1393 | 1455 |
1394 void OrthancPlugins::GetDicomForInstance(const void* parameters) | 1456 void OrthancPlugins::GetDicomForInstance(const void* parameters) |
1395 { | 1457 { |
2283 // An exception might be raised in this function if the | 2345 // An exception might be raised in this function if the |
2284 // connection was closed by the HTTP client. | 2346 // connection was closed by the HTTP client. |
2285 const _OrthancPluginAnswerBuffer& p = | 2347 const _OrthancPluginAnswerBuffer& p = |
2286 *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters); | 2348 *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters); |
2287 | 2349 |
2288 HttpOutput* output = reinterpret_cast<HttpOutput*>(p.output); | 2350 HttpOutput& output = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
2289 | 2351 |
2290 std::map<std::string, std::string> headers; // No custom headers | 2352 std::map<std::string, std::string> headers; // No custom headers |
2291 output->SendMultipartItem(p.answer, p.answerSize, headers); | 2353 output.SendMultipartItem(p.answer, p.answerSize, headers); |
2292 } | 2354 } |
2293 | 2355 |
2294 | 2356 |
2295 void OrthancPlugins::ApplySendMultipartItem2(const void* parameters) | 2357 void OrthancPlugins::ApplySendMultipartItem2(const void* parameters) |
2296 { | 2358 { |
2297 // An exception might be raised in this function if the | 2359 // An exception might be raised in this function if the |
2298 // connection was closed by the HTTP client. | 2360 // connection was closed by the HTTP client. |
2299 const _OrthancPluginSendMultipartItem2& p = | 2361 const _OrthancPluginSendMultipartItem2& p = |
2300 *reinterpret_cast<const _OrthancPluginSendMultipartItem2*>(parameters); | 2362 *reinterpret_cast<const _OrthancPluginSendMultipartItem2*>(parameters); |
2301 HttpOutput* output = reinterpret_cast<HttpOutput*>(p.output); | 2363 HttpOutput& output = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
2302 | 2364 |
2303 std::map<std::string, std::string> headers; | 2365 std::map<std::string, std::string> headers; |
2304 for (uint32_t i = 0; i < p.headersCount; i++) | 2366 for (uint32_t i = 0; i < p.headersCount; i++) |
2305 { | 2367 { |
2306 headers[p.headersKeys[i]] = p.headersValues[i]; | 2368 headers[p.headersKeys[i]] = p.headersValues[i]; |
2307 } | 2369 } |
2308 | 2370 |
2309 output->SendMultipartItem(p.answer, p.answerSize, headers); | 2371 output.SendMultipartItem(p.answer, p.answerSize, headers); |
2310 } | 2372 } |
2311 | 2373 |
2312 | 2374 |
2313 void OrthancPlugins::DatabaseAnswer(const void* parameters) | 2375 void OrthancPlugins::DatabaseAnswer(const void* parameters) |
2314 { | 2376 { |
2506 SetCookie(parameters); | 2568 SetCookie(parameters); |
2507 return true; | 2569 return true; |
2508 | 2570 |
2509 case _OrthancPluginService_SetHttpHeader: | 2571 case _OrthancPluginService_SetHttpHeader: |
2510 SetHttpHeader(parameters); | 2572 SetHttpHeader(parameters); |
2573 return true; | |
2574 | |
2575 case _OrthancPluginService_SetHttpErrorDetails: | |
2576 SetHttpErrorDetails(parameters); | |
2511 return true; | 2577 return true; |
2512 | 2578 |
2513 case _OrthancPluginService_LookupPatient: | 2579 case _OrthancPluginService_LookupPatient: |
2514 case _OrthancPluginService_LookupStudy: | 2580 case _OrthancPluginService_LookupStudy: |
2515 case _OrthancPluginService_LookupStudyWithAccessionNumber: | 2581 case _OrthancPluginService_LookupStudyWithAccessionNumber: |
2571 | 2637 |
2572 case _OrthancPluginService_StartMultipartAnswer: | 2638 case _OrthancPluginService_StartMultipartAnswer: |
2573 { | 2639 { |
2574 const _OrthancPluginStartMultipartAnswer& p = | 2640 const _OrthancPluginStartMultipartAnswer& p = |
2575 *reinterpret_cast<const _OrthancPluginStartMultipartAnswer*>(parameters); | 2641 *reinterpret_cast<const _OrthancPluginStartMultipartAnswer*>(parameters); |
2576 HttpOutput* output = reinterpret_cast<HttpOutput*>(p.output); | 2642 HttpOutput& output = reinterpret_cast<PImpl::PluginHttpOutput*>(p.output)->GetOutput(); |
2577 output->StartMultipart(p.subType, p.contentType); | 2643 output.StartMultipart(p.subType, p.contentType); |
2578 return true; | 2644 return true; |
2579 } | 2645 } |
2580 | 2646 |
2581 case _OrthancPluginService_SendMultipartItem: | 2647 case _OrthancPluginService_SendMultipartItem: |
2582 ApplySendMultipartItem(parameters); | 2648 ApplySendMultipartItem(parameters); |