diff UnitTests/ServerIndex.cpp @ 209:9960642f0f45

abstraction of RestApi
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 28 Nov 2012 17:22:07 +0100
parents de640de989b8
children 0200cd330582
line wrap: on
line diff
--- a/UnitTests/ServerIndex.cpp	Wed Nov 28 17:00:46 2012 +0100
+++ b/UnitTests/ServerIndex.cpp	Wed Nov 28 17:22:07 2012 +0100
@@ -257,620 +257,3 @@
   index.DeleteResource(a[6]);
   ASSERT_EQ("", listener.ancestorId_);  // No more ancestor
 }
-
-
-
-
-#include "../Core/HttpServer/FilesystemHttpSender.h"
-
-#include "../Core/Toolbox.h"
-#include "../Core/HttpServer/HttpOutput.h"
-#include "../Core/HttpServer/HttpHandler.h"
-
-#include "../Core/HttpServer/HttpFileSender.h"
-
-
-namespace Orthanc
-{
-  class RestApiPath
-  {
-  private:
-    UriComponents uri_;
-    bool hasTrailing_;
-    std::vector<std::string> components_;
-
-  public:
-    typedef std::map<std::string, std::string> Components;
-
-    RestApiPath(const std::string& uri)
-    {
-      Toolbox::SplitUriComponents(uri_, uri);
-
-      if (uri_.size() == 0)
-      {
-        return;
-      }
-
-      if (uri_.back() == "*")
-      {
-        hasTrailing_ = true;
-        uri_.pop_back();
-      }
-      else
-      {
-        hasTrailing_ = false;
-      }
-
-      components_.resize(uri_.size());
-      for (size_t i = 0; i < uri_.size(); i++)
-      {
-        size_t s = uri_[i].size();
-        assert(s > 0);
-
-        if (uri_[i][0] == '{' && 
-            uri_[i][s - 1] == '}')
-        {
-          components_[i] = uri_[i].substr(1, s - 2);
-          uri_[i] = "";
-        }
-        else
-        {
-          components_[i] = "";
-        }
-      }
-    }
-
-    // This version is slower
-    bool Match(Components& components,
-               UriComponents& trailing,
-               const std::string& uriRaw) const
-    {
-      UriComponents uri;
-      Toolbox::SplitUriComponents(uri, uriRaw);
-      return Match(components, trailing, uri);
-    }
-
-    bool Match(Components& components,
-               UriComponents& trailing,
-               const UriComponents& uri) const
-    {
-      if (uri.size() < uri_.size())
-      {
-        return false;
-      }
-
-      if (!hasTrailing_ && uri.size() > uri_.size())
-      {
-        return false;
-      }
-
-      components.clear();
-      trailing.clear();
-
-      assert(uri_.size() <= uri.size());
-      for (size_t i = 0; i < uri_.size(); i++)
-      {
-        if (components_[i].size() == 0)
-        {
-          // This URI component is not a free parameter
-          if (uri_[i] != uri[i])
-          {
-            return false;
-          }
-        }
-        else
-        {
-          // This URI component is a free parameter
-          components[components_[i]] = uri[i];
-        }
-      }
-
-      if (hasTrailing_)
-      {
-        trailing.assign(uri.begin() + uri_.size(), uri.end());
-      }
-
-      return true;
-    }
-
-    bool Match(const UriComponents& uri) const
-    {
-      Components components;
-      UriComponents trailing;
-      return Match(components, trailing, uri);
-    }
-  };
-
-
-  class RestApiOutput
-  {
-  private:
-    HttpOutput& output_;
-
-  public:
-    RestApiOutput(HttpOutput& output) : output_(output)
-    {
-    }
-
-    void AnswerFile(HttpFileSender& sender)
-    {
-      sender.Send(output_);
-    }
-
-    void AnswerJson(const Json::Value& value)
-    {
-      Json::StyledWriter writer;
-      std::string s = writer.write(value);
-      output_.AnswerBufferWithContentType(s, "application/json");
-    }
-
-    void AnswerBuffer(const std::string& buffer,
-                      const std::string& contentType)
-    {
-      output_.AnswerBufferWithContentType(buffer, contentType);
-    }
-
-    void Redirect(const char* path)
-    {
-      output_.Redirect(path);
-    }
-  };
-
-
-  class RestApiSharedCall
-  {
-  protected:
-    RestApiOutput* output_;
-    IDynamicObject* context_;
-    const HttpHandler::Arguments* httpHeaders_;
-    const RestApiPath::Components* uriComponents_;
-    const UriComponents* trailing_;
-
-  public:
-    RestApiOutput& GetOutput()
-    {
-      return *output_;
-    }
-
-    IDynamicObject* GetContext()
-    {
-      return context_;
-    }
-    
-    const HttpHandler::Arguments& GetHttpHeaders() const
-    {
-      return *httpHeaders_;
-    }
-
-    const RestApiPath::Components& GetUriComponents() const
-    {
-      return *uriComponents_;
-    }
-
-    const UriComponents& GetTrailing() const
-    {
-      return *trailing_;
-    }
-
-    std::string GetUriComponent(const std::string& name,
-                                const std::string& defaultValue)
-    {
-      return HttpHandler::GetArgument(*uriComponents_, name, defaultValue);
-    }
-  };
-
- 
-  class RestApiPutCall : public RestApiSharedCall
-  {
-    friend class RestApi;
-
-  private:
-    const std::string* data_;
-
-  public:
-    const std::string& GetData()
-    {
-      return *data_;
-    }
-  };
-
-
-  class RestApiPostCall : public RestApiSharedCall
-  {
-    friend class RestApi;
-
-  private:
-    const std::string* data_;
-
-  public:
-    const std::string& GetData()
-    {
-      return *data_;
-    }
-  };
-
-
- 
-  class RestApiDeleteCall : public RestApiSharedCall
-  {
-    friend class RestApi;
-  };
-
-
-
-
-  class RestApiGetCall : public RestApiSharedCall
-  {
-    friend class RestApi;
-
-  private:
-    const HttpHandler::Arguments* getArguments_;
-
-  public:
-    std::string GetArgument(const std::string& name,
-                            const std::string& defaultValue)
-    {
-      return HttpHandler::GetArgument(*getArguments_, name, defaultValue);
-    }
-  };
-
-
-
-  class RestApi : public HttpHandler
-  {
-  public:
-    typedef void (*GetHandler) (RestApiGetCall& call);
-    
-    typedef void (*DeleteHandler) (RestApiDeleteCall& call);
-    
-    typedef void (*PutHandler) (RestApiPutCall& call);
-    
-    typedef void (*PostHandler) (RestApiPostCall& call);
-    
-  private:
-    typedef std::list< std::pair<RestApiPath*, GetHandler> > GetHandlers;
-    typedef std::list< std::pair<RestApiPath*, PutHandler> > PutHandlers;
-    typedef std::list< std::pair<RestApiPath*, PostHandler> > PostHandlers;
-    typedef std::list< std::pair<RestApiPath*, DeleteHandler> > DeleteHandlers;
-
-    // TODO MUTEX BETWEEN CONTEXTS !!!
-    std::auto_ptr<IDynamicObject> context_;
-
-    GetHandlers  getHandlers_;
-    PutHandlers  putHandlers_;
-    PostHandlers  postHandlers_;
-    DeleteHandlers  deleteHandlers_;
-
-    bool IsGetAccepted(const UriComponents& uri)
-    {
-      for (GetHandlers::const_iterator it = getHandlers_.begin();
-           it != getHandlers_.end(); it++)
-      {
-        if (it->first->Match(uri))
-        {
-          return true;
-        }
-      }
-
-      return false;
-    }
-
-    bool IsPutAccepted(const UriComponents& uri)
-    {
-      for (PutHandlers::const_iterator it = putHandlers_.begin();
-           it != putHandlers_.end(); it++)
-      {
-        if (it->first->Match(uri))
-        {
-          return true;
-        }
-      }
-
-      return false;
-    }
-
-    bool IsPostAccepted(const UriComponents& uri)
-    {
-      for (PostHandlers::const_iterator it = postHandlers_.begin();
-           it != postHandlers_.end(); it++)
-      {
-        if (it->first->Match(uri))
-        {
-          return true;
-        }
-      }
-
-      return false;
-    }
-
-    bool IsDeleteAccepted(const UriComponents& uri)
-    {
-      for (DeleteHandlers::const_iterator it = deleteHandlers_.begin();
-           it != deleteHandlers_.end(); it++)
-      {
-        if (it->first->Match(uri))
-        {
-          return true;
-        }
-      }
-
-      return false;
-    }
-
-    void AddMethod(std::string& target,
-                   const std::string& method) const
-    {
-      if (target.size() > 0)
-        target += "," + method;
-      else
-        target = method;
-    }
-
-    std::string  GetAcceptedMethods(const UriComponents& uri)
-    {
-      std::string s;
-
-      if (IsGetAccepted(uri))
-        AddMethod(s, "GET");
-
-      if (IsPutAccepted(uri))
-        AddMethod(s, "PUT");
-
-      if (IsPostAccepted(uri))
-        AddMethod(s, "POST");
-
-      if (IsDeleteAccepted(uri))
-        AddMethod(s, "DELETE");
-
-      return s;
-    }
-
-  public:
-    RestApi()
-    {
-    }
-
-    void SetContext(IDynamicObject* context)  // This takes the ownership
-    {
-      context_.reset(context);
-    }
-
-    ~RestApi()
-    {
-      for (GetHandlers::iterator it = getHandlers_.begin(); 
-           it != getHandlers_.end(); it++)
-      {
-        delete it->first;
-      } 
-
-      for (PutHandlers::iterator it = putHandlers_.begin(); 
-           it != putHandlers_.end(); it++)
-      {
-        delete it->first;
-      } 
-
-      for (PostHandlers::iterator it = postHandlers_.begin(); 
-           it != postHandlers_.end(); it++)
-      {
-        delete it->first;
-      } 
-
-      for (DeleteHandlers::iterator it = deleteHandlers_.begin(); 
-           it != deleteHandlers_.end(); it++)
-      {
-        delete it->first;
-      } 
-    }
-
-    virtual bool IsServedUri(const UriComponents& uri)
-    {
-      return (IsGetAccepted(uri) ||
-              IsPutAccepted(uri) ||
-              IsPostAccepted(uri) ||
-              IsDeleteAccepted(uri));
-    }
-
-    virtual void Handle(HttpOutput& output,
-                        const std::string& method,
-                        const UriComponents& uri,
-                        const Arguments& headers,
-                        const Arguments& getArguments,
-                        const std::string& postData)
-    {
-      bool ok = false;
-      RestApiOutput restOutput(output);
-      RestApiPath::Components components;
-      UriComponents trailing;
-               
-      if (method == "GET")
-      {
-        for (GetHandlers::const_iterator it = getHandlers_.begin();
-             it != getHandlers_.end(); it++)
-        {
-          if (it->first->Match(components, trailing, uri))
-          {
-            ok = true;
-            RestApiGetCall call;
-            call.output_ = &restOutput;
-            call.context_ = context_.get();
-            call.httpHeaders_ = &headers;
-            call.uriComponents_ = &components;
-            call.trailing_ = &trailing;
-           
-            call.getArguments_ = &getArguments;
-            it->second(call);
-          }
-        }
-      }
-      else if (method == "PUT")
-      {
-        for (PutHandlers::const_iterator it = putHandlers_.begin();
-             it != putHandlers_.end(); it++)
-        {
-          if (it->first->Match(components, trailing, uri))
-          {
-            ok = true;
-            RestApiPutCall call;
-            call.output_ = &restOutput;
-            call.context_ = context_.get();
-            call.httpHeaders_ = &headers;
-            call.uriComponents_ = &components;
-            call.trailing_ = &trailing;
-           
-            call.data_ = &postData;
-            it->second(call);
-          }
-        }
-      }
-      else if (method == "POST")
-      {
-        for (PostHandlers::const_iterator it = postHandlers_.begin();
-             it != postHandlers_.end(); it++)
-        {
-          if (it->first->Match(components, trailing, uri))
-          {
-            ok = true;
-            RestApiPostCall call;
-            call.output_ = &restOutput;
-            call.context_ = context_.get();
-            call.httpHeaders_ = &headers;
-            call.uriComponents_ = &components;
-            call.trailing_ = &trailing;
-           
-            call.data_ = &postData;
-            it->second(call);
-          }
-        }
-      }
-      else if (method == "DELETE")
-      {
-        for (DeleteHandlers::const_iterator it = deleteHandlers_.begin();
-             it != deleteHandlers_.end(); it++)
-        {
-          if (it->first->Match(components, trailing, uri))
-          {
-            ok = true;
-            RestApiDeleteCall call;
-            call.output_ = &restOutput;
-            call.context_ = context_.get();
-            call.httpHeaders_ = &headers;
-            call.uriComponents_ = &components;
-            call.trailing_ = &trailing;
-            it->second(call);
-          }
-        }
-      }
-
-      if (!ok)
-      {
-        output.SendMethodNotAllowedError(GetAcceptedMethods(uri));
-      }
-    }
-
-    void Register(const std::string& path,
-                  GetHandler handler)
-    {
-      getHandlers_.push_back(std::make_pair(new RestApiPath(path), handler));
-    }
-
-
-    void Register(const std::string& path,
-                  PutHandler handler)
-    {
-      putHandlers_.push_back(std::make_pair(new RestApiPath(path), handler));
-    }
-
-
-    void Register(const std::string& path,
-                  PostHandler handler)
-    {
-      postHandlers_.push_back(std::make_pair(new RestApiPath(path), handler));
-    }
-
-
-    void Register(const std::string& path,
-                  DeleteHandler handler)
-    {
-      deleteHandlers_.push_back(std::make_pair(new RestApiPath(path), handler));
-    }
-
-  };
-
-}
-
-
-TEST(RestApi, RestApiPath)
-{
-  RestApiPath::Components args;
-  UriComponents trail;
-
-  {
-    RestApiPath uri("/coucou/{abc}/d/*");
-    ASSERT_TRUE(uri.Match(args, trail, "/coucou/moi/d/e/f/g"));
-    ASSERT_EQ(1u, args.size());
-    ASSERT_EQ(3u, trail.size());
-    ASSERT_EQ("moi", args["abc"]);
-    ASSERT_EQ("e", trail[0]);
-    ASSERT_EQ("f", trail[1]);
-    ASSERT_EQ("g", trail[2]);
-
-    ASSERT_FALSE(uri.Match(args, trail, "/coucou/moi/f"));
-    ASSERT_TRUE(uri.Match(args, trail, "/coucou/moi/d/"));
-    ASSERT_FALSE(uri.Match(args, trail, "/a/moi/d"));
-    ASSERT_FALSE(uri.Match(args, trail, "/coucou/moi"));
-  }
-
-  {
-    RestApiPath uri("/coucou/{abc}/d");
-    ASSERT_FALSE(uri.Match(args, trail, "/coucou/moi/d/e/f/g"));
-    ASSERT_TRUE(uri.Match(args, trail, "/coucou/moi/d"));
-    ASSERT_EQ(1u, args.size());
-    ASSERT_EQ(0u, trail.size());
-    ASSERT_EQ("moi", args["abc"]);
-  }
-
-  {
-    RestApiPath uri("/*");
-    ASSERT_TRUE(uri.Match(args, trail, "/a/b/c"));
-    ASSERT_EQ(0u, args.size());
-    ASSERT_EQ(3u, trail.size());
-    ASSERT_EQ("a", trail[0]);
-    ASSERT_EQ("b", trail[1]);
-    ASSERT_EQ("c", trail[2]);
-  }
-}
-
-
-
-
-#include "../Core/HttpServer/MongooseServer.h"
-
-struct Tutu : public IDynamicObject
-{
-  static void Toto(RestApiGetCall& call)
-  {
-    printf("DONE\n");
-    Json::Value a = Json::objectValue;
-    a["Tutu"] = "Toto";
-    a["Youpie"] = call.GetArgument("coucou", "nope");
-    a["Toto"] = call.GetUriComponent("test", "nope");
-    call.GetOutput().AnswerJson(a);
-  }
-};
-
-
-
-TEST(RestApi, Tutu)
-{
-  MongooseServer httpServer;
-  httpServer.SetPortNumber(8042);
-  httpServer.Start();
-
-  RestApi* api = new RestApi;
-  httpServer.RegisterHandler(api);
-  api->Register("/coucou/{test}/a/*", Tutu::Toto);
-
-  httpServer.Start();
-  /*LOG(WARNING) << "REST has started";
-    Toolbox::ServerBarrier();*/
-}