/* */ #include "HttpListenCommand.h" #include "DownloadEngine.h" #include "RecoverableException.h" #include "message.h" #include "Logger.h" #include "LogFactory.h" #include "SocketCore.h" #include "HttpServerCommand.h" #include "CUIDCounter.h" #include "RequestGroupMan.h" #include "prefs.h" #include "Option.h" #include "util.h" #include "A2STR.h" #include "fmt.h" namespace aria2 { HttpListenCommand::HttpListenCommand(cuid_t cuid, DownloadEngine* e, int family, bool secure) : Command(cuid), e_(e), family_(family), secure_(secure) { } HttpListenCommand::~HttpListenCommand() { if (serverSocket_) { e_->deleteSocketForReadCheck(serverSocket_, this); } } bool HttpListenCommand::execute() { if (e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) { return true; } try { if (serverSocket_->isReadable(0)) { std::shared_ptr socket(serverSocket_->acceptConnection()); socket->setTcpNodelay(true); auto endpoint = socket->getPeerInfo(); A2_LOG_INFO(fmt("RPC: Accepted the connection from %s:%u.", endpoint.addr.c_str(), endpoint.port)); e_->setNoWait(true); e_->addCommand( make_unique(e_->newCUID(), e_, socket, secure_)); } } catch (RecoverableException& e) { A2_LOG_DEBUG_EX(fmt(MSG_ACCEPT_FAILURE, getCuid()), e); } e_->addCommand(std::unique_ptr(this)); return false; } bool HttpListenCommand::bindPort(uint16_t port) { if (serverSocket_) { e_->deleteSocketForReadCheck(serverSocket_, this); } serverSocket_ = std::make_shared(); const int ipv = (family_ == AF_INET) ? 4 : 6; try { int flags = 0; if (e_->getOption()->getAsBool(PREF_RPC_LISTEN_ALL)) { flags = AI_PASSIVE; } serverSocket_->bind(nullptr, port, family_, flags); serverSocket_->beginListen(); A2_LOG_INFO(fmt(MSG_LISTENING_PORT, getCuid(), port)); e_->addSocketForReadCheck(serverSocket_, this); A2_LOG_NOTICE(fmt(_("IPv%d RPC: listening on TCP port %u"), ipv, port)); return true; } catch (RecoverableException& e) { A2_LOG_ERROR_EX(fmt("IPv%d RPC: failed to bind TCP port %u", ipv, port), e); serverSocket_->closeConnection(); } return false; } } // namespace aria2