/* */ #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