blob: 9ba7d11e027baec816c9be4e2de5da0707133a41 [file] [log] [blame]
Alex Vakulenko31a63792015-02-03 12:44:57 -08001// Copyright 2015 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef WEBSERVER_LIBWEBSERV_PROTOCOL_HANDLER_H_
6#define WEBSERVER_LIBWEBSERV_PROTOCOL_HANDLER_H_
7
8#include <map>
9#include <memory>
10#include <string>
11#include <vector>
12
13#include <base/callback_forward.h>
14#include <base/macros.h>
15#include <base/memory/weak_ptr.h>
16#include <chromeos/errors/error.h>
17#include <chromeos/secure_blob.h>
18
19#include <libwebserv/export.h>
20#include <libwebserv/request_handler_interface.h>
21
22namespace org {
23namespace chromium {
24namespace WebServer {
25
26class ProtocolHandlerProxy;
27
28} // namespace WebServer
29} // namespace chromium
30} // namespace org
31
32namespace libwebserv {
33
34class Server;
35class Request;
36
37// Wrapper around a protocol handler (e.g. HTTP or HTTPs).
38// ProtocolHandler allows consumers to add request handlers on a given protocol.
39// When the ProtocolHandler is connected, allows users to read port and protocol
40// information.
41class LIBWEBSERV_EXPORT ProtocolHandler final {
42 public:
43 explicit ProtocolHandler(const std::string& id, Server* server);
44 ~ProtocolHandler();
45
46 // Returns true if the protocol handler object is connected to the web server
47 // daemon's proxy object and is capable of processing incoming requests.
48 bool IsConnected() const { return proxy_ != nullptr; }
49
50 // Handler's unique ID. This is generally a GUID string, except for the
51 // default HTTP and HTTPS handlers which have IDs of "http" and "https"
52 // respectively.
53 std::string GetID() const;
54
55 // Returns the port the handler is bound to.
56 // ATTENTION: The handler must be connected to the web server before this
57 // method can be called.
58 uint16_t GetPort() const;
59
60 // Returns the transport protocol that is served by this handler.
61 // Can be either "http" or "https".
62 // ATTENTION: The handler must be connected to the web server before this
63 // method can be called.
64 std::string GetProtocol() const;
65
66 // Returns a SHA-256 fingerprint of HTTPS certificate used. Returns an empty
67 // byte buffer if this handler does not serve the HTTPS protocol.
68 // ATTENTION: The handler must be connected to the web server before this
69 // method can be called.
70 chromeos::Blob GetCertificateFingerprint() const;
71
72 // Adds a request handler for given |url|. If the |url| ends with a '/', this
73 // makes the handler respond to any URL beneath this path.
74 // Note that it is not possible to add a specific handler just for the root
75 // path "/". Doing so means "respond to any URL".
76 // |method| is optional request method verb, such as "GET" or "POST".
77 // If |method| is empty, the handler responds to any request verb.
78 // If there are more than one handler for a given request, the most specific
79 // match is chosen. For example, if there are the following handlers provided:
80 // - A["/foo/", ""]
81 // - B["/foo/bar", "GET"]
82 // - C["/foo/bar", ""]
83 // Here is what handlers are called when making certain requests:
84 // - GET("/foo/bar") => B[]
85 // - POST("/foo/bar") => C[]
86 // - PUT("/foo/bar") => C[]
87 // - GET("/foo/baz") => A[]
88 // - GET("/foo") => 404 Not Found
89 // This functions returns a handler ID which can be used later to remove
90 // the handler.
91 //
92 // The handler registration information is stored inside ProtocolHandler and
93 // is used to register the handlers with the web server daemon when it becomes
94 // available. This also happens when the web server goes away and then comes
95 // back (e.g. restarted). So, there is no need to re-register the handlers
96 // once the web server process is restarted.
97 int AddHandler(const std::string& url,
98 const std::string& method,
99 std::unique_ptr<RequestHandlerInterface> handler);
100
101 // Similar to AddHandler() above but the handler is just a callback function.
102 int AddHandlerCallback(
103 const std::string& url,
104 const std::string& method,
105 const base::Callback<RequestHandlerInterface::HandlerSignature>&
106 handler_callback);
107
108 // Removes the handler with the specified |handler_id|.
109 // Returns false if the handler with the given ID is not found.
110 bool RemoveHandler(int handler_id);
111
112 static const char kHttp[];
113 static const char kHttps[];
114
115 private:
116 friend class FileInfo;
117 friend class Server;
118 friend class Response;
119
120 struct LIBWEBSERV_PRIVATE HandlerMapEntry {
121 std::string url;
122 std::string method;
123 std::string remote_handler_id;
124 std::unique_ptr<RequestHandlerInterface> handler;
125 };
126
127 // Called by the Server class when the D-Bus proxy object gets connected
128 // to the web server daemon.
129
130 LIBWEBSERV_PRIVATE void Connect(
131 org::chromium::WebServer::ProtocolHandlerProxy* proxy);
132 // Called by the Server class when the D-Bus proxy object gets disconnected
133 // from the web server daemon.
134 LIBWEBSERV_PRIVATE void Disconnect();
135
136 // Asynchronous callbacks to handle successful or failed request handler
137 // registration over D-Bus.
138 LIBWEBSERV_PRIVATE void AddHandlerSuccess(
139 int handler_id, const std::string& remote_handler_id);
140 LIBWEBSERV_PRIVATE void AddHandlerError(int handler_id,
141 chromeos::Error* error);
142
143 // Called by Server when an incoming request is dispatched.
144 LIBWEBSERV_PRIVATE bool ProcessRequest(const std::string& remote_handler_id,
145 const std::string& request_id,
146 std::unique_ptr<Request> request,
147 chromeos::ErrorPtr* error);
148
149 // Called by Response object to finish the request and send response data.
150 LIBWEBSERV_PRIVATE void CompleteRequest(
151 const std::string& request_id,
152 int status_code,
153 const std::multimap<std::string, std::string>& headers,
154 const std::vector<uint8_t>& data);
155
156 // Makes a call to the (remote) web server request handler over D-Bus to
157 // obtain the file content of uploaded file (identified by |file_id|) during
158 // request with |request_id|.
159 LIBWEBSERV_PRIVATE void GetFileData(
160 const std::string& request_id,
161 int file_id,
162 const base::Callback<void(const std::vector<uint8_t>&)>& success_callback,
163 const base::Callback<void(chromeos::Error*)>& error_callback);
164
165 // Protocol Handler unique ID.
166 std::string id_;
167 // Back reference to the server object.
168 Server* server_{nullptr};
169 // Handler data map. The key is the client-facing request handler ID returned
170 // by AddHandler() when registering the handler.
171 std::map<int, HandlerMapEntry> request_handlers_;
172 // Map of remote handler IDs (GUID strings) to client-facing request handler
173 // IDs (int) which are returned by AddHandler() and used as a key in
174 // |request_handlers_|.
175 std::map<std::string, int> remote_handler_id_map_;
176 // The counter to generate new handler IDs.
177 int last_handler_id_{0};
178 // Remove D-Bus proxy for the server protocol handler object.
179 org::chromium::WebServer::ProtocolHandlerProxy* proxy_{nullptr};
180
181 base::WeakPtrFactory<ProtocolHandler> weak_ptr_factory_{this};
182 DISALLOW_COPY_AND_ASSIGN(ProtocolHandler);
183};
184
185} // namespace libwebserv
186
187#endif // WEBSERVER_LIBWEBSERV_PROTOCOL_HANDLER_H_