/* */ #include "AbstractHttpServerResponseCommand.h" #include "SocketCore.h" #include "DownloadEngine.h" #include "HttpServer.h" #include "Logger.h" #include "LogFactory.h" #include "HttpServerCommand.h" #include "RequestGroupMan.h" #include "RecoverableException.h" #include "wallclock.h" #include "util.h" #include "fmt.h" namespace aria2 { AbstractHttpServerResponseCommand::AbstractHttpServerResponseCommand( cuid_t cuid, const std::shared_ptr& httpServer, DownloadEngine* e, const std::shared_ptr& socket) : Command(cuid), e_(e), socket_(socket), httpServer_(httpServer), readCheck_(false), writeCheck_(true) { setStatus(Command::STATUS_ONESHOT_REALTIME); e_->addSocketForWriteCheck(socket_, this); } AbstractHttpServerResponseCommand::~AbstractHttpServerResponseCommand() { if (readCheck_) { e_->deleteSocketForReadCheck(socket_, this); } if (writeCheck_) { e_->deleteSocketForWriteCheck(socket_, this); } } void AbstractHttpServerResponseCommand::updateReadWriteCheck() { if (httpServer_->wantRead()) { if (!readCheck_) { readCheck_ = true; e_->addSocketForReadCheck(socket_, this); } } else if (readCheck_) { readCheck_ = false; e_->deleteSocketForReadCheck(socket_, this); } if (httpServer_->wantWrite()) { if (!writeCheck_) { writeCheck_ = true; e_->addSocketForWriteCheck(socket_, this); } } else if (writeCheck_) { writeCheck_ = false; e_->deleteSocketForWriteCheck(socket_, this); } } bool AbstractHttpServerResponseCommand::execute() { if (e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) { return true; } try { ssize_t len = httpServer_->sendResponse(); if (len > 0) { timeoutTimer_ = global::wallclock(); } } catch (RecoverableException& e) { A2_LOG_INFO_EX(fmt("CUID#%" PRId64 " - Error occurred while transmitting response body.", getCuid()), e); return true; } if (httpServer_->sendBufferIsEmpty()) { A2_LOG_INFO(fmt("CUID#%" PRId64 " - HttpServer: all response transmitted.", getCuid())); afterSend(httpServer_, e_); return true; } else { if (timeoutTimer_.difference(global::wallclock()) >= 30_s) { A2_LOG_INFO(fmt("CUID#%" PRId64 " - HttpServer: Timeout while trasmitting response.", getCuid())); return true; } else { updateReadWriteCheck(); e_->addCommand(std::unique_ptr(this)); return false; } } } } // namespace aria2