changeset 128:ffe7bfbe370e dev

url encoding
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 23 Jun 2016 18:04:35 +0200
parents 1a21c9da983a
children 1aad2bf98d8c
files Plugin/Configuration.cpp Plugin/Configuration.h Plugin/Plugin.cpp Plugin/StowRsClient.cpp
diffstat 4 files changed, 124 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/Plugin/Configuration.cpp	Thu Jun 23 17:31:40 2016 +0200
+++ b/Plugin/Configuration.cpp	Thu Jun 23 18:04:35 2016 +0200
@@ -309,6 +309,50 @@
   }
 
 
+  void ParseAssociativeArray(std::map<std::string, std::string>& target,
+                             const Json::Value& value,
+                             const std::string& key)
+  {
+    target.clear();
+
+    if (value.type() != Json::objectValue)
+    {
+      OrthancPlugins::Configuration::LogError("This is not a JSON object");
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
+    }
+
+    if (!value.isMember(key))
+    {
+      return;
+    }
+
+    const Json::Value& tmp = value[key];
+
+    if (tmp.type() != Json::objectValue)
+    {
+      OrthancPlugins::Configuration::LogError("The field \"" + key + "\" of a JSON object is "
+                                              "not a JSON associative array as expected");
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
+    }
+
+    Json::Value::Members names = tmp.getMemberNames();
+
+    for (size_t i = 0; i < names.size(); i++)
+    {
+      if (tmp[names[i]].type() != Json::stringValue)
+      {
+        OrthancPlugins::Configuration::LogError("Some value in the associative array \"" + key + 
+                                                "\" is not a string as expected");
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
+      }
+      else
+      {
+        target[names[i]] = tmp[names[i]].asString();
+      }
+    }
+  }
+
+
   namespace Configuration
   {
     static OrthancConfiguration configuration_;
--- a/Plugin/Configuration.h	Thu Jun 23 17:31:40 2016 +0200
+++ b/Plugin/Configuration.h	Thu Jun 23 18:04:35 2016 +0200
@@ -74,6 +74,10 @@
                        const std::string& uri,
                        const std::string& body);
 
+  void ParseAssociativeArray(std::map<std::string, std::string>& target,
+                             const Json::Value& value,
+                             const std::string& key);
+
   namespace Configuration
   {
     void Initialize(OrthancPluginContext* context);
--- a/Plugin/Plugin.cpp	Thu Jun 23 17:31:40 2016 +0200
+++ b/Plugin/Plugin.cpp	Thu Jun 23 18:04:35 2016 +0200
@@ -29,6 +29,7 @@
 #include "DicomWebServers.h"
 
 #include "../Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h"
+#include "../Orthanc/Core/Toolbox.h"
 
 #include <gdcmDictEntry.h>
 #include <gdcmDict.h>
@@ -116,7 +117,7 @@
 
 
 void ListServerOperations(OrthancPluginRestOutput* output,
-                          const char* url,
+                          const char* /*url*/,
                           const OrthancPluginHttpRequest* request)
 {
   if (request->method != OrthancPluginHttpMethod_Get)
@@ -139,8 +140,69 @@
 
 
 
+static const char* GET_ARGUMENTS = "Arguments";
+
+
+static void UrlEncode(std::string& url,
+                      const Orthanc::WebServiceParameters& server,
+                      const std::string& uri,
+                      const std::map<std::string, std::string>& getArguments)
+{
+  url = server.GetUrl();
+  assert(!url.empty() && url[url.size() - 1] == '/');
+
+  if (uri.find('?') != std::string::npos)
+  {
+    OrthancPlugins::Configuration::LogError("The GET arguments must be provided in the \"" + 
+                                            std::string(GET_ARGUMENTS) + "\" field (\"?\" is disallowed): " + uri);
+    throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
+  }
+
+  // Remove the leading "/" in the URI if need be
+  std::string tmp;
+  if (!uri.empty() &&
+      uri[0] == '/')
+  {
+    url += uri.substr(1);
+  }
+  else
+  {
+    url += uri;
+  }
+
+  bool isFirst = true;
+  for (std::map<std::string, std::string>::const_iterator
+         it = getArguments.begin(); it != getArguments.end(); ++it)
+  {
+    if (isFirst)
+    {
+      url += '?';
+      isFirst = false;
+    }
+    else
+    {
+      url += '&';
+    }
+
+    std::string key, value;
+    Orthanc::Toolbox::UriEncode(key, it->first);
+    Orthanc::Toolbox::UriEncode(value, it->second);
+
+    if (value.empty())
+    {
+      url += key;
+    }
+    else
+    {
+      url += key + "=" + value;
+    }
+  }
+}
+                      
+
+
 void GetFromServer(OrthancPluginRestOutput* output,
-                   const char* url,
+                   const char* /*url*/,
                    const OrthancPluginHttpRequest* request)
 {
   if (request->method != OrthancPluginHttpMethod_Post)
@@ -151,7 +213,6 @@
 
   Orthanc::WebServiceParameters server(OrthancPlugins::DicomWebServers::GetInstance().GetServer(request->groups[0]));
 
-#if 0
   static const char* URI = "Uri";
   static const char* HTTP_HEADERS = "HttpHeaders";
 
@@ -162,15 +223,19 @@
       !body.isMember(URI) ||
       body[URI].type() != Json::stringValue)
   {
-    std::string s = ("A request to the DICOMweb STOW-RS client must provide a JSON object "
-                     "with the field \"Uri\" containing the URI of interest");
-    OrthancPluginLogError(OrthancPlugins::Configuration::GetContext(), s.c_str());
+    OrthancPlugins::Configuration::LogError("A request to the DICOMweb STOW-RS client must provide a JSON object "
+                                            "with the field \"Uri\" containing the URI of interest");
     throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
   }
 
-  std::map<std::string, std::string>
-  Json
-#endif
+  std::map<std::string, std::string> httpHeaders, getArguments;
+  OrthancPlugins::ParseAssociativeArray(httpHeaders, body, HTTP_HEADERS);
+  OrthancPlugins::ParseAssociativeArray(getArguments, body, GET_ARGUMENTS);
+
+  std::string url; 
+  UrlEncode(url, server, body[URI].asString(), getArguments);
+
+  printf("URL: [%s]\n", url.c_str());
 }
 
 
--- a/Plugin/StowRsClient.cpp	Thu Jun 23 17:31:40 2016 +0200
+++ b/Plugin/StowRsClient.cpp	Thu Jun 23 18:04:35 2016 +0200
@@ -221,36 +221,9 @@
     throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
   }
 
-  Json::Value& resources = body[RESOURCES];
-
-  if (body.isMember(HTTP_HEADERS))
-  {
-    const Json::Value& tmp = body[HTTP_HEADERS];
+  OrthancPlugins::ParseAssociativeArray(httpHeaders, body, HTTP_HEADERS);
 
-    if (tmp.type() != Json::objectValue)
-    {
-      OrthancPlugins::Configuration::LogError("The HTTP headers of a DICOMweb STOW-RS client request "
-                                              "must be given as a JSON associative array");
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-    }
-    else
-    {
-      Json::Value::Members names = tmp.getMemberNames();
-      for (size_t i = 0; i < names.size(); i++)
-      {
-        if (tmp[names[i]].type() != Json::stringValue)
-        {
-          OrthancPlugins::Configuration::LogError("The HTTP header \"" + names[i] + 
-                                                  "\" is not a string in some DICOMweb STOW-RS client request");
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-        }
-        else
-        {
-          httpHeaders[names[i]] = tmp[names[i]].asString();
-        }
-      }
-    }
-  }
+  Json::Value& resources = body[RESOURCES];
 
   // Extract information about all the child instances
   for (Json::Value::ArrayIndex i = 0; i < resources.size(); i++)