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_PROTOCOL_HANDLER_H_
16 #define WEBSERVER_LIBWEBSERV_DBUS_PROTOCOL_HANDLER_H_
17 
18 #include <map>
19 #include <memory>
20 #include <set>
21 #include <string>
22 #include <vector>
23 
24 #include <base/callback_forward.h>
25 #include <base/macros.h>
26 #include <base/memory/weak_ptr.h>
27 #include <brillo/errors/error.h>
28 #include <brillo/secure_blob.h>
29 #include <brillo/streams/stream.h>
30 #include <dbus/object_path.h>
31 
32 #include <libwebserv/export.h>
33 #include <libwebserv/protocol_handler.h>
34 #include <libwebserv/request_handler_interface.h>
35 
36 namespace org {
37 namespace chromium {
38 namespace WebServer {
39 
40 class ProtocolHandlerProxyInterface;
41 
42 }  // namespace WebServer
43 }  // namespace chromium
44 }  // namespace org
45 
46 namespace libwebserv {
47 
48 class DBusServer;
49 class Request;
50 
51 class LIBWEBSERV_PRIVATE DBusProtocolHandler : public ProtocolHandler {
52  public:
53   DBusProtocolHandler(const std::string& name, DBusServer* server);
54   ~DBusProtocolHandler() override;
55 
56   bool IsConnected() const override;
57 
58   std::string GetName() const override;
59 
60   std::set<uint16_t> GetPorts() const override;
61 
62   std::set<std::string> GetProtocols() const override;
63 
64   brillo::Blob GetCertificateFingerprint() const override;
65 
66   int AddHandler(const std::string& url,
67                  const std::string& method,
68                  std::unique_ptr<RequestHandlerInterface> handler) override;
69 
70   int AddHandlerCallback(
71       const std::string& url,
72       const std::string& method,
73       const base::Callback<RequestHandlerInterface::HandlerSignature>&
74           handler_callback) override;
75 
76   bool RemoveHandler(int handler_id) override;
77 
78  private:
79   friend class FileInfo;
80   friend class DBusServer;
81   friend class ResponseImpl;
82 
83   using ProtocolHandlerProxyInterface =
84       org::chromium::WebServer::ProtocolHandlerProxyInterface;
85 
86   struct HandlerMapEntry {
87     std::string url;
88     std::string method;
89     std::map<ProtocolHandlerProxyInterface*, std::string> remote_handler_ids;
90     std::unique_ptr<RequestHandlerInterface> handler;
91   };
92 
93   // Called by the DBusServer class when the D-Bus proxy object gets connected
94   // to the web server daemon.
95   void Connect(ProtocolHandlerProxyInterface* proxy);
96 
97   // Called by the DBusServer class when the D-Bus proxy object gets
98   // disconnected from the web server daemon.
99   void Disconnect(const dbus::ObjectPath& object_path);
100 
101   // Asynchronous callbacks to handle successful or failed request handler
102   // registration over D-Bus.
103   void AddHandlerSuccess(
104       int handler_id,
105       ProtocolHandlerProxyInterface* proxy,
106       const std::string& remote_handler_id);
107   void AddHandlerError(int handler_id, brillo::Error* error);
108 
109   // Called by DBusServer when an incoming request is dispatched.
110   bool ProcessRequest(const std::string& protocol_handler_id,
111                       const std::string& remote_handler_id,
112                       const std::string& request_id,
113                       std::unique_ptr<Request> request,
114                       brillo::ErrorPtr* error);
115 
116   // Called by Response object to finish the request and send response data.
117   void CompleteRequest(
118       const std::string& request_id,
119       int status_code,
120       const std::multimap<std::string, std::string>& headers,
121       brillo::StreamPtr data_stream);
122 
123   // Makes a call to the (remote) web server request handler over D-Bus to
124   // obtain the file content of uploaded file (identified by |file_id|) during
125   // request with |request_id|.
126   void GetFileData(
127       const std::string& request_id,
128       int file_id,
129       const base::Callback<void(brillo::StreamPtr)>& success_callback,
130       const base::Callback<void(brillo::Error*)>& error_callback);
131 
132   // A helper method to obtain a corresponding protocol handler D-Bus proxy for
133   // outstanding request with ID |request_id|.
134   ProtocolHandlerProxyInterface* GetRequestProtocolHandlerProxy(
135       const std::string& request_id) const;
136 
137   // Protocol Handler name.
138   std::string name_;
139   // Back reference to the server object.
140   DBusServer* server_{nullptr};
141   // Handler data map. The key is the client-facing request handler ID returned
142   // by AddHandler() when registering the handler.
143   std::map<int, HandlerMapEntry> request_handlers_;
144   // The counter to generate new handler IDs.
145   int last_handler_id_{0};
146   // Map of remote handler IDs (GUID strings) to client-facing request handler
147   // IDs (int) which are returned by AddHandler() and used as a key in
148   // |request_handlers_|.
149   std::map<std::string, int> remote_handler_id_map_;
150   // Remote D-Bus proxies for the server protocol handler objects.
151   // There could be multiple protocol handlers with the same name (to make
152   // it possible to server the same requests on different ports, for example).
153   std::map<dbus::ObjectPath, ProtocolHandlerProxyInterface*> proxies_;
154   // A map of request ID to protocol handler ID. Used to locate the appropriate
155   // protocol handler D-Bus proxy for given request.
156   std::map<std::string, std::string> request_id_map_;
157 
158   base::WeakPtrFactory<DBusProtocolHandler> weak_ptr_factory_{this};
159   DISALLOW_COPY_AND_ASSIGN(DBusProtocolHandler);
160 };
161 
162 }  // namespace libwebserv
163 
164 #endif  // WEBSERVER_LIBWEBSERV_DBUS_PROTOCOL_HANDLER_H_
165