# HG changeset patch # User Sebastien Jodogne # Date 1620233916 -7200 # Node ID a9d773afdbc671aa89a8068a490f058d3904db55 # Parent a17b1848aff6ea2ff05e7582bec0189a78b7278e Fix issue #196 (STOW-RS: Should return 200 only when successfully stored all instances) diff -r a17b1848aff6 -r a9d773afdbc6 NEWS --- a/NEWS Wed May 05 12:13:37 2021 +0200 +++ b/NEWS Wed May 05 18:58:36 2021 +0200 @@ -4,6 +4,7 @@ * New field "Timeout" in "DicomWeb.Servers" to specify HTTP timeout on a per-server basis * Reduced memory consumption in STOW-RS server thanks to an optimization of Orthanc::MultipartStreamReader in Orthanc framework 1.9.3 +* Fix issue #196 (STOW-RS: Should return 200 only when successfully stored all instances) Version 1.5 (2021-01-26) diff -r a17b1848aff6 -r a9d773afdbc6 Plugin/StowRs.cpp --- a/Plugin/StowRs.cpp Wed May 05 12:13:37 2021 +0200 +++ b/Plugin/StowRs.cpp Wed May 05 18:58:36 2021 +0200 @@ -37,7 +37,9 @@ isFirst_(true), result_(Json::objectValue), success_(Json::arrayValue), - failed_(Json::arrayValue) + failed_(Json::arrayValue), + hasBadSyntax_(false), + hasConflict_(false) { std::string tmp, contentType, subType, boundary; if (!Orthanc::MultipartStreamReader::GetMainContentType(tmp, headers) || @@ -111,8 +113,9 @@ if (!ok) { - // Bad DICOM file => TODO add to error + // Bad DICOM file LogWarning("STOW-RS cannot parse an incoming DICOM file"); + hasBadSyntax_ = true; return; } @@ -127,6 +130,21 @@ dicom[Orthanc::DICOM_TAG_STUDY_INSTANCE_UID.Format()].type() != Json::stringValue) { LogWarning("STOW-RS: Missing a mandatory tag in incoming DICOM file"); + hasBadSyntax_ = true; + + if (dicom.isMember(Orthanc::DICOM_TAG_SOP_CLASS_UID.Format()) && + dicom.isMember(Orthanc::DICOM_TAG_SOP_INSTANCE_UID.Format()) && + dicom[Orthanc::DICOM_TAG_SOP_CLASS_UID.Format()].type() == Json::stringValue && + dicom[Orthanc::DICOM_TAG_SOP_INSTANCE_UID.Format()].type() == Json::stringValue) + { + Json::Value item = Json::objectValue; + item[DICOM_TAG_REFERENCED_SOP_CLASS_UID.Format()] = dicom[Orthanc::DICOM_TAG_SOP_CLASS_UID.Format()].asString(); + item[DICOM_TAG_REFERENCED_SOP_INSTANCE_UID.Format()] = dicom[Orthanc::DICOM_TAG_SOP_INSTANCE_UID.Format()].asString(); + item[DICOM_TAG_FAILURE_REASON.Format()] = + boost::lexical_cast(0xC000); // Error: Cannot understand + failed_.append(item); + } + return; } @@ -142,12 +160,14 @@ if (!expectedStudy_.empty() && studyInstanceUid != expectedStudy_) { - LogInfo("STOW-RS request restricted to study [" + expectedStudy_ + - "]: Ignoring instance from study [" + studyInstanceUid + "]"); + LogWarning("STOW-RS request restricted to study [" + expectedStudy_ + + "], but received instance from study [" + studyInstanceUid + "]"); - /*item[DICOM_TAG_WARNING_REASON.Format()] = - boost::lexical_cast(0xB006); // Elements discarded - success.append(item);*/ + hasConflict_ = true; + + item[DICOM_TAG_FAILURE_REASON.Format()] = + boost::lexical_cast(0x0110); // Processing failure + failed_.append(item); } else { @@ -203,9 +223,23 @@ DicomWebFormatter::Apply(answer, context_, result_, xml_, OrthancPluginDicomWebBinaryMode_Ignore, ""); - - OrthancPluginAnswerBuffer(context_, output, answer.c_str(), answer.size(), - xml_ ? "application/dicom+xml" : "application/dicom+json"); + + // http://dicom.nema.org/medical/dicom/current/output/html/part18.html#table_10.5.3-1 + if (hasBadSyntax_) + { + // Error 400 + OrthancPluginSendHttpStatus(context_, output, 400, answer.c_str(), answer.size()); + } + else if (hasConflict_) + { + // Error 409 + OrthancPluginSendHttpStatus(context_, output, 409, answer.c_str(), answer.size()); + } + else + { + OrthancPluginAnswerBuffer(context_, output, answer.c_str(), answer.size(), + xml_ ? "application/dicom+xml" : "application/dicom+json"); + } }; diff -r a17b1848aff6 -r a9d773afdbc6 Plugin/StowRs.h --- a/Plugin/StowRs.h Wed May 05 12:13:37 2021 +0200 +++ b/Plugin/StowRs.h Wed May 05 18:58:36 2021 +0200 @@ -41,6 +41,8 @@ Json::Value result_; Json::Value success_; Json::Value failed_; + bool hasBadSyntax_; + bool hasConflict_; std::unique_ptr parser_;