1 // Copyright 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef WEBSERVER_LIBWEBSERV_DBUS_SERVER_H_
16 #define WEBSERVER_LIBWEBSERV_DBUS_SERVER_H_
17 
18 #include <map>
19 #include <memory>
20 #include <string>
21 
22 #include <base/macros.h>
23 #include <dbus/bus.h>
24 #include <brillo/dbus/async_event_sequencer.h>
25 #include <brillo/dbus/dbus_object.h>
26 
27 #include "libwebserv/export.h"
28 #include "libwebserv/request_handler_interface.h"
29 #include "libwebserv/server.h"
30 
31 namespace org {
32 namespace chromium {
33 namespace WebServer {
34 
35 class ObjectManagerProxy;
36 class ProtocolHandlerProxyInterface;
37 class RequestHandlerAdaptor;
38 class ServerProxyInterface;
39 
40 }  // namespace WebServer
41 }  // namespace chromium
42 }  // namespace org
43 
44 namespace libwebserv {
45 
46 class DBusProtocolHandler;
47 
48 class LIBWEBSERV_PRIVATE DBusServer : public Server {
49  public:
50   DBusServer();
51   ~DBusServer() override = default;
52 
53   // Establish a connection to the system webserver.
54   // |service_name| is the well known D-Bus name of the client's process, used
55   // to expose a callback D-Bus object the web server calls back with incoming
56   // requests.
57   // |on_server_online| and |on_server_offline| will notify the caller when the
58   // server comes up and down.
59   // Note that we can Connect() even before the webserver attaches to D-Bus,
60   // and appropriate state will be built up when the webserver appears on D-Bus.
61   void Connect(
62       const scoped_refptr<dbus::Bus>& bus,
63       const std::string& service_name,
64       const brillo::dbus_utils::AsyncEventSequencer::CompletionAction& cb,
65       const base::Closure& on_server_online,
66       const base::Closure& on_server_offline);
67 
68   ProtocolHandler* GetDefaultHttpHandler() override;
69 
70   ProtocolHandler* GetDefaultHttpsHandler() override;
71   ProtocolHandler* GetProtocolHandler(const std::string& name) override;
72 
73   bool IsConnected() const override;
74 
75   void OnProtocolHandlerConnected(
76       const base::Callback<void(ProtocolHandler*)>& callback) override;
77 
78   void OnProtocolHandlerDisconnected(
79       const base::Callback<void(ProtocolHandler*)>& callback) override;
80 
81   base::TimeDelta GetDefaultRequestTimeout() const override;
82 
83  private:
84   friend class DBusProtocolHandler;
85   class RequestHandler;
86 
87   // Handler invoked when a connection is established to web server daemon.
88   void Online(org::chromium::WebServer::ServerProxyInterface* server);
89 
90   // Handler invoked when the web server daemon connection is dropped.
91   void Offline(const dbus::ObjectPath& object_path);
92 
93   // Handler invoked when a new protocol handler D-Bus proxy object becomes
94   // available.
95   void ProtocolHandlerAdded(
96       org::chromium::WebServer::ProtocolHandlerProxyInterface* handler);
97 
98   // Handler invoked when a protocol handler D-Bus proxy object disappears.
99   void ProtocolHandlerRemoved(
100       const dbus::ObjectPath& object_path);
101 
102   // Looks up a protocol handler by ID. If not found, returns nullptr.
103   DBusProtocolHandler* GetProtocolHandlerByID(
104       const std::string& id) const;
105 
106   // Like the public version, but returns our specific handler type.
107   DBusProtocolHandler* GetProtocolHandlerImpl(const std::string& name);
108 
109   // Private implementation of D-Bus RequestHandlerInterface called by the web
110   // server daemon whenever a new request is available to be processed.
111   std::unique_ptr<RequestHandler> request_handler_;
112 
113   // D-Bus object to handler registration of RequestHandlerInterface.
114   std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object_;
115 
116   // D-Bus object adaptor for RequestHandlerInterface.
117   std::unique_ptr<org::chromium::WebServer::RequestHandlerAdaptor>
118       dbus_adaptor_;
119 
120   // D-Bus object manager proxy that receives notification of web server
121   // daemon's D-Bus object creation and destruction.
122   std::unique_ptr<org::chromium::WebServer::ObjectManagerProxy> object_manager_;
123 
124   // A mapping of protocol handler name to the associated object.
125   std::map<std::string, std::unique_ptr<DBusProtocolHandler>>
126       protocol_handlers_names_;
127   // A mapping of protocol handler IDs to the associated object.
128   std::map<std::string, DBusProtocolHandler*> protocol_handlers_ids_;
129   // A map between D-Bus object path of protocol handler and remote protocol
130   // handler ID.
131   std::map<dbus::ObjectPath, std::string> protocol_handler_id_map_;
132 
133   // User-specified callbacks for server and protocol handler life-time events.
134   base::Closure on_server_online_;
135   base::Closure on_server_offline_;
136   base::Callback<void(ProtocolHandler*)> on_protocol_handler_connected_;
137   base::Callback<void(ProtocolHandler*)> on_protocol_handler_disconnected_;
138 
139   // D-Bus proxy for the web server main object.
140   org::chromium::WebServer::ServerProxyInterface* proxy_{nullptr};
141 
142   // D-Bus service name used by the daemon hosting this object.
143   std::string service_name_;
144 
145   DISALLOW_COPY_AND_ASSIGN(DBusServer);
146 };
147 
148 }  // namespace libwebserv
149 
150 #endif  // WEBSERVER_LIBWEBSERV_DBUS_SERVER_H_
151