# HG changeset patch # User Sebastien Jodogne # Date 1687941455 -7200 # Node ID 26f7f795e379f794a6bda29688e53401f41563d7 # Parent be50622282fb3f2d8c73a275299ef95424746f86 Fix issue #216 (Requests fail due to bad parsing of the accept HTTP header (semi-colons)) diff -r be50622282fb -r 26f7f795e379 NEWS --- a/NEWS Tue Jun 27 18:41:53 2023 +0200 +++ b/NEWS Wed Jun 28 10:37:35 2023 +0200 @@ -4,6 +4,7 @@ * Speeded up instance metadata retrieval using OrthancPluginLoadDicomInstance() from SDK 1.12.1 * Support "X-Forwarded-Host" and "X-Forwarded-Proto" headers to compute BulkDataURI. * Small speed-up the studies/../series/../metadata route when in "MainDicomTags" mode. +* Fix issue #216 (Requests fail due to bad parsing of the accept HTTP header (semi-colons)) * New "Experimental" mode for "SeriesMetadata" that is fetching tags from the DB or from the storage if they are missing (useful if you recently changed the "ExtraMainDicomTags" configuration) diff -r be50622282fb -r 26f7f795e379 Plugin/WadoRs.cpp --- a/Plugin/WadoRs.cpp Tue Jun 27 18:41:53 2023 +0200 +++ b/Plugin/WadoRs.cpp Wed Jun 28 10:37:35 2023 +0200 @@ -24,8 +24,9 @@ #include "Configuration.h" #include "DicomWebFormatter.h" +#include #include -#include +#include #include #include @@ -149,6 +150,70 @@ } +namespace +{ + class AcceptMetadataJson : public Orthanc::HttpContentNegociation::IHandler + { + public: + virtual void Handle(const std::string& type, + const std::string& subtype, + const Orthanc::HttpContentNegociation::Dictionary& parameters) ORTHANC_OVERRIDE + { + assert(type == "application"); + assert(subtype == "json" || subtype == "dicom+json"); + } + }; + + class AcceptMetadataMultipart : public Orthanc::HttpContentNegociation::IHandler + { + private: + bool& isXml_; + + public: + AcceptMetadataMultipart(bool& isXml /* out */) : + isXml_(isXml) + { + } + + virtual void Handle(const std::string& type, + const std::string& subtype, + const Orthanc::HttpContentNegociation::Dictionary& parameters) ORTHANC_OVERRIDE + { + assert(type == "multipart" && + subtype == "related"); + + Orthanc::HttpContentNegociation::Dictionary::const_iterator found = parameters.find("type"); + + if (found != parameters.end()) + { + if (found->second == "application/dicom+xml") + { + isXml_ = true; + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, + "This WADO-RS plugin only supports application/dicom+xml " + "type for multipart/related accept (" + found->second + ")"); + } + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, + "Missing \"type\" in multipart/related accept type"); + } + + found = parameters.find("transfer-syntax"); + if (found != parameters.end()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, + "This WADO-RS plugin cannot change the transfer syntax to " + + found->second); + } + } + }; +} + static bool AcceptMetadata(const OrthancPluginHttpRequest* request, bool& isXml) @@ -160,61 +225,19 @@ { return true; } - - std::string application; - std::map attributes; - OrthancPlugins::ParseContentType(application, attributes, accept); - - std::vector applicationTokens; - Orthanc::Toolbox::TokenizeString(applicationTokens, application, ','); - - for (size_t i = 0; i < applicationTokens.size(); i++) - { - std::string token = Orthanc::Toolbox::StripSpaces(applicationTokens[i]); - - if (token == "application/json" || - token == "application/dicom+json" || - token == "*/*") - { - return true; - } - } - - if (application != "multipart/related") - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, - "This WADO-RS plugin cannot generate the following content type: " + accept); - } - - if (attributes.find("type") != attributes.end()) - { - std::string s = attributes["type"]; - Orthanc::Toolbox::ToLowerCase(s); - if (s == "application/dicom+xml") - { - isXml = true; - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, - "This WADO-RS plugin only supports application/dicom+xml " - "type for multipart/related accept (" + accept + ")"); - } - } else { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, - "Missing \"type\" in multipart/related accept type (" + accept + ")"); - } + Orthanc::HttpContentNegociation negociation; + + AcceptMetadataJson json; + negociation.Register("application/json", json); + negociation.Register("application/dicom+json", json); - if (attributes.find("transfer-syntax") != attributes.end()) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, - "This WADO-RS plugin cannot change the transfer syntax to " + - attributes["transfer-syntax"]); + AcceptMetadataMultipart multipart(isXml); + negociation.Register("multipart/related", multipart); + + return negociation.Apply(accept); } - - return true; }