// Copyright 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef WEBSERVER_LIBWEBSERV_DBUS_PROTOCOL_HANDLER_H_
#define WEBSERVER_LIBWEBSERV_DBUS_PROTOCOL_HANDLER_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include <base/callback_forward.h>
#include <base/macros.h>
#include <base/memory/weak_ptr.h>
#include <brillo/errors/error.h>
#include <brillo/secure_blob.h>
#include <brillo/streams/stream.h>
#include <dbus/object_path.h>
#include <libwebserv/export.h>
#include <libwebserv/protocol_handler.h>
#include <libwebserv/request_handler_interface.h>
namespace org {
namespace chromium {
namespace WebServer {
class ProtocolHandlerProxyInterface;
} // namespace WebServer
} // namespace chromium
} // namespace org
namespace libwebserv {
class DBusServer;
class Request;
class LIBWEBSERV_PRIVATE DBusProtocolHandler : public ProtocolHandler {
public:
DBusProtocolHandler(const std::string& name, DBusServer* server);
~DBusProtocolHandler() override;
bool IsConnected() const override;
std::string GetName() const override;
std::set<uint16_t> GetPorts() const override;
std::set<std::string> GetProtocols() const override;
brillo::Blob GetCertificateFingerprint() const override;
int AddHandler(const std::string& url,
const std::string& method,
std::unique_ptr<RequestHandlerInterface> handler) override;
int AddHandlerCallback(
const std::string& url,
const std::string& method,
const base::Callback<RequestHandlerInterface::HandlerSignature>&
handler_callback) override;
bool RemoveHandler(int handler_id) override;
private:
friend class FileInfo;
friend class DBusServer;
friend class ResponseImpl;
using ProtocolHandlerProxyInterface =
org::chromium::WebServer::ProtocolHandlerProxyInterface;
struct HandlerMapEntry {
std::string url;
std::string method;
std::map<ProtocolHandlerProxyInterface*, std::string> remote_handler_ids;
std::unique_ptr<RequestHandlerInterface> handler;
};
// Called by the DBusServer class when the D-Bus proxy object gets connected
// to the web server daemon.
void Connect(ProtocolHandlerProxyInterface* proxy);
// Called by the DBusServer class when the D-Bus proxy object gets
// disconnected from the web server daemon.
void Disconnect(const dbus::ObjectPath& object_path);
// Asynchronous callbacks to handle successful or failed request handler
// registration over D-Bus.
void AddHandlerSuccess(
int handler_id,
ProtocolHandlerProxyInterface* proxy,
const std::string& remote_handler_id);
void AddHandlerError(int handler_id, brillo::Error* error);
// Called by DBusServer when an incoming request is dispatched.
bool ProcessRequest(const std::string& protocol_handler_id,
const std::string& remote_handler_id,
const std::string& request_id,
std::unique_ptr<Request> request,
brillo::ErrorPtr* error);
// Called by Response object to finish the request and send response data.
void CompleteRequest(
const std::string& request_id,
int status_code,
const std::multimap<std::string, std::string>& headers,
brillo::StreamPtr data_stream);
// 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|.
void GetFileData(
const std::string& request_id,
int file_id,
const base::Callback<void(brillo::StreamPtr)>& success_callback,
const base::Callback<void(brillo::Error*)>& error_callback);
// A helper method to obtain a corresponding protocol handler D-Bus proxy for
// outstanding request with ID |request_id|.
ProtocolHandlerProxyInterface* GetRequestProtocolHandlerProxy(
const std::string& request_id) const;
// Protocol Handler name.
std::string name_;
// Back reference to the server object.
DBusServer* 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_;
// The counter to generate new handler IDs.
int last_handler_id_{0};
// 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_;
// Remote D-Bus proxies for the server protocol handler objects.
// There could be multiple protocol handlers with the same name (to make
// it possible to server the same requests on different ports, for example).
std::map<dbus::ObjectPath, ProtocolHandlerProxyInterface*> proxies_;
// A map of request ID to protocol handler ID. Used to locate the appropriate
// protocol handler D-Bus proxy for given request.
std::map<std::string, std::string> request_id_map_;
base::WeakPtrFactory<DBusProtocolHandler> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(DBusProtocolHandler);
};
} // namespace libwebserv
#endif // WEBSERVER_LIBWEBSERV_DBUS_PROTOCOL_HANDLER_H_