changeset 1363:feaf2840917c

Plugins now receive duplicated GET arguments in their REST callbacks
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 20 May 2015 15:21:26 +0200
parents bf6db7d2f8b1
children 111e23bb4904 4460e2622016
files Core/HttpServer/EmbeddedResourceHttpHandler.cpp Core/HttpServer/EmbeddedResourceHttpHandler.h Core/HttpServer/FilesystemHttpHandler.cpp Core/HttpServer/FilesystemHttpHandler.h Core/HttpServer/HttpHandler.cpp Core/HttpServer/HttpHandler.h Core/HttpServer/MongooseServer.cpp Core/RestApi/RestApi.cpp Core/RestApi/RestApi.h NEWS Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/OrthancPlugins.h UnitTestsSources/UnitTestsMain.cpp
diffstat 13 files changed, 115 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/Core/HttpServer/EmbeddedResourceHttpHandler.cpp	Fri May 15 17:33:43 2015 +0200
+++ b/Core/HttpServer/EmbeddedResourceHttpHandler.cpp	Wed May 20 15:21:26 2015 +0200
@@ -56,7 +56,7 @@
     HttpMethod method,
     const UriComponents& uri,
     const Arguments& headers,
-    const Arguments& arguments,
+    const GetArguments& arguments,
     const std::string&)
   {
     if (!Toolbox::IsChildUri(baseUri_, uri))
--- a/Core/HttpServer/EmbeddedResourceHttpHandler.h	Fri May 15 17:33:43 2015 +0200
+++ b/Core/HttpServer/EmbeddedResourceHttpHandler.h	Wed May 20 15:21:26 2015 +0200
@@ -55,7 +55,7 @@
       HttpMethod method,
       const UriComponents& uri,
       const Arguments& headers,
-      const Arguments& arguments,
+      const GetArguments& arguments,
       const std::string&);
   };
 }
--- a/Core/HttpServer/FilesystemHttpHandler.cpp	Fri May 15 17:33:43 2015 +0200
+++ b/Core/HttpServer/FilesystemHttpHandler.cpp	Wed May 20 15:21:26 2015 +0200
@@ -129,7 +129,7 @@
     HttpMethod method,
     const UriComponents& uri,
     const Arguments& headers,
-    const Arguments& arguments,
+    const GetArguments& arguments,
     const std::string&)
   {
     if (!Toolbox::IsChildUri(pimpl_->baseUri_, uri))
--- a/Core/HttpServer/FilesystemHttpHandler.h	Fri May 15 17:33:43 2015 +0200
+++ b/Core/HttpServer/FilesystemHttpHandler.h	Wed May 20 15:21:26 2015 +0200
@@ -57,7 +57,7 @@
       HttpMethod method,
       const UriComponents& uri,
       const Arguments& headers,
-      const Arguments& arguments,
+      const GetArguments& arguments,
       const std::string&);
 
     bool IsListDirectoryContent() const
--- a/Core/HttpServer/HttpHandler.cpp	Fri May 15 17:33:43 2015 +0200
+++ b/Core/HttpServer/HttpHandler.cpp	Wed May 20 15:21:26 2015 +0200
@@ -39,7 +39,7 @@
 
 namespace Orthanc
 {
-  static void SplitGETNameValue(HttpHandler::Arguments& result,
+  static void SplitGETNameValue(HttpHandler::GetArguments& result,
                                 const char* start,
                                 const char* end)
   {
@@ -60,11 +60,12 @@
     Toolbox::UrlDecode(name);
     Toolbox::UrlDecode(value);
 
-    result.insert(std::make_pair(name, value));
+    result.push_back(std::make_pair(name, value));
   }
 
 
-  void HttpHandler::ParseGetArguments(HttpHandler::Arguments& result, const char* query)
+  void HttpHandler::ParseGetArguments(HttpHandler::GetArguments& result, 
+                                      const char* query)
   {
     const char* pos = query;
 
@@ -87,7 +88,7 @@
 
 
   void  HttpHandler::ParseGetQuery(UriComponents& uri,
-                                   HttpHandler::Arguments& getArguments, 
+                                   HttpHandler::GetArguments& getArguments, 
                                    const char* query)
   {
     const char *questionMark = ::strchr(query, '?');
@@ -104,7 +105,7 @@
     }    
   }
 
-
+ 
   std::string HttpHandler::GetArgument(const Arguments& getArguments,
                                        const std::string& name,
                                        const std::string& defaultValue)
@@ -121,6 +122,22 @@
   }
 
 
+  std::string HttpHandler::GetArgument(const GetArguments& getArguments,
+                                       const std::string& name,
+                                       const std::string& defaultValue)
+  {
+    for (size_t i = 0; i < getArguments.size(); i++)
+    {
+      if (getArguments[i].first == name)
+      {
+        return getArguments[i].second;
+      }
+    }
+
+    return defaultValue;
+  }
+
+
 
   void HttpHandler::ParseCookies(HttpHandler::Arguments& result, 
                                  const HttpHandler::Arguments& httpHeaders)
@@ -159,4 +176,16 @@
       }
     }
   }
+
+
+  void HttpHandler::CompileGetArguments(Arguments& compiled,
+                                        const GetArguments& source)
+  {
+    compiled.clear();
+
+    for (size_t i = 0; i < source.size(); i++)
+    {
+      compiled[source[i].first] = source[i].second;
+    }
+  }
 }
--- a/Core/HttpServer/HttpHandler.h	Fri May 15 17:33:43 2015 +0200
+++ b/Core/HttpServer/HttpHandler.h	Wed May 20 15:21:26 2015 +0200
@@ -44,7 +44,8 @@
   class HttpHandler
   {
   public:
-    typedef std::map<std::string, std::string> Arguments;
+    typedef std::map<std::string, std::string>                  Arguments;
+    typedef std::vector< std::pair<std::string, std::string> >  GetArguments;
 
     virtual ~HttpHandler()
     {
@@ -54,21 +55,28 @@
                         HttpMethod method,
                         const UriComponents& uri,
                         const Arguments& headers,
-                        const Arguments& getArguments,
+                        const GetArguments& getArguments,
                         const std::string& postData) = 0;
 
-    static void ParseGetArguments(HttpHandler::Arguments& result, 
+    static void ParseGetArguments(HttpHandler::GetArguments& result, 
                                   const char* query);
 
     static void ParseGetQuery(UriComponents& uri,
-                              HttpHandler::Arguments& getArguments, 
+                              HttpHandler::GetArguments& getArguments, 
                               const char* query);
 
     static std::string GetArgument(const Arguments& getArguments,
                                    const std::string& name,
                                    const std::string& defaultValue);
 
+    static std::string GetArgument(const GetArguments& getArguments,
+                                   const std::string& name,
+                                   const std::string& defaultValue);
+
     static void ParseCookies(HttpHandler::Arguments& result, 
                              const HttpHandler::Arguments& httpHeaders);
+
+    static void CompileGetArguments(Arguments& compiled,
+                                    const GetArguments& source);
   };
 }
--- a/Core/HttpServer/MongooseServer.cpp	Fri May 15 17:33:43 2015 +0200
+++ b/Core/HttpServer/MongooseServer.cpp	Wed May 20 15:21:26 2015 +0200
@@ -466,7 +466,7 @@
   static bool ExtractMethod(HttpMethod& method,
                             const struct mg_request_info *request,
                             const HttpHandler::Arguments& headers,
-                            const HttpHandler::Arguments& argumentsGET)
+                            const HttpHandler::GetArguments& argumentsGET)
   {
     std::string overriden;
 
@@ -484,10 +484,13 @@
     {
       // 2. Faking with Ruby on Rail's approach
       // GET /my/resource?_method=delete <=> DELETE /my/resource
-      methodOverride = argumentsGET.find("_method");
-      if (methodOverride != argumentsGET.end())
+      for (size_t i = 0; i < argumentsGET.size(); i++)
       {
-        overriden = methodOverride->second;
+        if (argumentsGET[i].first == "_method")
+        {
+          overriden = argumentsGET[i].second;
+          break;
+        }
       }
     }
 
@@ -567,7 +570,7 @@
 
 
     // Extract the GET arguments
-    HttpHandler::Arguments argumentsGET;
+    HttpHandler::GetArguments argumentsGET;
     if (!strcmp(request->request_method, "GET"))
     {
       HttpHandler::ParseGetArguments(argumentsGET, request->query_string);
--- a/Core/RestApi/RestApi.cpp	Fri May 15 17:33:43 2015 +0200
+++ b/Core/RestApi/RestApi.cpp	Wed May 20 15:21:26 2015 +0200
@@ -160,7 +160,7 @@
                        HttpMethod method,
                        const UriComponents& uri,
                        const Arguments& headers,
-                       const Arguments& getArguments,
+                       const GetArguments& getArguments,
                        const std::string& postData)
   {
     RestApiOutput wrappedOutput(output);
@@ -188,7 +188,10 @@
     }
 #endif
 
-    HttpHandlerVisitor visitor(*this, wrappedOutput, method, headers, getArguments, postData);
+    Arguments compiled;
+    HttpHandler::CompileGetArguments(compiled, getArguments);
+
+    HttpHandlerVisitor visitor(*this, wrappedOutput, method, headers, compiled, postData);
 
     if (root_.LookupResource(uri, visitor))
     {
--- a/Core/RestApi/RestApi.h	Fri May 15 17:33:43 2015 +0200
+++ b/Core/RestApi/RestApi.h	Wed May 20 15:21:26 2015 +0200
@@ -50,7 +50,7 @@
                         HttpMethod method,
                         const UriComponents& uri,
                         const Arguments& headers,
-                        const Arguments& getArguments,
+                        const GetArguments& getArguments,
                         const std::string& postData);
 
     void Register(const std::string& path,
--- a/NEWS	Fri May 15 17:33:43 2015 +0200
+++ b/NEWS	Wed May 20 15:21:26 2015 +0200
@@ -23,6 +23,7 @@
   USE_SYSTEM_DCMTK is set to OFF (http://forum.dcmtk.org/viewtopic.php?f=1&t=4009)
 * Fix issue 30 (QR response missing "Query/Retrieve Level" (008,0052))
 * Fix issue 32 (Cyrillic symbols): Introduction of the "Windows1251" encoding
+* Plugins now receive duplicated GET arguments in their REST callbacks
 
 
 Version 0.8.6 (2015/02/12)
--- a/Plugins/Engine/OrthancPlugins.cpp	Fri May 15 17:33:43 2015 +0200
+++ b/Plugins/Engine/OrthancPlugins.cpp	Wed May 20 15:21:26 2015 +0200
@@ -303,11 +303,26 @@
   }
 
 
+  static void ArgumentsToPlugin(std::vector<const char*>& keys,
+                                std::vector<const char*>& values,
+                                const HttpHandler::GetArguments& arguments)
+  {
+    keys.resize(arguments.size());
+    values.resize(arguments.size());
+
+    for (size_t i = 0; i < arguments.size(); i++)
+    {
+      keys[i] = arguments[i].first.c_str();
+      values[i] = arguments[i].second.c_str();
+    }
+  }
+
+
   bool OrthancPlugins::Handle(HttpOutput& output,
                               HttpMethod method,
                               const UriComponents& uri,
                               const Arguments& headers,
-                              const Arguments& getArguments,
+                              const GetArguments& getArguments,
                               const std::string& postData)
   {
     std::string flatUri = Toolbox::FlattenUri(uri);
@@ -671,7 +686,7 @@
     std::string body;  // No body for a GET request
 
     UriComponents uri;
-    HttpHandler::Arguments getArguments;
+    HttpHandler::GetArguments getArguments;
     HttpHandler::ParseGetQuery(uri, getArguments, p.uri);
 
     StringHttpOutput stream;
@@ -714,7 +729,7 @@
       *reinterpret_cast<const _OrthancPluginRestApiPostPut*>(parameters);
 
     HttpHandler::Arguments headers;  // No HTTP header
-    HttpHandler::Arguments getArguments;  // No GET argument for POST/PUT
+    HttpHandler::GetArguments getArguments;  // No GET argument for POST/PUT
 
     UriComponents uri;
     Toolbox::SplitUriComponents(uri, p.uri);
@@ -763,7 +778,7 @@
     Toolbox::SplitUriComponents(uri, reinterpret_cast<const char*>(parameters));
 
     HttpHandler::Arguments headers;  // No HTTP header
-    HttpHandler::Arguments getArguments;  // No GET argument for POST/PUT
+    HttpHandler::GetArguments getArguments;  // No GET argument for POST/PUT
     std::string body;  // No body for DELETE
 
     StringHttpOutput stream;
--- a/Plugins/Engine/OrthancPlugins.h	Fri May 15 17:33:43 2015 +0200
+++ b/Plugins/Engine/OrthancPlugins.h	Wed May 20 15:21:26 2015 +0200
@@ -97,7 +97,7 @@
                         HttpMethod method,
                         const UriComponents& uri,
                         const Arguments& headers,
-                        const Arguments& getArguments,
+                        const GetArguments& getArguments,
                         const std::string& postData);
 
     virtual bool InvokeService(_OrthancPluginService service,
--- a/UnitTestsSources/UnitTestsMain.cpp	Fri May 15 17:33:43 2015 +0200
+++ b/UnitTestsSources/UnitTestsMain.cpp	Wed May 20 15:21:26 2015 +0200
@@ -177,8 +177,12 @@
 
 TEST(ParseGetArguments, Basic)
 {
+  HttpHandler::GetArguments b;
+  HttpHandler::ParseGetArguments(b, "aaa=baaa&bb=a&aa=c");
+
   HttpHandler::Arguments a;
-  HttpHandler::ParseGetArguments(a, "aaa=baaa&bb=a&aa=c");
+  HttpHandler::CompileGetArguments(a, b);
+
   ASSERT_EQ(3u, a.size());
   ASSERT_EQ(a["aaa"], "baaa");
   ASSERT_EQ(a["bb"], "a");
@@ -187,8 +191,12 @@
 
 TEST(ParseGetArguments, BasicEmpty)
 {
+  HttpHandler::GetArguments b;
+  HttpHandler::ParseGetArguments(b, "aaa&bb=aa&aa");
+
   HttpHandler::Arguments a;
-  HttpHandler::ParseGetArguments(a, "aaa&bb=aa&aa");
+  HttpHandler::CompileGetArguments(a, b);
+
   ASSERT_EQ(3u, a.size());
   ASSERT_EQ(a["aaa"], "");
   ASSERT_EQ(a["bb"], "aa");
@@ -197,16 +205,24 @@
 
 TEST(ParseGetArguments, Single)
 {
+  HttpHandler::GetArguments b;
+  HttpHandler::ParseGetArguments(b, "aaa=baaa");
+
   HttpHandler::Arguments a;
-  HttpHandler::ParseGetArguments(a, "aaa=baaa");
+  HttpHandler::CompileGetArguments(a, b);
+
   ASSERT_EQ(1u, a.size());
   ASSERT_EQ(a["aaa"], "baaa");
 }
 
 TEST(ParseGetArguments, SingleEmpty)
 {
+  HttpHandler::GetArguments b;
+  HttpHandler::ParseGetArguments(b, "aaa");
+
   HttpHandler::Arguments a;
-  HttpHandler::ParseGetArguments(a, "aaa");
+  HttpHandler::CompileGetArguments(a, b);
+
   ASSERT_EQ(1u, a.size());
   ASSERT_EQ(a["aaa"], "");
 }
@@ -214,8 +230,12 @@
 TEST(ParseGetQuery, Test1)
 {
   UriComponents uri;
+  HttpHandler::GetArguments b;
+  HttpHandler::ParseGetQuery(uri, b, "/instances/test/world?aaa=baaa&bb=a&aa=c");
+
   HttpHandler::Arguments a;
-  HttpHandler::ParseGetQuery(uri, a, "/instances/test/world?aaa=baaa&bb=a&aa=c");
+  HttpHandler::CompileGetArguments(a, b);
+
   ASSERT_EQ(3u, uri.size());
   ASSERT_EQ("instances", uri[0]);
   ASSERT_EQ("test", uri[1]);
@@ -229,8 +249,12 @@
 TEST(ParseGetQuery, Test2)
 {
   UriComponents uri;
+  HttpHandler::GetArguments b;
+  HttpHandler::ParseGetQuery(uri, b, "/instances/test/world");
+
   HttpHandler::Arguments a;
-  HttpHandler::ParseGetQuery(uri, a, "/instances/test/world");
+  HttpHandler::CompileGetArguments(a, b);
+
   ASSERT_EQ(3u, uri.size());
   ASSERT_EQ("instances", uri[0]);
   ASSERT_EQ("test", uri[1]);