# HG changeset patch # User Sebastien Jodogne # Date 1432128086 -7200 # Node ID feaf2840917c105383e1f1b0f4884cb0037fc7aa # Parent bf6db7d2f8b141343fb0085e039022337d5ca32c Plugins now receive duplicated GET arguments in their REST callbacks diff -r bf6db7d2f8b1 -r feaf2840917c Core/HttpServer/EmbeddedResourceHttpHandler.cpp --- 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)) diff -r bf6db7d2f8b1 -r feaf2840917c Core/HttpServer/EmbeddedResourceHttpHandler.h --- 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&); }; } diff -r bf6db7d2f8b1 -r feaf2840917c Core/HttpServer/FilesystemHttpHandler.cpp --- 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)) diff -r bf6db7d2f8b1 -r feaf2840917c Core/HttpServer/FilesystemHttpHandler.h --- 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 diff -r bf6db7d2f8b1 -r feaf2840917c Core/HttpServer/HttpHandler.cpp --- 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; + } + } } diff -r bf6db7d2f8b1 -r feaf2840917c Core/HttpServer/HttpHandler.h --- 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 Arguments; + typedef std::map Arguments; + typedef std::vector< std::pair > 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); }; } diff -r bf6db7d2f8b1 -r feaf2840917c Core/HttpServer/MongooseServer.cpp --- 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); diff -r bf6db7d2f8b1 -r feaf2840917c Core/RestApi/RestApi.cpp --- 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)) { diff -r bf6db7d2f8b1 -r feaf2840917c Core/RestApi/RestApi.h --- 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, diff -r bf6db7d2f8b1 -r feaf2840917c NEWS --- 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) diff -r bf6db7d2f8b1 -r feaf2840917c Plugins/Engine/OrthancPlugins.cpp --- 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& keys, + std::vector& 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(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(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; diff -r bf6db7d2f8b1 -r feaf2840917c Plugins/Engine/OrthancPlugins.h --- 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, diff -r bf6db7d2f8b1 -r feaf2840917c UnitTestsSources/UnitTestsMain.cpp --- 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]);