Mercurial > hg > orthanc-dicomweb
changeset 576:26f7f795e379
Fix issue #216 (Requests fail due to bad parsing of the accept HTTP header (semi-colons))
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 28 Jun 2023 10:37:35 +0200 |
parents | be50622282fb |
children | 4e7ed606a9a4 |
files | NEWS Plugin/WadoRs.cpp |
diffstat | 2 files changed, 76 insertions(+), 52 deletions(-) [+] |
line wrap: on
line diff
--- 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)
--- 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 <ChunkedBuffer.h> #include <Compatibility.h> -#include <ChunkedBuffer.h> +#include <HttpServer/HttpContentNegociation.h> #include <Logging.h> #include <Toolbox.h> @@ -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<std::string, std::string> attributes; - OrthancPlugins::ParseContentType(application, attributes, accept); - - std::vector<std::string> 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; }