/* */ #include "HttpServerCommand.h" #include "SocketCore.h" #include "DownloadEngine.h" #include "HttpServer.h" #include "HttpHeader.h" #include "Logger.h" #include "LogFactory.h" #include "RequestGroup.h" #include "RequestGroupMan.h" #include "HttpServerBodyCommand.h" #include "HttpServerResponseCommand.h" #include "RecoverableException.h" #include "prefs.h" #include "Option.h" #include "util.h" #include "wallclock.h" #include "fmt.h" #include "SocketRecvBuffer.h" namespace aria2 { HttpServerCommand::HttpServerCommand (cuid_t cuid, DownloadEngine* e, const SharedHandle& socket) : Command(cuid), e_(e), socket_(socket), httpServer_(new HttpServer(socket, e)) { setStatus(Command::STATUS_ONESHOT_REALTIME); e_->addSocketForReadCheck(socket_, this); httpServer_->setUsernamePassword(e_->getOption()->get(PREF_RPC_USER), e_->getOption()->get(PREF_RPC_PASSWD)); if(e_->getOption()->getAsBool(PREF_RPC_ALLOW_ORIGIN_ALL)) { httpServer_->setAllowOrigin("*"); } #ifdef HAVE_ZLIB httpServer_->enableGZip(); #else // !HAVE_ZLIB httpServer_->disableGZip(); #endif // !HAVE_ZLIB checkSocketRecvBuffer(); } HttpServerCommand::HttpServerCommand (cuid_t cuid, const SharedHandle& httpServer, DownloadEngine* e, const SharedHandle& socket) : Command(cuid), e_(e), socket_(socket), httpServer_(httpServer) { e_->addSocketForReadCheck(socket_, this); checkSocketRecvBuffer(); } HttpServerCommand::~HttpServerCommand() { e_->deleteSocketForReadCheck(socket_, this); } void HttpServerCommand::checkSocketRecvBuffer() { if(!httpServer_->getSocketRecvBuffer()->bufferEmpty()) { setStatus(Command::STATUS_ONESHOT_REALTIME); e_->setNoWait(true); } } bool HttpServerCommand::execute() { if(e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) { return true; } try { if(socket_->isReadable(0) || !httpServer_->getSocketRecvBuffer()->bufferEmpty()) { timeoutTimer_ = global::wallclock(); SharedHandle header; header = httpServer_->receiveRequest(); if(!header) { e_->addCommand(this); return false; } if(!httpServer_->authenticate()) { httpServer_->disableKeepAlive(); std::string text; httpServer_->feedResponse("401 Unauthorized", "WWW-Authenticate: Basic realm=\"aria2\"", text,"text/html"); Command* command = new HttpServerResponseCommand(getCuid(), httpServer_, e_, socket_); e_->addCommand(command); e_->setNoWait(true); return true; } if(e_->getOption()->getAsInt(PREF_RPC_MAX_REQUEST_SIZE) < httpServer_->getContentLength()) { A2_LOG_INFO (fmt("Request too long. ContentLength=%lld." " See --rpc-max-request-size option to loose" " this limitation.", static_cast(httpServer_->getContentLength()))); return true; } Command* command = new HttpServerBodyCommand(getCuid(), httpServer_, e_, socket_); e_->addCommand(command); e_->setNoWait(true); return true; } else { if(timeoutTimer_.difference(global::wallclock()) >= 30) { A2_LOG_INFO("HTTP request timeout."); return true; } else { e_->addCommand(this); return false; } } } catch(RecoverableException& e) { A2_LOG_INFO_EX(fmt("CUID#%lld - Error occurred while reading HTTP request", getCuid()), e); return true; } } } // namespace aria2