webserver: Move web server functionality into webservd

Moved libmicrohttpd from libwebserv to webservd daemon. Added the
D-Bus interface between the web server daemon and client library.

Updated privetd to use the new interface.

BUG=brillo:10
TEST=`FEATURES=test emerge-link libwebserv privetd`
CQ-DEPEND=CL:245780,CL:245118,CL:*195757

Change-Id: I26bfab64c6a0fd9460a47fd3fa9205c89abb943a
Reviewed-on: https://chromium-review.googlesource.com/245980
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/libwebserv/server.h b/libwebserv/server.h
index 6221115..ba133df 100644
--- a/libwebserv/server.h
+++ b/libwebserv/server.h
@@ -9,110 +9,135 @@
 #include <memory>
 #include <string>
 
-#include <base/callback_forward.h>
 #include <base/macros.h>
-#include <base/memory/ref_counted.h>
-#include <base/strings/string_piece.h>
-#include <chromeos/secure_blob.h>
+#include <dbus/bus.h>
+#include <chromeos/dbus/async_event_sequencer.h>
+#include <chromeos/dbus/dbus_object.h>
 #include <libwebserv/export.h>
 #include <libwebserv/request_handler_interface.h>
 
-struct MHD_Daemon;
+namespace org {
+namespace chromium {
+namespace WebServer {
 
-namespace base {
-class TaskRunner;
-}  // namespace base
+class ObjectManagerProxy;
+class ProtocolHandlerProxy;
+class RequestHandlerAdaptor;
+class ServerProxy;
+
+}  // namespace WebServer
+}  // namespace chromium
+}  // namespace org
 
 namespace libwebserv {
 
 // Top-level wrapper class around HTTP server and provides an interface to
-// the web server. It allows the users to start the server and
-// register request handlers.
+// the web server.
 class LIBWEBSERV_EXPORT Server final {
  public:
   Server();
   ~Server();
 
-  // Starts the server and makes it listen to HTTP requests on the given port.
-  //
-  // Note that a valid message loop must exist before calling Start.
-  bool Start(uint16_t port);
+  // Establish a connection to the system webserver.
+  // |service_name| is the well known D-Bus name of the client's process, used
+  // to expose a callback D-Bus object the web server calls back with incoming
+  // requests.
+  // |on_server_online| and |on_server_offline| will notify the caller when the
+  // server comes up and down.
+  // Note that we can Connect() even before the webserver attaches to D-Bus,
+  // and appropriate state will be built up when the webserver appears on D-Bus.
+  void Connect(
+      const scoped_refptr<dbus::Bus>& bus,
+      const std::string& service_name,
+      const chromeos::dbus_utils::AsyncEventSequencer::CompletionAction& cb,
+      const base::Closure& on_server_online,
+      const base::Closure& on_server_offline);
 
-  // Starts the server and makes it listen to HTTPS requests on the given port.
-  //
-  // Note that a valid message loop must exist before calling StartWithTLS.
-  bool StartWithTLS(uint16_t port,
-                    const chromeos::SecureBlob& private_key,
-                    const chromeos::Blob& certificate);
+  // Disconnects from the web server and removes the library interface from
+  // D-Bus.
+  void Disconnect();
 
-  // Stops the server.
-  bool Stop();
+  // A helper method that returns the default handler for "http".
+  ProtocolHandler* GetDefaultHttpHandler() const;
 
-  // Adds a request handler for given |url|. If the |url| ends with a '/', this
-  // makes the handler respond to any URL beneath this path.
-  // Note that it is not possible to add a specific handler just for the root
-  // path "/". Doing so means "respond to any URL".
-  // |method| is optional request method verb, such as "GET" or "POST".
-  // If |method| is empty, the handler responds to any request verb.
-  // If there are more than one handler for a given request, the most specific
-  // match is chosen. For example, if there are the following handlers provided:
-  //    - A["/foo/",  ""]
-  //    - B["/foo/bar", "GET"]
-  //    - C["/foo/bar", ""]
-  // Here is what handlers are called when making certain requests:
-  //    - GET("/foo/bar")   => B[]
-  //    - POST("/foo/bar")  => C[]
-  //    - PUT("/foo/bar")   => C[]
-  //    - GET("/foo/baz")   => A[]
-  //    - GET("/foo")       => 404 Not Found
-  // This functions returns a handler ID which can be used later to remove
-  // the handler.
-  int AddHandler(const base::StringPiece& url,
-                 const base::StringPiece& method,
-                 std::unique_ptr<RequestHandlerInterface> handler);
+  // A helper method that returns the default handler for "https".
+  ProtocolHandler* GetDefaultHttpsHandler() const;
 
-  // Similar to AddHandler() above but the handler is just a callback function.
-  int AddHandlerCallback(
-      const base::StringPiece& url,
-      const base::StringPiece& method,
-      const base::Callback<RequestHandlerInterface::HandlerSignature>&
-          handler_callback);
+  // Returns true if the web server daemon is connected to DBus and our
+  // connection to it has been established.
+  bool IsConnected() const { return proxy_ != nullptr; }
 
-  // Removes the handler with the specified |handler_id|.
-  // Returns false if the handler with the given ID is not found.
-  bool RemoveHandler(int handler_id);
+  // Set a user-callback to be invoked when a protocol handler is connect to the
+  // server daemon.  Multiple calls to this method will overwrite previously set
+  // callbacks.
+  void OnProtocolHandlerConnected(
+      const base::Callback<void(ProtocolHandler*)>& callback);
 
-  // Finds the handler ID given the exact match criteria. Note that using
-  // this function could cause unexpected side effects if there are more than
-  // one handler registered for given URL/Method parameters.
-  // It is better to remember the handler ID from AddHandler() method and use
-  // that ID to remove the handler, instead of looking the handler up using
-  // URL/Method.
-  int GetHandlerId(const base::StringPiece& url,
-                   const base::StringPiece& method) const;
-
-  // Finds a handler for given URL/Method. This method does the criteria
-  // matching and not exact match performed by GetHandlerId. This is the method
-  // used to look up the handler for incoming HTTP requests.
-  RequestHandlerInterface* FindHandler(
-      const base::StringPiece& url,
-      const base::StringPiece& method) const;
+  // Set a user-callback to be invoked when a protocol handler is disconnected
+  // from the server daemon (e.g. on shutdown).  Multiple calls to this method
+  // will overwrite previously set callbacks.
+  void OnProtocolHandlerDisconnected(
+      const base::Callback<void(ProtocolHandler*)>& callback);
 
  private:
-  MHD_Daemon* server_ = nullptr;
-  scoped_refptr<base::TaskRunner> task_runner_;
+  friend class ProtocolHandler;
+  class RequestHandler;
 
-  struct LIBWEBSERV_PRIVATE HandlerMapEntry {
-    std::string url;
-    std::string method;
-    std::unique_ptr<RequestHandlerInterface> handler;
-  };
+  // Returns an existing protocol handler by ID.  See documentation in
+  // ProtocolHandler about IDs and how they work with webservd.
+  LIBWEBSERV_PRIVATE ProtocolHandler* GetProtocolHandler(
+      const std::string& id) const;
 
-  std::map<int, HandlerMapEntry> request_handlers_;
-  int last_handler_id_{0};
+  // Handler invoked when a connection is established to web server daemon.
+  LIBWEBSERV_PRIVATE void Online(org::chromium::WebServer::ServerProxy* server);
 
-  friend class ServerHelper;
-  friend class Connection;
+  // Handler invoked when the web server daemon connection is dropped.
+  LIBWEBSERV_PRIVATE void Offline(const dbus::ObjectPath& object_path);
+
+  // Handler invoked when a new protocol handler D-Bus proxy object becomes
+  // available.
+  LIBWEBSERV_PRIVATE void ProtocolHandlerAdded(
+      org::chromium::WebServer::ProtocolHandlerProxy* handler);
+
+  // Handler invoked when a protocol handler D-Bus proxy object disappears.
+  LIBWEBSERV_PRIVATE void ProtocolHandlerRemoved(
+      const dbus::ObjectPath& object_path);
+
+  LIBWEBSERV_PRIVATE void AddProtocolHandler(
+      std::unique_ptr<ProtocolHandler> handler);
+
+  // Private implementation of D-Bus RequestHandlerInterface called by the web
+  // server daemon whenever a new request is available to be processed.
+  std::unique_ptr<RequestHandler> request_handler_;
+  // D-Bus object adaptor for RequestHandlerInterface.
+  std::unique_ptr<org::chromium::WebServer::RequestHandlerAdaptor>
+      dbus_adaptor_;
+  // D-Bus object to handler registration of RequestHandlerInterface.
+  std::unique_ptr<chromeos::dbus_utils::DBusObject> dbus_object_;
+
+  // A mapping of protocol handler IDs to the associated object.
+  // Handler IDs are either GUIDs or the two well-known handler IDs.
+  std::map<std::string, std::unique_ptr<ProtocolHandler>> protocol_handlers_;
+  // A map between D-Bus object path of protocol handler and remote protocol
+  // handler ID.
+  std::map<dbus::ObjectPath, std::string> protocol_handler_id_map_;
+
+  // User-specified callbacks for server and protocol handler life-time events.
+  base::Closure on_server_online_;
+  base::Closure on_server_offline_;
+  base::Callback<void(ProtocolHandler*)> on_protocol_handler_connected_;
+  base::Callback<void(ProtocolHandler*)> on_protocol_handler_disconnected_;
+
+  // D-Bus object manager proxy that receives notification of web server
+  // daemon's D-Bus object creation and destruction.
+  std::unique_ptr<org::chromium::WebServer::ObjectManagerProxy> object_manager_;
+
+  // D-Bus proxy for the web server main object.
+  org::chromium::WebServer::ServerProxy* proxy_{nullptr};
+
+  // D-Bus service name used by the daemon hosting this object.
+  std::string service_name_;
+
   DISALLOW_COPY_AND_ASSIGN(Server);
 };