diff options
author | Casey Dahlin <sadmac@google.com> | 2016-02-25 19:25:44 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-02-25 19:25:44 +0000 |
commit | 2b04370638af9dfd793f76503d2c3549ba6c54f3 (patch) | |
tree | 49f913b60589edb8441d3e972a9c6aa4bd8103ce | |
parent | 4bc43769bbb985336481cfb2f0962bc3548b2b89 (diff) | |
parent | 730b0d564355033a5a0528a9288ff3d60b1b5148 (diff) | |
download | webservd-2b04370638af9dfd793f76503d2c3549ba6c54f3.tar.gz |
Build libwebserv protocol handler proxy and stub out request handler
am: 730b0d5643
* commit '730b0d564355033a5a0528a9288ff3d60b1b5148':
Build libwebserv protocol handler proxy and stub out request handler
-rw-r--r-- | libwebserv/binder_server.cc | 211 | ||||
-rw-r--r-- | libwebserv/binder_server.h | 5 |
2 files changed, 196 insertions, 20 deletions
diff --git a/libwebserv/binder_server.cc b/libwebserv/binder_server.cc index ced4ba8..4ac8636 100644 --- a/libwebserv/binder_server.cc +++ b/libwebserv/binder_server.cc @@ -12,22 +12,191 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "libwebserv/binder_server.h" - #include "webserv_common/binder_constants.h" + +#include "libwebserv/binder_server.h" #include "libwebserv/protocol_handler.h" +#include "libwebserv/request_handler_callback.h" + +#include "android/webservd/BnRequestHandler.h" +#include <map> +#include <set> #include <string> #include <vector> using android::sp; using android::IBinder; using android::binder::Status; +using android::webservd::IHttpRequest; +using android::webservd::IProtocolHandler; +using android::webservd::IRequestHandler; +using std::map; +using std::pair; +using std::set; using std::string; +using std::unique_ptr; using std::vector; namespace libwebserv { +class BinderRequestHandler : public android::webservd::BnRequestHandler { + public: + explicit BinderRequestHandler(unique_ptr<RequestHandlerInterface> handler) + : handler_(std::move(handler)) {} + + Status ProcessRequest(const sp<IHttpRequest>& request) override { + (void)request; + return Status::ok(); + } + + private: + unique_ptr<RequestHandlerInterface> handler_; + + DISALLOW_COPY_AND_ASSIGN(BinderRequestHandler); +}; + +class BinderProtocolHandler : public ProtocolHandler { + public: + explicit BinderProtocolHandler(const string& name) + : name_(name) {} + + virtual ~BinderProtocolHandler() { + ResetRemoteProtocolHandlers(); + } + + bool AddRemote(sp<IProtocolHandler> handler) { + string name; + int32_t port; + string protocol; + + if (!handler->GetName(&name).isOk()) { + LOG(INFO) << "Could not get name of remote protocol handler."; + return false; + } + + CHECK(name == name_); + + if (!handler->GetPort(&port).isOk()) { + LOG(INFO) << "Could not get port for remote protocol handler."; + return false; + } + + if (!handler->GetProtocol(&protocol).isOk()) { + LOG(INFO) << "Could not get protocol for remote protocol handler."; + return false; + } + + ports_.insert(uint16_t(port)); + protocols_.insert(protocol); + remote_handlers_.push_back(handler); + + return true; + } + + int AddHandler(const string& url, + const string& method, + unique_ptr<RequestHandlerInterface> handler) override { + sp<IRequestHandler> binder_handler( + new BinderRequestHandler(std::move(handler))); + set<pair<sp<IProtocolHandler>, string>> guids; + + // Add this local request handler to each remote protocol handler + // associated with this local protocol handler. + for (sp<IProtocolHandler> handler : remote_handlers_) { + string guid; + + if (!handler->AddRequestHandler(url, + method, + binder_handler, + &guid).isOk()) { + LOG(WARNING) << "Remote protocol handler failed to " + << "register new request handler."; + } else { + guids.emplace(handler, guid); + } + } + + int id = last_handler_id_++; + handler_ids_.emplace(id, guids); + return id; + } + + int AddHandlerCallback( + const string& url, + const string& method, + const base::Callback<RequestHandlerInterface::HandlerSignature>& + handler_callback) override { + std::unique_ptr<RequestHandlerInterface> handler{ + new RequestHandlerCallback{handler_callback}}; + return AddHandler(url, method, std::move(handler)); + } + + bool RemoveHandler(int handler_id) override { + auto it = handler_ids_.find(handler_id); + + if (it == handler_ids_.end()) { + return false; + } + + for (const pair<sp<IProtocolHandler>,string>& remote : it->second) { + if (!remote.first->RemoveRequestHandler(remote.second).isOk()) { + LOG(WARNING) << "Could not remove request handler from remote."; + } + } + + return true; + } + + void ResetRemoteProtocolHandlers() { + for (auto it : handler_ids_) { + for (auto remote : it.second) { + if (!remote.first->RemoveRequestHandler(remote.second).isOk()) { + LOG(INFO) << "Could not remove request handler from remote."; + } + } + } + + handler_ids_.clear(); + remote_handlers_.clear(); + } + + bool IsConnected() const override { return !remote_handlers_.empty(); } + string GetName() const override { return name_; } + set<uint16_t> GetPorts() const override { return ports_; } + set<string> GetProtocols() const override { return protocols_; } + + brillo::Blob GetCertificateFingerprint() const override { + brillo::Blob result; + + for (auto& handler : remote_handlers_) { + Status status = handler->GetCertificateFingerprint(&result); + if (!status.isOk()) { + LOG(WARNING) << "Could not get certificate fingerprint " + << "from protocol handler: " << status; + } else if (!result.empty()) { + break; + } + } + + return result; + } + + private: + int last_handler_id_ = 0; + set<uint16_t> ports_; + set<string> protocols_; + string name_; + vector<sp<IProtocolHandler>> remote_handlers_; + + // Map of handler ID numbers as returned by AddHandler to pairs of + // IProtocolHandler pointers and string handler GUIDs as returned by the + // daemon. + map<int,set<pair<sp<IProtocolHandler>,string>>> handler_ids_; + + DISALLOW_COPY_AND_ASSIGN(BinderProtocolHandler); +}; + BinderServer::BinderServer(brillo::MessageLoop* message_loop, const base::Closure& on_server_online, const base::Closure& on_server_offline, @@ -59,14 +228,10 @@ void BinderServer::TryConnecting() { base::TimeDelta::FromSeconds(1)); } - void BinderServer::ClearLocalState() { - // Remove all references to remote protocol handlers from our local wrappers. - - // TODO(wiley) Define this method - //for (auto& local_handler: local_protocol_handlers_) { - // local_handler.second->ResetRemoteProtocolHandlers(); - //} + for (auto& local_handler: local_protocol_handlers_) { + local_handler.second->ResetRemoteProtocolHandlers(); + } remote_server_.clear(); } @@ -90,11 +255,17 @@ bool BinderServer::BuildLocalState(android::sp<android::IBinder> server) { LOG(INFO) << "Remote handler could not report its name."; return false; } - // TODO(wiley) Look for a BinderPHGroup by that name in local_handlers_ - // Create a new BinderPHGroup if necessary - // Add it to the map under |name| - // Update |it| appropriately - // Tell |it| about |remote_handler| + + auto it = local_protocol_handlers_.find(name); + + if (it == local_protocol_handlers_.end()) { + unique_ptr<BinderProtocolHandler> local_handler( + new BinderProtocolHandler(name)); + local_protocol_handlers_[name] = std::move(local_handler); + it = local_protocol_handlers_.find(name); + } + + it->second->AddRemote(remote_handler); } return true; } @@ -107,10 +278,14 @@ ProtocolHandler* BinderServer::GetDefaultHttpsHandler() { return GetProtocolHandler(ProtocolHandler::kHttps); } -ProtocolHandler* BinderServer::GetProtocolHandler(const string& /*name*/) { - // TODO(sadmac) Once BuildLocalState populates the map of protocol handlers, - // use it to return a result here. - return nullptr; +ProtocolHandler* BinderServer::GetProtocolHandler(const string& name) { + auto it = local_protocol_handlers_.find(name); + + if (it == local_protocol_handlers_.end()) { + return nullptr; + } + + return it->second.get(); } bool BinderServer::IsConnected() const { diff --git a/libwebserv/binder_server.h b/libwebserv/binder_server.h index ac37a31..f3ba155 100644 --- a/libwebserv/binder_server.h +++ b/libwebserv/binder_server.h @@ -36,6 +36,7 @@ namespace libwebserv { class ProtocolHandler; +class BinderProtocolHandler; class BinderPHGroup; class LIBWEBSERV_PRIVATE BinderServer : public Server { @@ -74,8 +75,8 @@ class LIBWEBSERV_PRIVATE BinderServer : public Server { android::BinderWrapper* binder_wrapper_; android::sp<RemoteServer> remote_server_; - //std::map<std::string, std::unique_ptr<BinderPHGroup>> - // local_protocol_handlers_; + std::map<std::string, std::unique_ptr<BinderProtocolHandler>> + local_protocol_handlers_; base::WeakPtrFactory<BinderServer> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(BinderServer); |