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/protocol_handler.h b/libwebserv/protocol_handler.h
new file mode 100644
index 0000000..9ba7d11
--- /dev/null
+++ b/libwebserv/protocol_handler.h
@@ -0,0 +1,187 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBSERVER_LIBWEBSERV_PROTOCOL_HANDLER_H_
+#define WEBSERVER_LIBWEBSERV_PROTOCOL_HANDLER_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <base/callback_forward.h>
+#include <base/macros.h>
+#include <base/memory/weak_ptr.h>
+#include <chromeos/errors/error.h>
+#include <chromeos/secure_blob.h>
+
+#include <libwebserv/export.h>
+#include <libwebserv/request_handler_interface.h>
+
+namespace org {
+namespace chromium {
+namespace WebServer {
+
+class ProtocolHandlerProxy;
+
+}  // namespace WebServer
+}  // namespace chromium
+}  // namespace org
+
+namespace libwebserv {
+
+class Server;
+class Request;
+
+// Wrapper around a protocol handler (e.g. HTTP or HTTPs).
+// ProtocolHandler allows consumers to add request handlers on a given protocol.
+// When the ProtocolHandler is connected, allows users to read port and protocol
+// information.
+class LIBWEBSERV_EXPORT ProtocolHandler final {
+ public:
+  explicit ProtocolHandler(const std::string& id, Server* server);
+  ~ProtocolHandler();
+
+  // Returns true if the protocol handler object is connected to the web server
+  // daemon's proxy object and is capable of processing incoming requests.
+  bool IsConnected() const { return proxy_ != nullptr; }
+
+  // Handler's unique ID. This is generally a GUID string, except for the
+  // default HTTP and HTTPS handlers which have IDs of "http" and "https"
+  // respectively.
+  std::string GetID() const;
+
+  // Returns the port the handler is bound to.
+  // ATTENTION: The handler must be connected to the web server before this
+  // method can be called.
+  uint16_t GetPort() const;
+
+  // Returns the transport protocol that is served by this handler.
+  // Can be either "http" or "https".
+  // ATTENTION: The handler must be connected to the web server before this
+  // method can be called.
+  std::string GetProtocol() const;
+
+  // Returns a SHA-256 fingerprint of HTTPS certificate used. Returns an empty
+  // byte buffer if this handler does not serve the HTTPS protocol.
+  // ATTENTION: The handler must be connected to the web server before this
+  // method can be called.
+  chromeos::Blob GetCertificateFingerprint() 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.
+  //
+  // The handler registration information is stored inside ProtocolHandler and
+  // is used to register the handlers with the web server daemon when it becomes
+  // available. This also happens when the web server goes away and then comes
+  // back (e.g. restarted). So, there is no need to re-register the handlers
+  // once the web server process is restarted.
+  int AddHandler(const std::string& url,
+                 const std::string& method,
+                 std::unique_ptr<RequestHandlerInterface> handler);
+
+  // Similar to AddHandler() above but the handler is just a callback function.
+  int AddHandlerCallback(
+      const std::string& url,
+      const std::string& method,
+      const base::Callback<RequestHandlerInterface::HandlerSignature>&
+          handler_callback);
+
+  // 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);
+
+  static const char kHttp[];
+  static const char kHttps[];
+
+ private:
+  friend class FileInfo;
+  friend class Server;
+  friend class Response;
+
+  struct LIBWEBSERV_PRIVATE HandlerMapEntry {
+    std::string url;
+    std::string method;
+    std::string remote_handler_id;
+    std::unique_ptr<RequestHandlerInterface> handler;
+  };
+
+  // Called by the Server class when the D-Bus proxy object gets connected
+  // to the web server daemon.
+
+  LIBWEBSERV_PRIVATE void Connect(
+      org::chromium::WebServer::ProtocolHandlerProxy* proxy);
+  // Called by the Server class when the D-Bus proxy object gets disconnected
+  // from the web server daemon.
+  LIBWEBSERV_PRIVATE void Disconnect();
+
+  // Asynchronous callbacks to handle successful or failed request handler
+  // registration over D-Bus.
+  LIBWEBSERV_PRIVATE void AddHandlerSuccess(
+      int handler_id, const std::string& remote_handler_id);
+  LIBWEBSERV_PRIVATE void AddHandlerError(int handler_id,
+                                          chromeos::Error* error);
+
+  // Called by Server when an incoming request is dispatched.
+  LIBWEBSERV_PRIVATE bool ProcessRequest(const std::string& remote_handler_id,
+                                         const std::string& request_id,
+                                         std::unique_ptr<Request> request,
+                                         chromeos::ErrorPtr* error);
+
+  // Called by Response object to finish the request and send response data.
+  LIBWEBSERV_PRIVATE void CompleteRequest(
+      const std::string& request_id,
+      int status_code,
+      const std::multimap<std::string, std::string>& headers,
+      const std::vector<uint8_t>& data);
+
+  // Makes a call to the (remote) web server request handler over D-Bus to
+  // obtain the file content of uploaded file (identified by |file_id|) during
+  // request with |request_id|.
+  LIBWEBSERV_PRIVATE void GetFileData(
+    const std::string& request_id,
+    int file_id,
+    const base::Callback<void(const std::vector<uint8_t>&)>& success_callback,
+    const base::Callback<void(chromeos::Error*)>& error_callback);
+
+  // Protocol Handler unique ID.
+  std::string id_;
+  // Back reference to the server object.
+  Server* server_{nullptr};
+  // Handler data map. The key is the client-facing request handler ID returned
+  // by AddHandler() when registering the handler.
+  std::map<int, HandlerMapEntry> request_handlers_;
+  // Map of remote handler IDs (GUID strings) to client-facing request handler
+  // IDs (int) which are returned by AddHandler() and used as a key in
+  // |request_handlers_|.
+  std::map<std::string, int> remote_handler_id_map_;
+  // The counter to generate new handler IDs.
+  int last_handler_id_{0};
+  // Remove D-Bus proxy for the server protocol handler object.
+  org::chromium::WebServer::ProtocolHandlerProxy* proxy_{nullptr};
+
+  base::WeakPtrFactory<ProtocolHandler> weak_ptr_factory_{this};
+  DISALLOW_COPY_AND_ASSIGN(ProtocolHandler);
+};
+
+}  // namespace libwebserv
+
+#endif  // WEBSERVER_LIBWEBSERV_PROTOCOL_HANDLER_H_