LCOV - code coverage report
Current view: top level - zeroeq/http - server.h (source / functions) Hit Total Coverage
Test: ZeroEQ Lines: 5 5 100.0 %
Date: 2017-12-01 01:44:57 Functions: 2 2 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2016-2017, Human Brain Project
       3             :  *                          Stefan.Eilemann@epfl.ch
       4             :  *                          Raphael.Dumusc@epfl.ch
       5             :  */
       6             : 
       7             : #ifndef ZEROEQ_HTTP_SERVER_H
       8             : #define ZEROEQ_HTTP_SERVER_H
       9             : 
      10             : #include <zeroeq/http/api.h>
      11             : #include <zeroeq/http/request.h>
      12             : #include <zeroeq/http/types.h>
      13             : 
      14             : #include <zeroeq/log.h>
      15             : #include <zeroeq/receiver.h> // base class
      16             : 
      17             : namespace zeroeq
      18             : {
      19             : namespace http
      20             : {
      21             : /**
      22             :  * Serves HTTP GET and PUT requests for servus::Serializable objects.
      23             :  *
      24             :  * Behaves semantically like a Publisher (for GET) and Subscriber (for PUT),
      25             :  * except uses HTTP with JSON payload as the protocol. Requests are served
      26             :  * synchronously (as per HTTP spec). Objects are available under their
      27             :  * Serializable::getTypeName(), with '::' replaced by '/'. The REST API is case
      28             :  * insensitive. For example, zerobuf::render::Camera is served at
      29             :  * 'GET|PUT [uri]/zerobuf/render/camera'.
      30             :  *
      31             :  * Announces itself if a zeroconf implementation is available, including
      32             :  * "Type=ZeroEQ" in the zeroconf record.
      33             :  *
      34             :  * Not thread safe.
      35             :  *
      36             :  * Example: @include tests/http/server.cpp
      37             :  */
      38             : class Server : public zeroeq::Receiver
      39             : {
      40             : public:
      41             :     /** @name Setup */
      42             :     //@{
      43             :     /**
      44             :      * Construct a new HTTP server.
      45             :      *
      46             :      * To process requests on the incoming port, call receive().
      47             :      *
      48             :      * If no hostname is given, the server listens on all interfaces
      49             :      * (INADDR_ANY). If no port is given, the server selects a random port. Use
      50             :      * getURI() to retrieve the chosen parameters.
      51             :      *
      52             :      * @param uri The server address in the form "[tcp://][hostname][:port]"
      53             :      * @param shared a shared receiver, see Receiver constructor.
      54             :      * @throw std::runtime_error on malformed URI or connection issues.
      55             :      */
      56             :     ZEROEQHTTP_API Server(const URI& uri, Receiver& shared);
      57             :     ZEROEQHTTP_API explicit Server(const URI& uri);
      58             :     ZEROEQHTTP_API explicit Server(Receiver& shared);
      59           1 :     explicit Server(Server& shared)
      60           1 :         : Server(static_cast<Receiver&>(shared))
      61             :     {
      62           1 :     }
      63             :     ZEROEQHTTP_API Server();
      64             : 
      65             :     /** Destruct this http server. */
      66             :     ZEROEQHTTP_API ~Server();
      67             : 
      68             :     /**
      69             :      * Create a new Server when requested.
      70             :      *
      71             :      * The creation and parameters depend on the following command line
      72             :      * parameters:
      73             :      * * --zeroeq-http-server [host][:port]: Enable the server. The optional
      74             :      *   parameters configure the web server, running by default on INADDR_ANY
      75             :      *   and a randomly chosen port
      76             :      */
      77             :     ZEROEQHTTP_API
      78             :     static std::unique_ptr<Server> parse(int argc, const char* const* argv);
      79             :     ZEROEQHTTP_API
      80             :     static std::unique_ptr<Server> parse(int argc, const char* const* argv,
      81             :                                          Receiver& shared);
      82             :     /**
      83             :      * Get the publisher URI.
      84             :      *
      85             :      * Contains the used hostname and port, if none where given in the
      86             :      * constructor uri.
      87             :      *
      88             :      * @return the publisher URI.
      89             :      */
      90             :     ZEROEQHTTP_API const URI& getURI() const;
      91             : 
      92             :     /**
      93             :      * Get the underlying socket descriptor.
      94             :      *
      95             :      * Can be used by client code to be notified when new data is available and
      96             :      * subsequently call receive.
      97             :      *
      98             :      * @return the socket descriptor.
      99             :      * @throw std::runtime_error if the descriptor could not be obtained.
     100             :      * @note not supported on Windows due to ZMQ limitations, will throw
     101             :      *       std::runtime_error
     102             :      */
     103             :     ZEROEQHTTP_API SocketDescriptor getSocketDescriptor() const;
     104             :     //@}
     105             : 
     106             :     /**
     107             :      * Handle a single method on a given endpoint.
     108             :      *
     109             :      * @param method to handle
     110             :      * @param endpoint the endpoint to receive requests for during receive()
     111             :      * @param func the callback function for serving the request
     112             :      * @return true if subscription was successful, false otherwise
     113             :      * @sa Request
     114             :      */
     115             :     bool handle(Method method, const std::string& endpoint, RESTFunc func);
     116             : 
     117             :     /** @name Object registration for PUT and GET requests */
     118             :     //@{
     119             :     /**
     120             :      * Handle PUT and GET for the given object.
     121             :      *
     122             :      * @param object the object to update and serve on receive()
     123             :      * @return true if subscription was successful, false otherwise
     124             :      */
     125           7 :     bool handle(servus::Serializable& object)
     126             :     {
     127           7 :         return handlePUT(object) && handleGET(object);
     128             :     }
     129             : 
     130             :     /**
     131             :      * @overload
     132             :      * @param object the object to update and serve on receive()
     133             :      * @param endpoint use this as the URL endpoint instead of the default
     134             :      *                 servus::Serializable::getTypeName()
     135             :      */
     136             :     ZEROEQHTTP_API bool handle(const std::string& endpoint,
     137             :                                servus::Serializable& object);
     138             : 
     139             :     /** Remove PUT and GET handling for given object. */
     140             :     ZEROEQHTTP_API bool remove(const servus::Serializable& object);
     141             : 
     142             :     /** Remove all handling for given endpoint. */
     143             :     ZEROEQHTTP_API bool remove(const std::string& endpoint);
     144             : 
     145             :     /**
     146             :      * Subscribe a serializable object to receive updates from HTTP PUT
     147             :      * requests.
     148             :      *
     149             :      * Every update will be directly applied on the object during receive()
     150             :      * using fromJSON(). To track updates on the object, the serializable's
     151             :      * updated function is called accordingly.
     152             :      *
     153             :      * The subscribed object instance has to be valid until remove().
     154             :      *
     155             :      * @param object the object to update on receive()
     156             :      * @return true if subscription was successful, false otherwise
     157             :      */
     158             :     ZEROEQHTTP_API bool handlePUT(servus::Serializable& object);
     159             : 
     160             :     /**
     161             :      * @overload
     162             :      * @param object the object to update on receive()
     163             :      * @param endpoint use this as the URL endpoint instead of the default
     164             :      *                 servus::Serializable::getTypeName()
     165             :      */
     166             :     ZEROEQHTTP_API bool handlePUT(const std::string& endpoint,
     167             :                                   servus::Serializable& object);
     168             : 
     169             :     /**
     170             :      * Subscribe an endpoint to receive HTTP PUT requests.
     171             :      *
     172             :      * Every receival of the endpoint will call the registered callback
     173             :      * function.
     174             :      *
     175             :      * @param endpoint the endpoint to receive PUT requests for during receive()
     176             :      * @param func the callback function for serving the PUT request
     177             :      * @return true if subscription was successful, false otherwise
     178             :      */
     179             :     ZEROEQHTTP_API
     180             :     bool handlePUT(const std::string& endpoint, const PUTFunc& func);
     181             : 
     182             :     /**
     183             :      * @overload
     184             :      * @param endpoint the endpoint to receive PUT requests for during receive()
     185             :      * @param schema describes data layout of endpoint
     186             :      * @param func the callback function for serving the PUT request
     187             :      */
     188             :     ZEROEQHTTP_API bool handlePUT(const std::string& endpoint,
     189             :                                   const std::string& schema,
     190             :                                   const PUTFunc& func);
     191             : 
     192             :     /**
     193             :      * Subscribe an endpoint to receive HTTP PUT requests with payload.
     194             :      *
     195             :      * Every receival of the endpoint will call the registered callback
     196             :      * function.
     197             :      *
     198             :      * @param endpoint the endpoint to receive PUT requests for during receive()
     199             :      * @param func the callback function for serving the PUT request
     200             :      * @return true if subscription was successful, false otherwise
     201             :      */
     202             :     ZEROEQHTTP_API bool handlePUT(const std::string& endpoint,
     203             :                                   const PUTPayloadFunc& func);
     204             : 
     205             :     /**
     206             :      * @overload
     207             :      * @param endpoint the endpoint to receive PUT requests for during receive()
     208             :      * @param schema describes data layout of the endpoint
     209             :      * @param func the callback function for serving the PUT request
     210             :      */
     211             :     ZEROEQHTTP_API bool handlePUT(const std::string& endpoint,
     212             :                                   const std::string& schema,
     213             :                                   const PUTPayloadFunc& func);
     214             :     /**
     215             :      * Subscribe a serializable object to serve HTTP GET requests.
     216             :      *
     217             :      * Every request will be directly handled during receive() by using
     218             :      * toJSON(). To track updates on the object, the serializable's received
     219             :      * function is called accordingly.
     220             :      *
     221             :      * The subscribed object instance has to be valid until remove().
     222             :      *
     223             :      * @param object the object to serve during receive()
     224             :      * @return true if subscription was successful, false otherwise
     225             :      */
     226             :     ZEROEQHTTP_API bool handleGET(const servus::Serializable& object);
     227             : 
     228             :     /**
     229             :      * @overload
     230             :      * @param object the object to serve during receive()
     231             :      * @param endpoint use this as the URL endpoint instead of the default
     232             :      *                 servus::Serializable::getTypeName()
     233             :      */
     234             :     ZEROEQHTTP_API bool handleGET(const std::string& endpoint,
     235             :                                   const servus::Serializable& object);
     236             : 
     237             :     /**
     238             :      * Subscribe an endpoint to serve HTTP GET requests.
     239             :      *
     240             :      * Every request will be directly handled during receive() by calling the
     241             :      * registered GET function.
     242             :      *
     243             :      * @param endpoint the endpoint to serve during receive()
     244             :      * @param func the callback function for serving the GET request
     245             :      * @return true if subscription was successful, false otherwise
     246             :      */
     247             :     ZEROEQHTTP_API
     248             :     bool handleGET(const std::string& endpoint, const GETFunc& func);
     249             : 
     250             :     /**
     251             :      * @overload
     252             :      * @param endpoint the endpoint to serve during receive()
     253             :      * @param schema describes data layout of the endpoint
     254             :      * @param func the callback function for serving the GET request
     255             :      */
     256             :     ZEROEQHTTP_API
     257             :     bool handleGET(const std::string& endpoint, const std::string& schema,
     258             :                    const GETFunc& func);
     259             : 
     260             :     /**
     261             :      * @return the registered schema for the given object, or empty if not
     262             :      *         registered.
     263             :      */
     264             :     ZEROEQHTTP_API
     265             :     std::string getSchema(const servus::Serializable& object) const;
     266             : 
     267             :     /** @overload */
     268             :     ZEROEQHTTP_API std::string getSchema(const std::string& endpoint) const;
     269             :     //@}
     270             : 
     271             : protected:
     272             :     /**
     273             :      * Respond to a request.
     274             :      *
     275             :      * This function can be overridden in derived classes to implement special
     276             :      * processing such as filtering for certain sources or http methods.
     277             :      * @param request to process.
     278             :      * @return future response to a request.
     279             :      */
     280             :     virtual std::future<Response> respondTo(Request& request) const;
     281             : 
     282             : private:
     283             :     class Impl;
     284             :     std::unique_ptr<Impl> _impl;
     285             : 
     286             :     // Receiver API
     287             :     void addSockets(std::vector<detail::Socket>& entries) final;
     288             :     bool process(detail::Socket& socket) final;
     289             : };
     290             : }
     291             : }
     292             : 
     293             : #endif

Generated by: LCOV version 1.11