libwebserv(system/webservd/libwebserv)是weaved(system/weaved)的一个子模块。weaved通过libwebserv向webservd添加request handler,而libweabsrv又是通过D-Bus与webservd进行通信。
- weaved – libwebserv – 初始化
weaved调用libwebserv的入口函数的流程为:
-> main() @ system/weaved/buffet/main.cc -> brillo::Daemon::Run() @ external/libbrillo/brillo/daemons/daemon.cc -> brillo::DBusServiceDaemon::OnInit() @ external/libbrillo/brillo/daemons/dbus_daemon.cc -> buffet::Daemon::RegisterDBusObjectsAsync() @ system/weaved/buffet/main.cc -> buffet::Manager::RestartWeave() @ system/weaved/buffet/manager.cc -> buffet::WebServClient::WebServClient() @ system/weaved/buffet/webserv_client.cc -> libwebserv::Server::ConnectToServerViaDBus() @ system/webservd/libwebserv/server.cc -> libwebserv::DBusServer::Connect() @ system/webservd/libwebserv/dbus_server.cc
这里,我们重点看一下bufffer::WebServvClient::WebServClient()与libwebserv::DBusServer::Connect()这两个方法。首先我们看一下buffet::WebServClient::WebServClient()做了些什么:
WebServClient::WebServClient( const scoped_refptr<dbus::Bus>& bus, brillo::dbus_utils::AsyncEventSequencer* sequencer, const base::Closure& server_available_callback) : server_available_callback_{server_available_callback} { web_server_ = libwebserv::Server::ConnectToServerViaDBus( bus, buffet::dbus_constants::kServiceName, sequencer->GetHandler("Server::Connect failed.", true), base::Bind(&base::DoNothing), base::Bind(&base::DoNothing)); web_server_->OnProtocolHandlerConnected( base::Bind(&WebServClient::OnProtocolHandlerConnected, weak_ptr_factory_.GetWeakPtr())); web_server_->OnProtocolHandlerDisconnected( base::Bind(&WebServClient::OnProtocolHandlerDisconnected, weak_ptr_factory_.GetWeakPtr())); }
可以看到这里设置了protocol handler connected/disconnected callback, 当protocol handler added/removed时,就会回调这个callback。
接着我们再看一下libwebserv::DBusServer::Connect()方法:
void DBusServer::Connect( const scoped_refptr<dbus::Bus>& bus, const std::string& service_name, const brillo::dbus_utils::AsyncEventSequencer::CompletionAction& cb, const base::Closure& on_server_online, const base::Closure& on_server_offline) { service_name_ = service_name; dbus_object_.reset(new brillo::dbus_utils::DBusObject{ nullptr, bus, dbus_adaptor_->GetObjectPath()}); dbus_adaptor_->RegisterWithDBusObject(dbus_object_.get()); dbus_object_->RegisterAsync(cb); on_server_online_ = on_server_online; on_server_offline_ = on_server_offline; object_manager_.reset(new org::chromium::WebServer::ObjectManagerProxy{bus}); object_manager_->SetServerAddedCallback( base::Bind(&DBusServer::Online, base::Unretained(this))); object_manager_->SetServerRemovedCallback( base::Bind(&DBusServer::Offline, base::Unretained(this))); object_manager_->SetProtocolHandlerAddedCallback( base::Bind(&DBusServer::ProtocolHandlerAdded, base::Unretained(this))); object_manager_->SetProtocolHandlerRemovedCallback( base::Bind(&DBusServer::ProtocolHandlerRemoved, base::Unretained(this))); }
可以看到这里设置了webservd server online/offline callback,同时还设置了protocol handler added/removed callback。
- weaved – libwebserv – protocol handler added/removed callback
调用过程如下:
-> ...
-> dbus::ObjectManager::OnGetManagedObjects() @ external/libchrome/dbus/object_manager.cc
-> dbus::ObjectManager::UpdateObject() @ external/libchrome/dbus/object_manager.cc
-> org::chromium::WebServer::ObjectManagerProxy::ObjectAdded() @ ${OUT}/gen/SHARED_LIBRARIES/libwebservd-client-internal_intermediates/dbus_bindings/include/webservd/dbus-proxies.h
-> base::Callback<>::Run() @ external/libchrome/base/callback.h
-> libwebserv::DBusServer::ProtocolHandlerAdded() @ system/webserved/libwebserv/dbus_server.cc
-> buffet::WebServClient::OnProtocolHandlerConnected() @ system/weaved/buffet/webserv_client.cc
-> base::Callback<>::Run() @ external/libchrome/base/callback.h
-> buffet::Manager::CreateDevice() @ system/weaved/buffet/manager.cc
先看一下org::chromium::WebServer::ObjectManagerProxy::ObjectAdded()方法:
class ObjectManagerProxy : public dbus::ObjectManager::Interface { // ... void ObjectAdded( const dbus::ObjectPath& object_path, const std::string& interface_name) override { // ... if (interface_name == "org.chromium.WebServer.ProtocolHandler") { auto property_set = static_cast<org::chromium::WebServer::ProtocolHandlerProxy::PropertySet*>( dbus_object_manager_->GetProperties(object_path, interface_name)); std::unique_ptr<org::chromium::WebServer::ProtocolHandlerProxy> protocol_handler_proxy{ new org::chromium::WebServer::ProtocolHandlerProxy{bus_, object_path, property_set} }; auto p = protocol_handler_instances_.emplace(object_path, std::move(protocol_handler_proxy)); if (!on_protocol_handler_added_.is_null()) on_protocol_handler_added_.Run(p.first->second.get()); return; } // ... }
可以看到这里调用了on_protocol_handler_added_.Run(), 即调用libwebserv::DBusServer::ProtocolHandlerAdded()方法:
void DBusServer::ProtocolHandlerAdded( org::chromium::WebServer::ProtocolHandlerProxyInterface* handler) { VLOG(1) << "Server-side protocol handler with ID '" << handler->id() << "' is on-line (" << handler->name() << ")"; protocol_handler_id_map_.emplace(handler->GetObjectPath(), handler->id()); DBusProtocolHandler* registered_handler = GetProtocolHandlerImpl(handler->name()); if (registered_handler) { protocol_handlers_ids_.emplace(handler->id(), registered_handler); registered_handler->Connect(handler); if (!on_protocol_handler_connected_.is_null()) on_protocol_handler_connected_.Run(registered_handler); } }
可以看到,最后会去调用on_protocol_handler_connected_.Run(registered_handler)即调用buffer::WebServClient::OnProtocolHandlerConnected(callback):
void WebServClient::OnProtocolHandlerConnected( libwebserv::ProtocolHandler* protocol_handler) { if (protocol_handler->GetName() == libwebserv::ProtocolHandler::kHttp) { http_port_ = *protocol_handler->GetPorts().begin(); } else if (protocol_handler->GetName() == libwebserv::ProtocolHandler::kHttps) { https_port_ = *protocol_handler->GetPorts().begin(); certificate_ = protocol_handler->GetCertificateFingerprint(); } if (https_port_ && https_port_) server_available_callback_.Run(); }
可以看到,最后会去调用server_available_callback_.Run()即调用Manager::CreateDevice():
void Manager::CreateDevice() {
if (device_)
return;
device_ = weave::Device::Create(config_.get(), task_runner_.get(),
http_client_.get(), shill_client_.get(),
mdns_client_.get(), web_serv_client_.get(),
shill_client_.get(), bluetooth_client_.get());
LoadTraitDefinitions(options_.config_options, device_.get());
LoadCommandDefinitions(options_.config_options, device_.get());
LoadStateDefinitions(options_.config_options, device_.get());
LoadStateDefaults(options_.config_options, device_.get());
device_->AddSettingsChangedCallback(
base::Bind(&Manager::OnConfigChanged, weak_ptr_factory_.GetWeakPtr()));
device_->AddTraitDefsChangedCallback(
base::Bind(&Manager::OnTraitDefsChanged,
weak_ptr_factory_.GetWeakPtr()));
device_->AddStateChangedCallback(
base::Bind(&Manager::OnComponentTreeChanged,
weak_ptr_factory_.GetWeakPtr()));
device_->AddComponentTreeChangedCallback(
base::Bind(&Manager::OnComponentTreeChanged,
weak_ptr_factory_.GetWeakPtr()));
device_->AddGcdStateChangedCallback(
base::Bind(&Manager::OnGcdStateChanged, weak_ptr_factory_.GetWeakPtr()));
device_->AddPairingChangedCallbacks(
base::Bind(&Manager::OnPairingStart, weak_ptr_factory_.GetWeakPtr()),
base::Bind(&Manager::OnPairingEnd, weak_ptr_factory_.GetWeakPtr()));
device_->AddCommandHandler(kBaseComponent, kRebootCommand,
base::Bind(&Manager::OnRebootDevice,
weak_ptr_factory_.GetWeakPtr()));
CreateServicesForClients();
}
- weaved – libwebserv – add request handler
调用过程如下:
a. 通过libwebserv::DBusProtocolHandler::Connect() add request handler to webservd:
-> ...
-> dbus::ObjectManager::OnGetManagedObjects() @ external/libchrome/dbus/object_manager.cc
-> dbus::ObjectManager::UpdateObject() @ external/libchrome/dbus/object_manager.cc
-> org::chromium::WebServer::ObjectManagerProxy::ObjectAdded() @ ${OUT}/gen/SHARED_LIBRARIES/libwebservd-client-internal_intermediates/dbus_bindings/include/webservd/dbus-proxies.h
-> base::Callback<>::Run() @ external/libchrome/base/callback.h
-> libwebserv::DBusServer::ProtocolHandlerAdded() @ system/webserved/libwebserv/dbus_server.cc
-> libwebserv::DBusProtocolHandler::Connect() @ system/webservd/libwebserv/dbus_protocol_handler.cc
-> org::chromium::WebServer::ProtocolHandlerProxy::AddRequestHandlerAsync()
b. 通过libwebserv::DBusProtocolHandler::AddHandler() add request handler to webservd:
-> ...
-> dbus::ObjectManager::OnGetManagedObjects() @ external/libchrome/dbus/object_manager.cc
-> dbus::ObjectManager::UpdateObject() @ external/libchrome/dbus/object_manager.cc
-> org::chromium::WebServer::ObjectManagerProxy::ObjectAdded() @ ${OUT}/gen/SHARED_LIBRARIES/libwebservd-client-internal_intermediates/dbus_bindings/include/webservd/dbus-proxies.h
-> base::Callback<>::Run() @ external/libchrome/base/callback.h
-> libwebserv::DBusServer::ProtocolHandlerAdded() @ system/webserved/libwebserv/dbus_server.cc
-> buffet::WebServClient::OnProtocolHandlerConnected() @ system/weaved/buffet/webserv_client.cc
-> base::Callback<>::Run() @ external/libchrome/base/callback.h
-> buffet::Manager::CreateDevice() @ system/weaved/buffet/manager.cc
-> weave::Device::Create() @ external/libweave/src/device_manager.cc
-> weave::DeviceManager::DeviceManager() @ external/libweave/src/device_manager.cc
-> weave::DeviceManager::StartPrivet() @ external/libweave/src/device_manager.cc
-> weave::weave::privet::Manager::Start() @ external/libweave/src/privet/privet_manager.cc
-> buffet::WebServClient::AddHttpRequestHandler() @ system/weaved/buffet/webserv_client.cc
-> libwebserv::DBusProtocolHandler::AddHandlerCallback() @ system/webservd/libwebserv/dbus_protocol_handler.cc
-> libwebserv::DBusProtocolHandler::AddHandler() @ system/webservd/libwebserv/dbus_protool_handler.cc
-> org::chromium::WebServer::ProtocolHandlerProxy::AddRequestHandlerAsync()
libwebserv::DBusServer::ProtocolHandlerAdded()相关代码如下:
void DBusServer::ProtocolHandlerAdded( org::chromium::WebServer::ProtocolHandlerProxyInterface* handler) { VLOG(0) << "Server-side protocol handler with ID '" << handler->id() << "' is on-line (" << handler->name() << ")"; protocol_handler_id_map_.emplace(handler->GetObjectPath(), handler->id()); DBusProtocolHandler* registered_handler = GetProtocolHandlerImpl(handler->name()); if (registered_handler) { protocol_handlers_ids_.emplace(handler->id(), registered_handler); registered_handler->Connect(handler); if (!on_protocol_handler_connected_.is_null()) on_protocol_handler_connected_.Run(registered_handler); } }
NOTE: on_protocol_handler_connected_.Run()实际上就是调用buffet::WebServClient::OnProtocolHandlerConnected()方法。
- weaved – libwebserv – 关于protocol handler
从代码中可以看到weaved进程中只有两个DBusProtocolHander实例:
- http protocol handler: 处理http相关的request
- https protocol handler: 处理http & https相关的request
每个DBusProtocolHander实例中,可以有多个ProtocolHandlerProxyInterface (protocol handler client)。
- weaved – libwebserv – process request
如执行:
$ adb shell curl -H "Authorization: Privet anonymous" -k https://localhost/privet/info
调用过程如下:
-> ...
-> base::Callback<> @ external/libchrome/base/callback.h
-> libwebserv::DBusServer::RequestHandler::ProcessRequest() @ system/webserved/libwebserv/dbus_server.cc
-> libwebserv::DBusProtocolHandler::ProcessRequest() @ system/webservd/libwebserv/dbus_protocol_handler.cc
-> libwebserv::RequestHandlerCallback::HandleRquest() @ system/webservd/libwebserv/request_handler_callback.cc
-> base::Callback<>::Run() @ external/libchrome/base/callback.h:396
-> base::internal::Invoker<>::Run() @ external/libchrome/base/bind_internal.h:343
-> base::internal::InvokeHelper<>::MakeItSo() @ external/libchrome/base/bind_internal.h:303
-> base::internal::RunableAdapter<>::Run() @ external/libchrome/base/bind_internal.h:176
-> buffet::WebServClient::OnRequest() @ system/weaved/buffet/webserv_client.cc
-> base::Callback<>::Run() @ external/libchrome/base/callback.h
-> base::internal::Invoker<>::Run() @ external/libchrome/base/bind_internal.h:343
-> base::internal::InvokeHelper<>::MakeItSo() @ external/libchrome/base/bind_internal.h:303
-> base::internal::RunnableAdapter<>::Run() @external/libchrome/base/bind_internal.h:176
-> weave::privet::Manager::PrivetRequestHandler() @ external/libweave/src/privet/privet_manager.cc
-> weave::privet::Manager::PrivetRequestHandlerWithData() @ external/libweave/src/privet/privet_manager.cc
-> weave::privet::PrivetHandler::HandleInfo() @ external/libweave/src/privet/privet_handler.cc
- weaved – libwebserv – complete request
同样执行:
$ adb shell curl -H "Authorization: Privet anonymous" -k https://localhost/privet/info
调用过程如下:
-> ...
-> weave::privet::Manager::PrivetRequestHandler() @ external/libweave/src/privet/privet_manager.cc
-> weave::privet::Manager::PrivetRequestHandlerWithData() @ external/libweave/src/privet/privet_manager.cc
-> weave::privet::PrivetHandler::HandleInfo() @ external/libweave/src/privet/privet_handler.cc
-> base::Callback<>::Run() @ external/libchrome/base/callback.h
-> base::internal::Invoker<>::Run() @ external/libchrome/base/bind_internal.h:343
-> weave::privet::Manager::PrivetResponseHandler() @ external/libweave/src/privet/privet_manager.cc
-> libwebserv::ResponseImpl::ReplyWithText() @ system/webservd/libwebserv/response.cc
-> libwebserv::ResponseImpl::Reply() @ system/webservd/libwebserv/response.cc
-> libwebserv::ResponseImpl::SendResponse() @ system/webservd/libwebserv/response.cc
-> libwebserv::DBusProtocolHandler::CompleteRequest() @ system/webservd/libwebserv/dbus_protocol_handler.cc