changeset 1441:f3672356c121

refactoring: IHttpHandler and HttpToolbox
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 01 Jul 2015 10:38:39 +0200
parents 3567503c00a7
children 4ff8dd753d79
files CMakeLists.txt Core/HttpServer/EmbeddedResourceHttpHandler.h Core/HttpServer/FilesystemHttpHandler.h Core/HttpServer/HttpHandler.cpp Core/HttpServer/HttpHandler.h Core/HttpServer/HttpOutput.h Core/HttpServer/HttpToolbox.cpp Core/HttpServer/HttpToolbox.h Core/HttpServer/IHttpHandler.h Core/HttpServer/MongooseServer.cpp Core/HttpServer/MongooseServer.h Core/RestApi/RestApi.cpp Core/RestApi/RestApi.h Core/RestApi/RestApiCall.h Core/RestApi/RestApiDeleteCall.h Core/RestApi/RestApiGetCall.cpp Core/RestApi/RestApiGetCall.h Core/RestApi/RestApiHierarchy.cpp Core/RestApi/RestApiHierarchy.h Core/RestApi/RestApiPath.cpp Core/RestApi/RestApiPath.h Core/RestApi/RestApiPostCall.h Core/RestApi/RestApiPutCall.h OrthancServer/LuaScripting.cpp OrthancServer/LuaScripting.h Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/OrthancPlugins.h UnitTestsSources/RestApiTests.cpp UnitTestsSources/UnitTestsMain.cpp
diffstat 29 files changed, 466 insertions(+), 422 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Wed Jul 01 10:18:26 2015 +0200
+++ b/CMakeLists.txt	Wed Jul 01 10:38:39 2015 +0200
@@ -98,7 +98,7 @@
   Core/HttpClient.cpp
   Core/HttpServer/EmbeddedResourceHttpHandler.cpp
   Core/HttpServer/FilesystemHttpHandler.cpp
-  Core/HttpServer/HttpHandler.cpp
+  Core/HttpServer/HttpToolbox.cpp
   Core/HttpServer/HttpOutput.cpp
   Core/HttpServer/StringHttpOutput.cpp
   Core/HttpServer/MongooseServer.cpp
--- a/Core/HttpServer/EmbeddedResourceHttpHandler.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/HttpServer/EmbeddedResourceHttpHandler.h	Wed Jul 01 10:38:39 2015 +0200
@@ -32,14 +32,14 @@
 
 #pragma once
 
-#include "HttpHandler.h"
+#include "IHttpHandler.h"
 
 #include <EmbeddedResources.h>   // Autogenerated file
 #include <boost/shared_ptr.hpp>
 
 namespace Orthanc
 {
-  class EmbeddedResourceHttpHandler : public HttpHandler
+  class EmbeddedResourceHttpHandler : public IHttpHandler
   {
   private:
     UriComponents baseUri_;
--- a/Core/HttpServer/FilesystemHttpHandler.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/HttpServer/FilesystemHttpHandler.h	Wed Jul 01 10:38:39 2015 +0200
@@ -32,13 +32,13 @@
 
 #pragma once
 
-#include "HttpHandler.h"
+#include "IHttpHandler.h"
 
 #include <boost/shared_ptr.hpp>
 
 namespace Orthanc
 {
-  class FilesystemHttpHandler : public HttpHandler
+  class FilesystemHttpHandler : public IHttpHandler
   {
   private:
     // PImpl idiom to avoid the inclusion of boost::filesystem
--- a/Core/HttpServer/HttpHandler.cpp	Wed Jul 01 10:18:26 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../PrecompiledHeaders.h"
-#include "HttpHandler.h"
-
-#include <string.h>
-#include <iostream>
-
-#include "HttpOutput.h"
-#include "StringHttpOutput.h"
-
-
-namespace Orthanc
-{
-  static void SplitGETNameValue(HttpHandler::GetArguments& result,
-                                const char* start,
-                                const char* end)
-  {
-    std::string name, value;
-    
-    const char* equal = strchr(start, '=');
-    if (equal == NULL || equal >= end)
-    {
-      name = std::string(start, end - start);
-      //value = "";
-    }
-    else
-    {
-      name = std::string(start, equal - start);
-      value = std::string(equal + 1, end);
-    }
-
-    Toolbox::UrlDecode(name);
-    Toolbox::UrlDecode(value);
-
-    result.push_back(std::make_pair(name, value));
-  }
-
-
-  void HttpHandler::ParseGetArguments(HttpHandler::GetArguments& result, 
-                                      const char* query)
-  {
-    const char* pos = query;
-
-    while (pos != NULL)
-    {
-      const char* ampersand = strchr(pos, '&');
-      if (ampersand)
-      {
-        SplitGETNameValue(result, pos, ampersand);
-        pos = ampersand + 1;
-      }
-      else
-      {
-        // No more ampersand, this is the last argument
-        SplitGETNameValue(result, pos, pos + strlen(pos));
-        pos = NULL;
-      }
-    }
-  }
-
-
-  void  HttpHandler::ParseGetQuery(UriComponents& uri,
-                                   HttpHandler::GetArguments& getArguments, 
-                                   const char* query)
-  {
-    const char *questionMark = ::strchr(query, '?');
-    if (questionMark == NULL)
-    {
-      // No question mark in the string
-      Toolbox::SplitUriComponents(uri, query);
-      getArguments.clear();
-    }
-    else
-    {
-      Toolbox::SplitUriComponents(uri, std::string(query, questionMark));
-      HttpHandler::ParseGetArguments(getArguments, questionMark + 1);
-    }    
-  }
-
- 
-  std::string HttpHandler::GetArgument(const Arguments& getArguments,
-                                       const std::string& name,
-                                       const std::string& defaultValue)
-  {
-    Arguments::const_iterator it = getArguments.find(name);
-    if (it == getArguments.end())
-    {
-      return defaultValue;
-    }
-    else
-    {
-      return it->second;
-    }
-  }
-
-
-  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)
-  {
-    result.clear();
-
-    HttpHandler::Arguments::const_iterator it = httpHeaders.find("cookie");
-    if (it != httpHeaders.end())
-    {
-      const std::string& cookies = it->second;
-
-      size_t pos = 0;
-      while (pos != std::string::npos)
-      {
-        size_t nextSemicolon = cookies.find(";", pos);
-        std::string cookie;
-
-        if (nextSemicolon == std::string::npos)
-        {
-          cookie = cookies.substr(pos);
-          pos = std::string::npos;
-        }
-        else
-        {
-          cookie = cookies.substr(pos, nextSemicolon - pos);
-          pos = nextSemicolon + 1;
-        }
-
-        size_t equal = cookie.find("=");
-        if (equal != std::string::npos)
-        {
-          std::string name = Toolbox::StripSpaces(cookie.substr(0, equal));
-          std::string value = Toolbox::StripSpaces(cookie.substr(equal + 1));
-          result[name] = value;
-        }
-      }
-    }
-  }
-
-
-  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;
-    }
-  }
-
-
-  bool HttpHandler::SimpleGet(std::string& output,
-                              const std::string& uri)
-  {
-    Arguments headers;  // No HTTP header
-    std::string body;  // No body for a GET request
-
-    UriComponents curi;
-    GetArguments getArguments;
-    ParseGetQuery(curi, getArguments, uri.c_str());
-
-    StringHttpOutput stream;
-    HttpOutput http(stream, false /* no keep alive */);
-
-    if (Handle(http, HttpMethod_Get, curi, headers, getArguments, body))
-    {
-      stream.GetOutput(output);
-      return true;
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-}
--- a/Core/HttpServer/HttpHandler.h	Wed Jul 01 10:18:26 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <map>
-#include <vector>
-#include <stdint.h>
-#include "../Toolbox.h"
-
-namespace Orthanc
-{
-  class HttpOutput;
-
-  class HttpHandler
-  {
-  public:
-    typedef std::map<std::string, std::string>                  Arguments;
-    typedef std::vector< std::pair<std::string, std::string> >  GetArguments;
-
-    virtual ~HttpHandler()
-    {
-    }
-
-    virtual bool Handle(HttpOutput& output,
-                        HttpMethod method,
-                        const UriComponents& uri,
-                        const Arguments& headers,
-                        const GetArguments& getArguments,
-                        const std::string& postData) = 0;
-
-    static void ParseGetArguments(HttpHandler::GetArguments& result, 
-                                  const char* query);
-
-    static void ParseGetQuery(UriComponents& uri,
-                              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);
-
-    bool SimpleGet(std::string& output,
-                   const std::string& uri);
-  };
-}
--- a/Core/HttpServer/HttpOutput.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/HttpServer/HttpOutput.h	Wed Jul 01 10:38:39 2015 +0200
@@ -37,7 +37,6 @@
 #include <stdint.h>
 #include "../Enumerations.h"
 #include "IHttpOutputStream.h"
-#include "HttpHandler.h"
 #include "../Uuid.h"
 
 namespace Orthanc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Core/HttpServer/HttpToolbox.cpp	Wed Jul 01 10:38:39 2015 +0200
@@ -0,0 +1,221 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * In addition, as a special exception, the copyright holders of this
+ * program give permission to link the code of its release with the
+ * OpenSSL project's "OpenSSL" library (or with modified versions of it
+ * that use the same license as the "OpenSSL" library), and distribute
+ * the linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s) with this exception, you may extend this exception to
+ * your version of the file(s), but you are not obligated to do so. If
+ * you do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source files
+ * in the program, then also delete it here.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "../PrecompiledHeaders.h"
+#include "HttpToolbox.h"
+
+#include <string.h>
+#include <iostream>
+
+#include "HttpOutput.h"
+#include "StringHttpOutput.h"
+
+
+namespace Orthanc
+{
+  static void SplitGETNameValue(IHttpHandler::GetArguments& result,
+                                const char* start,
+                                const char* end)
+  {
+    std::string name, value;
+    
+    const char* equal = strchr(start, '=');
+    if (equal == NULL || equal >= end)
+    {
+      name = std::string(start, end - start);
+      //value = "";
+    }
+    else
+    {
+      name = std::string(start, equal - start);
+      value = std::string(equal + 1, end);
+    }
+
+    Toolbox::UrlDecode(name);
+    Toolbox::UrlDecode(value);
+
+    result.push_back(std::make_pair(name, value));
+  }
+
+
+  void HttpToolbox::ParseGetArguments(IHttpHandler::GetArguments& result, 
+                                      const char* query)
+  {
+    const char* pos = query;
+
+    while (pos != NULL)
+    {
+      const char* ampersand = strchr(pos, '&');
+      if (ampersand)
+      {
+        SplitGETNameValue(result, pos, ampersand);
+        pos = ampersand + 1;
+      }
+      else
+      {
+        // No more ampersand, this is the last argument
+        SplitGETNameValue(result, pos, pos + strlen(pos));
+        pos = NULL;
+      }
+    }
+  }
+
+
+  void  HttpToolbox::ParseGetQuery(UriComponents& uri,
+                                   IHttpHandler::GetArguments& getArguments, 
+                                   const char* query)
+  {
+    const char *questionMark = ::strchr(query, '?');
+    if (questionMark == NULL)
+    {
+      // No question mark in the string
+      Toolbox::SplitUriComponents(uri, query);
+      getArguments.clear();
+    }
+    else
+    {
+      Toolbox::SplitUriComponents(uri, std::string(query, questionMark));
+      HttpToolbox::ParseGetArguments(getArguments, questionMark + 1);
+    }    
+  }
+
+ 
+  std::string HttpToolbox::GetArgument(const IHttpHandler::Arguments& getArguments,
+                                       const std::string& name,
+                                       const std::string& defaultValue)
+  {
+    IHttpHandler::Arguments::const_iterator it = getArguments.find(name);
+    if (it == getArguments.end())
+    {
+      return defaultValue;
+    }
+    else
+    {
+      return it->second;
+    }
+  }
+
+
+  std::string HttpToolbox::GetArgument(const IHttpHandler::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 HttpToolbox::ParseCookies(IHttpHandler::Arguments& result, 
+                                 const IHttpHandler::Arguments& httpHeaders)
+  {
+    result.clear();
+
+    IHttpHandler::Arguments::const_iterator it = httpHeaders.find("cookie");
+    if (it != httpHeaders.end())
+    {
+      const std::string& cookies = it->second;
+
+      size_t pos = 0;
+      while (pos != std::string::npos)
+      {
+        size_t nextSemicolon = cookies.find(";", pos);
+        std::string cookie;
+
+        if (nextSemicolon == std::string::npos)
+        {
+          cookie = cookies.substr(pos);
+          pos = std::string::npos;
+        }
+        else
+        {
+          cookie = cookies.substr(pos, nextSemicolon - pos);
+          pos = nextSemicolon + 1;
+        }
+
+        size_t equal = cookie.find("=");
+        if (equal != std::string::npos)
+        {
+          std::string name = Toolbox::StripSpaces(cookie.substr(0, equal));
+          std::string value = Toolbox::StripSpaces(cookie.substr(equal + 1));
+          result[name] = value;
+        }
+      }
+    }
+  }
+
+
+  void HttpToolbox::CompileGetArguments(IHttpHandler::Arguments& compiled,
+                                        const IHttpHandler::GetArguments& source)
+  {
+    compiled.clear();
+
+    for (size_t i = 0; i < source.size(); i++)
+    {
+      compiled[source[i].first] = source[i].second;
+    }
+  }
+
+
+  bool HttpToolbox::SimpleGet(std::string& output,
+                              IHttpHandler& handler,
+                              const std::string& uri)
+  {
+    IHttpHandler::Arguments headers;  // No HTTP header
+    std::string body;  // No body for a GET request
+
+    UriComponents curi;
+    IHttpHandler::GetArguments getArguments;
+    ParseGetQuery(curi, getArguments, uri.c_str());
+
+    StringHttpOutput stream;
+    HttpOutput http(stream, false /* no keep alive */);
+
+    if (handler.Handle(http, HttpMethod_Get, curi, headers, getArguments, body))
+    {
+      stream.GetOutput(output);
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Core/HttpServer/HttpToolbox.h	Wed Jul 01 10:38:39 2015 +0200
@@ -0,0 +1,67 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * In addition, as a special exception, the copyright holders of this
+ * program give permission to link the code of its release with the
+ * OpenSSL project's "OpenSSL" library (or with modified versions of it
+ * that use the same license as the "OpenSSL" library), and distribute
+ * the linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s) with this exception, you may extend this exception to
+ * your version of the file(s), but you are not obligated to do so. If
+ * you do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source files
+ * in the program, then also delete it here.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "IHttpHandler.h"
+
+namespace Orthanc
+{
+  class HttpToolbox
+  {
+  public:
+    static void ParseGetArguments(IHttpHandler::GetArguments& result, 
+                                  const char* query);
+
+    static void ParseGetQuery(UriComponents& uri,
+                              IHttpHandler::GetArguments& getArguments, 
+                              const char* query);
+
+    static std::string GetArgument(const IHttpHandler::Arguments& getArguments,
+                                   const std::string& name,
+                                   const std::string& defaultValue);
+
+    static std::string GetArgument(const IHttpHandler::GetArguments& getArguments,
+                                   const std::string& name,
+                                   const std::string& defaultValue);
+
+    static void ParseCookies(IHttpHandler::Arguments& result, 
+                             const IHttpHandler::Arguments& httpHeaders);
+
+    static void CompileGetArguments(IHttpHandler::Arguments& compiled,
+                                    const IHttpHandler::GetArguments& source);
+
+    static bool SimpleGet(std::string& output,
+                          IHttpHandler& handler,
+                          const std::string& uri);
+  };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Core/HttpServer/IHttpHandler.h	Wed Jul 01 10:38:39 2015 +0200
@@ -0,0 +1,61 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * In addition, as a special exception, the copyright holders of this
+ * program give permission to link the code of its release with the
+ * OpenSSL project's "OpenSSL" library (or with modified versions of it
+ * that use the same license as the "OpenSSL" library), and distribute
+ * the linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s) with this exception, you may extend this exception to
+ * your version of the file(s), but you are not obligated to do so. If
+ * you do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source files
+ * in the program, then also delete it here.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "../Enumerations.h"
+#include "HttpOutput.h"
+
+#include <map>
+#include <vector>
+#include <string>
+
+namespace Orthanc
+{
+  class IHttpHandler : public boost::noncopyable
+  {
+  public:
+    typedef std::map<std::string, std::string>                  Arguments;
+    typedef std::vector< std::pair<std::string, std::string> >  GetArguments;
+
+    virtual ~IHttpHandler()
+    {
+    }
+
+    virtual bool Handle(HttpOutput& output,
+                        HttpMethod method,
+                        const UriComponents& uri,
+                        const Arguments& headers,
+                        const GetArguments& getArguments,
+                        const std::string& postData) = 0;
+  };
+}
--- a/Core/HttpServer/MongooseServer.cpp	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/HttpServer/MongooseServer.cpp	Wed Jul 01 10:38:39 2015 +0200
@@ -47,7 +47,7 @@
 
 #include "../OrthancException.h"
 #include "../ChunkedBuffer.h"
-#include "HttpOutput.h"
+#include "HttpToolbox.h"
 #include "mongoose.h"
 
 #if ORTHANC_SSL_ENABLED == 1
@@ -267,9 +267,9 @@
 
   static PostDataStatus ReadBody(std::string& postData,
                                  struct mg_connection *connection,
-                                 const HttpHandler::Arguments& headers)
+                                 const IHttpHandler::Arguments& headers)
   {
-    HttpHandler::Arguments::const_iterator cs = headers.find("content-length");
+    IHttpHandler::Arguments::const_iterator cs = headers.find("content-length");
     if (cs == headers.end())
     {
       return PostDataStatus_NoLength;
@@ -313,7 +313,7 @@
 
   static PostDataStatus ParseMultipartPost(std::string &completedFile,
                                            struct mg_connection *connection,
-                                           const HttpHandler::Arguments& headers,
+                                           const IHttpHandler::Arguments& headers,
                                            const std::string& contentType,
                                            ChunkStore& chunkStore)
   {
@@ -327,13 +327,13 @@
       return status;
     }
 
-    /*for (HttpHandler::Arguments::const_iterator i = headers.begin(); i != headers.end(); i++)
+    /*for (IHttpHandler::Arguments::const_iterator i = headers.begin(); i != headers.end(); i++)
       {
       std::cout << "Header [" << i->first << "] = " << i->second << "\n";
       }
       printf("CHUNK\n");*/
 
-    typedef HttpHandler::Arguments::const_iterator ArgumentIterator;
+    typedef IHttpHandler::Arguments::const_iterator ArgumentIterator;
 
     ArgumentIterator requestedWith = headers.find("x-requested-with");
     ArgumentIterator fileName = headers.find("x-file-name");
@@ -415,11 +415,11 @@
 
 
   static bool IsAccessGranted(const MongooseServer& that,
-                              const HttpHandler::Arguments& headers)
+                              const IHttpHandler::Arguments& headers)
   {
     bool granted = false;
 
-    HttpHandler::Arguments::const_iterator auth = headers.find("authorization");
+    IHttpHandler::Arguments::const_iterator auth = headers.find("authorization");
     if (auth != headers.end())
     {
       std::string s = auth->second;
@@ -435,9 +435,9 @@
   }
 
 
-  static std::string GetAuthenticatedUsername(const HttpHandler::Arguments& headers)
+  static std::string GetAuthenticatedUsername(const IHttpHandler::Arguments& headers)
   {
-    HttpHandler::Arguments::const_iterator auth = headers.find("authorization");
+    IHttpHandler::Arguments::const_iterator auth = headers.find("authorization");
 
     if (auth == headers.end())
     {
@@ -470,15 +470,15 @@
 
   static bool ExtractMethod(HttpMethod& method,
                             const struct mg_request_info *request,
-                            const HttpHandler::Arguments& headers,
-                            const HttpHandler::GetArguments& argumentsGET)
+                            const IHttpHandler::Arguments& headers,
+                            const IHttpHandler::GetArguments& argumentsGET)
   {
     std::string overriden;
 
     // Check whether some PUT/DELETE faking is done
 
     // 1. Faking with Google's approach
-    HttpHandler::Arguments::const_iterator methodOverride =
+    IHttpHandler::Arguments::const_iterator methodOverride =
       headers.find("x-http-method-override");
 
     if (methodOverride != headers.end())
@@ -565,7 +565,7 @@
 
 
     // Extract the HTTP headers
-    HttpHandler::Arguments headers;
+    IHttpHandler::Arguments headers;
     for (int i = 0; i < request->num_headers; i++)
     {
       std::string name = request->http_headers[i].name;
@@ -575,10 +575,10 @@
 
 
     // Extract the GET arguments
-    HttpHandler::GetArguments argumentsGET;
+    IHttpHandler::GetArguments argumentsGET;
     if (!strcmp(request->request_method, "GET"))
     {
-      HttpHandler::ParseGetArguments(argumentsGET, request->query_string);
+      HttpToolbox::ParseGetArguments(argumentsGET, request->query_string);
     }
 
 
@@ -627,7 +627,7 @@
     {
       PostDataStatus status;
 
-      HttpHandler::Arguments::const_iterator ct = headers.find("content-type");
+      IHttpHandler::Arguments::const_iterator ct = headers.find("content-type");
       if (ct == headers.end())
       {
         // No content-type specified. Assume no multi-part content occurs at this point.
@@ -876,7 +876,7 @@
   }
 
 
-  void MongooseServer::RegisterHandler(HttpHandler& handler)
+  void MongooseServer::RegisterHandler(IHttpHandler& handler)
   {
     Stop();
 
--- a/Core/HttpServer/MongooseServer.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/HttpServer/MongooseServer.h	Wed Jul 01 10:38:39 2015 +0200
@@ -32,7 +32,7 @@
 
 #pragma once
 
-#include "HttpHandler.h"
+#include "IHttpHandler.h"
 
 #include <list>
 #include <map>
@@ -60,7 +60,7 @@
   class MongooseServer
   {
   public:
-    typedef std::list<HttpHandler*> Handlers;
+    typedef std::list<IHttpHandler*> Handlers;
 
   private:
     // http://stackoverflow.com/questions/311166/stdauto-ptr-or-boostshared-ptr-for-pimpl-idiom
@@ -103,7 +103,7 @@
     void RegisterUser(const char* username,
                       const char* password);
 
-    void RegisterHandler(HttpHandler& handler);
+    void RegisterHandler(IHttpHandler& handler);
 
     bool IsAuthenticationEnabled() const
     {
--- a/Core/RestApi/RestApi.cpp	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApi.cpp	Wed Jul 01 10:38:39 2015 +0200
@@ -49,16 +49,16 @@
       RestApi& api_;
       RestApiOutput& output_;
       HttpMethod method_;
-      const HttpHandler::Arguments& headers_;
-      const HttpHandler::Arguments& getArguments_;
+      const IHttpHandler::Arguments& headers_;
+      const IHttpHandler::Arguments& getArguments_;
       const std::string& postData_;
 
     public:
       HttpHandlerVisitor(RestApi& api,
                          RestApiOutput& output,
                          HttpMethod method,
-                         const HttpHandler::Arguments& headers,
-                         const HttpHandler::Arguments& getArguments,
+                         const IHttpHandler::Arguments& headers,
+                         const IHttpHandler::Arguments& getArguments,
                          const std::string& postData) :
         api_(api),
         output_(output),
@@ -71,7 +71,7 @@
 
       virtual bool Visit(const RestApiHierarchy::Resource& resource,
                          const UriComponents& uri,
-                         const HttpHandler::Arguments& components,
+                         const IHttpHandler::Arguments& components,
                          const UriComponents& trailing)
       {
         if (resource.HasHandler(method_))
@@ -189,7 +189,7 @@
 #endif
 
     Arguments compiled;
-    HttpHandler::CompileGetArguments(compiled, getArguments);
+    HttpToolbox::CompileGetArguments(compiled, getArguments);
 
     HttpHandlerVisitor visitor(*this, wrappedOutput, method, headers, compiled, postData);
 
--- a/Core/RestApi/RestApi.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApi.h	Wed Jul 01 10:38:39 2015 +0200
@@ -38,7 +38,7 @@
 
 namespace Orthanc
 {
-  class RestApi : public HttpHandler
+  class RestApi : public IHttpHandler
   {
   private:
     RestApiHierarchy root_;
--- a/Core/RestApi/RestApiCall.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApiCall.h	Wed Jul 01 10:38:39 2015 +0200
@@ -32,7 +32,8 @@
 
 #pragma once
 
-#include "../HttpServer/HttpHandler.h"
+#include "../HttpServer/IHttpHandler.h"
+#include "../HttpServer/HttpToolbox.h"
 #include "RestApiPath.h"
 #include "RestApiOutput.h"
 
@@ -47,8 +48,8 @@
   private:
     RestApiOutput& output_;
     RestApi& context_;
-    const HttpHandler::Arguments& httpHeaders_;
-    const HttpHandler::Arguments& uriComponents_;
+    const IHttpHandler::Arguments& httpHeaders_;
+    const IHttpHandler::Arguments& uriComponents_;
     const UriComponents& trailing_;
     const UriComponents& fullUri_;
 
@@ -59,8 +60,8 @@
   public:
     RestApiCall(RestApiOutput& output,
                 RestApi& context,
-                const HttpHandler::Arguments& httpHeaders,
-                const HttpHandler::Arguments& uriComponents,
+                const IHttpHandler::Arguments& httpHeaders,
+                const IHttpHandler::Arguments& uriComponents,
                 const UriComponents& trailing,
                 const UriComponents& fullUri) :
       output_(output),
@@ -95,23 +96,23 @@
     std::string GetUriComponent(const std::string& name,
                                 const std::string& defaultValue) const
     {
-      return HttpHandler::GetArgument(uriComponents_, name, defaultValue);
+      return HttpToolbox::GetArgument(uriComponents_, name, defaultValue);
     }
 
     std::string GetHttpHeader(const std::string& name,
                               const std::string& defaultValue) const
     {
-      return HttpHandler::GetArgument(httpHeaders_, name, defaultValue);
+      return HttpToolbox::GetArgument(httpHeaders_, name, defaultValue);
     }
 
-    const HttpHandler::Arguments& GetHttpHeaders() const
+    const IHttpHandler::Arguments& GetHttpHeaders() const
     {
       return httpHeaders_;
     }
 
-    void ParseCookies(HttpHandler::Arguments& result) const
+    void ParseCookies(IHttpHandler::Arguments& result) const
     {
-      HttpHandler::ParseCookies(result, httpHeaders_);
+      HttpToolbox::ParseCookies(result, httpHeaders_);
     }
 
     std::string FlattenUri() const;
--- a/Core/RestApi/RestApiDeleteCall.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApiDeleteCall.h	Wed Jul 01 10:38:39 2015 +0200
@@ -43,8 +43,8 @@
     
     RestApiDeleteCall(RestApiOutput& output,
                       RestApi& context,
-                      const HttpHandler::Arguments& httpHeaders,
-                      const HttpHandler::Arguments& uriComponents,
+                      const IHttpHandler::Arguments& httpHeaders,
+                      const IHttpHandler::Arguments& uriComponents,
                       const UriComponents& trailing,
                       const UriComponents& fullUri) :
       RestApiCall(output, context, httpHeaders, uriComponents, trailing, fullUri)
--- a/Core/RestApi/RestApiGetCall.cpp	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApiGetCall.cpp	Wed Jul 01 10:38:39 2015 +0200
@@ -38,7 +38,7 @@
   {
     result.clear();
 
-    for (HttpHandler::Arguments::const_iterator 
+    for (IHttpHandler::Arguments::const_iterator 
            it = getArguments_.begin(); it != getArguments_.end(); ++it)
     {
       result[it->first] = it->second;
--- a/Core/RestApi/RestApiGetCall.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApiGetCall.h	Wed Jul 01 10:38:39 2015 +0200
@@ -39,18 +39,18 @@
   class RestApiGetCall : public RestApiCall
   {
   private:
-    const HttpHandler::Arguments& getArguments_;
+    const IHttpHandler::Arguments& getArguments_;
 
   public:
     typedef void (*Handler) (RestApiGetCall& call);   
 
     RestApiGetCall(RestApiOutput& output,
                    RestApi& context,
-                   const HttpHandler::Arguments& httpHeaders,
-                   const HttpHandler::Arguments& uriComponents,
+                   const IHttpHandler::Arguments& httpHeaders,
+                   const IHttpHandler::Arguments& uriComponents,
                    const UriComponents& trailing,
                    const UriComponents& fullUri,
-                   const HttpHandler::Arguments& getArguments) :
+                   const IHttpHandler::Arguments& getArguments) :
       RestApiCall(output, context, httpHeaders, uriComponents, trailing, fullUri),
       getArguments_(getArguments)
     {
@@ -59,7 +59,7 @@
     std::string GetArgument(const std::string& name,
                             const std::string& defaultValue) const
     {
-      return HttpHandler::GetArgument(getArguments_, name, defaultValue);
+      return HttpToolbox::GetArgument(getArguments_, name, defaultValue);
     }
 
     bool HasArgument(const std::string& name) const
--- a/Core/RestApi/RestApiHierarchy.cpp	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApiHierarchy.cpp	Wed Jul 01 10:38:39 2015 +0200
@@ -199,7 +199,7 @@
   }
 
 
-  bool RestApiHierarchy::LookupResource(HttpHandler::Arguments& components,
+  bool RestApiHierarchy::LookupResource(IHttpHandler::Arguments& components,
                                        const UriComponents& uri,
                                        IVisitor& visitor,
                                        size_t level)
@@ -240,7 +240,7 @@
       for (child = wildcardChildren_.begin();
            child != wildcardChildren_.end(); ++child)
       {
-        HttpHandler::Arguments subComponents = components;
+        IHttpHandler::Arguments subComponents = components;
         subComponents[child->first] = uri[level];
 
         if (child->second->LookupResource(subComponents, uri, visitor, level + 1))
@@ -404,7 +404,7 @@
   bool RestApiHierarchy::LookupResource(const UriComponents& uri,
                                         IVisitor& visitor)
   {
-    HttpHandler::Arguments components;
+    IHttpHandler::Arguments components;
     return LookupResource(components, uri, visitor, 0);
   }    
 
@@ -426,7 +426,7 @@
 
       virtual bool Visit(const RestApiHierarchy::Resource& resource,
                          const UriComponents& uri,
-                         const HttpHandler::Arguments& components,
+                         const IHttpHandler::Arguments& components,
                          const UriComponents& trailing)
       {
         if (trailing.size() == 0)  // Ignore universal handlers
@@ -460,7 +460,7 @@
   void RestApiHierarchy::GetAcceptedMethods(std::set<HttpMethod>& methods,
                                             const UriComponents& uri)
   {
-    HttpHandler::Arguments components;
+    IHttpHandler::Arguments components;
     AcceptedMethodsVisitor visitor(methods);
     LookupResource(components, uri, visitor, 0);
 
--- a/Core/RestApi/RestApiHierarchy.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApiHierarchy.h	Wed Jul 01 10:38:39 2015 +0200
@@ -98,7 +98,7 @@
 
       virtual bool Visit(const Resource& resource,
                          const UriComponents& uri,
-                         const HttpHandler::Arguments& components,
+                         const IHttpHandler::Arguments& components,
                          const UriComponents& trailing) = 0;
     };
 
@@ -123,7 +123,7 @@
 
     bool CanGenerateDirectory() const;
 
-    bool LookupResource(HttpHandler::Arguments& components,
+    bool LookupResource(IHttpHandler::Arguments& components,
                         const UriComponents& uri,
                         IVisitor& visitor,
                         size_t level);
--- a/Core/RestApi/RestApiPath.cpp	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApiPath.cpp	Wed Jul 01 10:38:39 2015 +0200
@@ -78,7 +78,7 @@
     }
   }
 
-  bool RestApiPath::Match(HttpHandler::Arguments& components,
+  bool RestApiPath::Match(IHttpHandler::Arguments& components,
                           UriComponents& trailing,
                           const std::string& uriRaw) const
   {
@@ -87,7 +87,7 @@
     return Match(components, trailing, uri);
   }
 
-  bool RestApiPath::Match(HttpHandler::Arguments& components,
+  bool RestApiPath::Match(IHttpHandler::Arguments& components,
                           UriComponents& trailing,
                           const UriComponents& uri) const
   {
@@ -135,7 +135,7 @@
 
   bool RestApiPath::Match(const UriComponents& uri) const
   {
-    HttpHandler::Arguments components;
+    IHttpHandler::Arguments components;
     UriComponents trailing;
     return Match(components, trailing, uri);
   }
--- a/Core/RestApi/RestApiPath.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApiPath.h	Wed Jul 01 10:38:39 2015 +0200
@@ -33,7 +33,7 @@
 #pragma once
 
 #include "../Toolbox.h"
-#include "../HttpServer/HttpHandler.h"
+#include "../HttpServer/IHttpHandler.h"
 
 #include <map>
 
@@ -50,11 +50,11 @@
     RestApiPath(const std::string& uri);
 
     // This version is slower
-    bool Match(HttpHandler::Arguments& components,
+    bool Match(IHttpHandler::Arguments& components,
                UriComponents& trailing,
                const std::string& uriRaw) const;
 
-    bool Match(HttpHandler::Arguments& components,
+    bool Match(IHttpHandler::Arguments& components,
                UriComponents& trailing,
                const UriComponents& uri) const;
 
--- a/Core/RestApi/RestApiPostCall.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApiPostCall.h	Wed Jul 01 10:38:39 2015 +0200
@@ -46,8 +46,8 @@
     
     RestApiPostCall(RestApiOutput& output,
                     RestApi& context,
-                    const HttpHandler::Arguments& httpHeaders,
-                    const HttpHandler::Arguments& uriComponents,
+                    const IHttpHandler::Arguments& httpHeaders,
+                    const IHttpHandler::Arguments& uriComponents,
                     const UriComponents& trailing,
                     const UriComponents& fullUri,
                     const std::string& data) :
--- a/Core/RestApi/RestApiPutCall.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Core/RestApi/RestApiPutCall.h	Wed Jul 01 10:38:39 2015 +0200
@@ -46,8 +46,8 @@
     
     RestApiPutCall(RestApiOutput& output,
                    RestApi& context,
-                   const HttpHandler::Arguments& httpHeaders,
-                   const HttpHandler::Arguments& uriComponents,
+                   const IHttpHandler::Arguments& httpHeaders,
+                   const IHttpHandler::Arguments& uriComponents,
                    const UriComponents& trailing,
                    const UriComponents& fullUri,
                    const std::string& data) :
--- a/OrthancServer/LuaScripting.cpp	Wed Jul 01 10:18:26 2015 +0200
+++ b/OrthancServer/LuaScripting.cpp	Wed Jul 01 10:38:39 2015 +0200
@@ -80,7 +80,7 @@
     const char* uri = lua_tostring(state, 1);
     
     std::string str;
-    if (restApi->SimpleGet(str, uri))
+    if (HttpToolbox::SimpleGet(str, *restApi, uri))
     {
       lua_pushstring(state, str.c_str());
     }
--- a/OrthancServer/LuaScripting.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/OrthancServer/LuaScripting.h	Wed Jul 01 10:38:39 2015 +0200
@@ -46,7 +46,7 @@
   private:
     static OrthancRestApi* GetRestApi(lua_State *state);
 
-    static int RestApiGet(lua_State *state);
+    static int OrthancApiGet(lua_State *state);
 
     void ApplyOnStoredInstance(const std::string& instanceId,
                                const Json::Value& simplifiedDicom,
--- a/Plugins/Engine/OrthancPlugins.cpp	Wed Jul 01 10:18:26 2015 +0200
+++ b/Plugins/Engine/OrthancPlugins.cpp	Wed Jul 01 10:38:39 2015 +0200
@@ -195,13 +195,13 @@
 
   static void ArgumentsToPlugin(std::vector<const char*>& keys,
                                 std::vector<const char*>& values,
-                                const HttpHandler::Arguments& arguments)
+                                const IHttpHandler::Arguments& arguments)
   {
     keys.resize(arguments.size());
     values.resize(arguments.size());
 
     size_t pos = 0;
-    for (HttpHandler::Arguments::const_iterator 
+    for (IHttpHandler::Arguments::const_iterator 
            it = arguments.begin(); it != arguments.end(); ++it)
     {
       keys[pos] = it->first.c_str();
@@ -213,7 +213,7 @@
 
   static void ArgumentsToPlugin(std::vector<const char*>& keys,
                                 std::vector<const char*>& values,
-                                const HttpHandler::GetArguments& arguments)
+                                const IHttpHandler::GetArguments& arguments)
   {
     keys.resize(arguments.size());
     values.resize(arguments.size());
@@ -616,14 +616,14 @@
     const _OrthancPluginRestApiGet& p = 
       *reinterpret_cast<const _OrthancPluginRestApiGet*>(parameters);
         
-    // TODO : Use "HttpHandler::SimpleGet()"
+    // TODO : Use "HttpToolbox::SimpleGet()"
 
-    HttpHandler::Arguments headers;  // No HTTP header
+    IHttpHandler::Arguments headers;  // No HTTP header
     std::string body;  // No body for a GET request
 
     UriComponents uri;
-    HttpHandler::GetArguments getArguments;
-    HttpHandler::ParseGetQuery(uri, getArguments, p.uri);
+    IHttpHandler::GetArguments getArguments;
+    HttpToolbox::ParseGetQuery(uri, getArguments, p.uri);
 
     StringHttpOutput stream;
     HttpOutput http(stream, false /* no keep alive */);
@@ -664,8 +664,8 @@
     const _OrthancPluginRestApiPostPut& p = 
       *reinterpret_cast<const _OrthancPluginRestApiPostPut*>(parameters);
 
-    HttpHandler::Arguments headers;  // No HTTP header
-    HttpHandler::GetArguments getArguments;  // No GET argument for POST/PUT
+    IHttpHandler::Arguments headers;  // No HTTP header
+    IHttpHandler::GetArguments getArguments;  // No GET argument for POST/PUT
 
     UriComponents uri;
     Toolbox::SplitUriComponents(uri, p.uri);
@@ -713,8 +713,8 @@
     UriComponents uri;
     Toolbox::SplitUriComponents(uri, reinterpret_cast<const char*>(parameters));
 
-    HttpHandler::Arguments headers;  // No HTTP header
-    HttpHandler::GetArguments getArguments;  // No GET argument for POST/PUT
+    IHttpHandler::Arguments headers;  // No HTTP header
+    IHttpHandler::GetArguments getArguments;  // No GET argument for POST/PUT
     std::string body;  // No body for DELETE
 
     StringHttpOutput stream;
--- a/Plugins/Engine/OrthancPlugins.h	Wed Jul 01 10:18:26 2015 +0200
+++ b/Plugins/Engine/OrthancPlugins.h	Wed Jul 01 10:38:39 2015 +0200
@@ -33,7 +33,7 @@
 #pragma once
 
 #include "../../Core/FileStorage/IStorageArea.h"
-#include "../../Core/HttpServer/HttpHandler.h"
+#include "../../Core/HttpServer/IHttpHandler.h"
 #include "../../OrthancServer/IServerListener.h"
 #include "OrthancPluginDatabase.h"
 #include "PluginsManager.h"
@@ -47,7 +47,7 @@
   class ServerContext;
 
   class OrthancPlugins : 
-    public HttpHandler, 
+    public IHttpHandler, 
     public IPluginServiceProvider, 
     public IServerListener
   {
--- a/UnitTestsSources/RestApiTests.cpp	Wed Jul 01 10:18:26 2015 +0200
+++ b/UnitTestsSources/RestApiTests.cpp	Wed Jul 01 10:38:39 2015 +0200
@@ -93,11 +93,11 @@
 
 TEST(RestApi, ParseCookies)
 {
-  HttpHandler::Arguments headers;
-  HttpHandler::Arguments cookies;
+  IHttpHandler::Arguments headers;
+  IHttpHandler::Arguments cookies;
 
   headers["cookie"] = "a=b;c=d;;;e=f;;g=h;";
-  HttpHandler::ParseCookies(cookies, headers);
+  HttpToolbox::ParseCookies(cookies, headers);
   ASSERT_EQ(4u, cookies.size());
   ASSERT_EQ("b", cookies["a"]);
   ASSERT_EQ("d", cookies["c"]);
@@ -105,24 +105,24 @@
   ASSERT_EQ("h", cookies["g"]);
 
   headers["cookie"] = "  name =  value  ; name2=value2";
-  HttpHandler::ParseCookies(cookies, headers);
+  HttpToolbox::ParseCookies(cookies, headers);
   ASSERT_EQ(2u, cookies.size());
   ASSERT_EQ("value", cookies["name"]);
   ASSERT_EQ("value2", cookies["name2"]);
 
   headers["cookie"] = "  ;;;    ";
-  HttpHandler::ParseCookies(cookies, headers);
+  HttpToolbox::ParseCookies(cookies, headers);
   ASSERT_EQ(0u, cookies.size());
 
   headers["cookie"] = "  ;   n=v  ;;    ";
-  HttpHandler::ParseCookies(cookies, headers);
+  HttpToolbox::ParseCookies(cookies, headers);
   ASSERT_EQ(1u, cookies.size());
   ASSERT_EQ("v", cookies["n"]);
 }
 
 TEST(RestApi, RestApiPath)
 {
-  HttpHandler::Arguments args;
+  IHttpHandler::Arguments args;
   UriComponents trail;
 
   {
@@ -220,7 +220,7 @@
   public:
     virtual bool Visit(const RestApiHierarchy::Resource& resource,
                        const UriComponents& uri,
-                       const HttpHandler::Arguments& components,
+                       const IHttpHandler::Arguments& components,
                        const UriComponents& trailing)
     {
       return resource.Handle(*reinterpret_cast<RestApiGetCall*>(NULL));
--- a/UnitTestsSources/UnitTestsMain.cpp	Wed Jul 01 10:18:26 2015 +0200
+++ b/UnitTestsSources/UnitTestsMain.cpp	Wed Jul 01 10:38:39 2015 +0200
@@ -39,7 +39,7 @@
 
 #include "../Core/Compression/ZlibCompressor.h"
 #include "../Core/DicomFormat/DicomTag.h"
-#include "../Core/HttpServer/HttpHandler.h"
+#include "../Core/HttpServer/HttpToolbox.h"
 #include "../Core/OrthancException.h"
 #include "../Core/Toolbox.h"
 #include "../Core/Uuid.h"
@@ -188,11 +188,11 @@
 
 TEST(ParseGetArguments, Basic)
 {
-  HttpHandler::GetArguments b;
-  HttpHandler::ParseGetArguments(b, "aaa=baaa&bb=a&aa=c");
+  IHttpHandler::GetArguments b;
+  HttpToolbox::ParseGetArguments(b, "aaa=baaa&bb=a&aa=c");
 
-  HttpHandler::Arguments a;
-  HttpHandler::CompileGetArguments(a, b);
+  IHttpHandler::Arguments a;
+  HttpToolbox::CompileGetArguments(a, b);
 
   ASSERT_EQ(3u, a.size());
   ASSERT_EQ(a["aaa"], "baaa");
@@ -202,11 +202,11 @@
 
 TEST(ParseGetArguments, BasicEmpty)
 {
-  HttpHandler::GetArguments b;
-  HttpHandler::ParseGetArguments(b, "aaa&bb=aa&aa");
+  IHttpHandler::GetArguments b;
+  HttpToolbox::ParseGetArguments(b, "aaa&bb=aa&aa");
 
-  HttpHandler::Arguments a;
-  HttpHandler::CompileGetArguments(a, b);
+  IHttpHandler::Arguments a;
+  HttpToolbox::CompileGetArguments(a, b);
 
   ASSERT_EQ(3u, a.size());
   ASSERT_EQ(a["aaa"], "");
@@ -216,11 +216,11 @@
 
 TEST(ParseGetArguments, Single)
 {
-  HttpHandler::GetArguments b;
-  HttpHandler::ParseGetArguments(b, "aaa=baaa");
+  IHttpHandler::GetArguments b;
+  HttpToolbox::ParseGetArguments(b, "aaa=baaa");
 
-  HttpHandler::Arguments a;
-  HttpHandler::CompileGetArguments(a, b);
+  IHttpHandler::Arguments a;
+  HttpToolbox::CompileGetArguments(a, b);
 
   ASSERT_EQ(1u, a.size());
   ASSERT_EQ(a["aaa"], "baaa");
@@ -228,11 +228,11 @@
 
 TEST(ParseGetArguments, SingleEmpty)
 {
-  HttpHandler::GetArguments b;
-  HttpHandler::ParseGetArguments(b, "aaa");
+  IHttpHandler::GetArguments b;
+  HttpToolbox::ParseGetArguments(b, "aaa");
 
-  HttpHandler::Arguments a;
-  HttpHandler::CompileGetArguments(a, b);
+  IHttpHandler::Arguments a;
+  HttpToolbox::CompileGetArguments(a, b);
 
   ASSERT_EQ(1u, a.size());
   ASSERT_EQ(a["aaa"], "");
@@ -241,11 +241,11 @@
 TEST(ParseGetQuery, Test1)
 {
   UriComponents uri;
-  HttpHandler::GetArguments b;
-  HttpHandler::ParseGetQuery(uri, b, "/instances/test/world?aaa=baaa&bb=a&aa=c");
+  IHttpHandler::GetArguments b;
+  HttpToolbox::ParseGetQuery(uri, b, "/instances/test/world?aaa=baaa&bb=a&aa=c");
 
-  HttpHandler::Arguments a;
-  HttpHandler::CompileGetArguments(a, b);
+  IHttpHandler::Arguments a;
+  HttpToolbox::CompileGetArguments(a, b);
 
   ASSERT_EQ(3u, uri.size());
   ASSERT_EQ("instances", uri[0]);
@@ -260,11 +260,11 @@
 TEST(ParseGetQuery, Test2)
 {
   UriComponents uri;
-  HttpHandler::GetArguments b;
-  HttpHandler::ParseGetQuery(uri, b, "/instances/test/world");
+  IHttpHandler::GetArguments b;
+  HttpToolbox::ParseGetQuery(uri, b, "/instances/test/world");
 
-  HttpHandler::Arguments a;
-  HttpHandler::CompileGetArguments(a, b);
+  IHttpHandler::Arguments a;
+  HttpToolbox::CompileGetArguments(a, b);
 
   ASSERT_EQ(3u, uri.size());
   ASSERT_EQ("instances", uri[0]);