diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-01-25 10:55:27 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-01-25 10:55:27 +0000 |
| commit | 5def96906fd17d9b48e9fda192617c6ad1b95683 (patch) | |
| tree | 7907dd734fbaa2a43636c2a7fea342bb5ef773e5 /src | |
| parent | 0742e3921f185613f98c2b31cd03182d8aa1d6f5 (diff) | |
2009-01-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Persist connection between the built-in HTTP server and a client
if a client supports keep-alive. Fixed the bug that aria2 exits
when the HTTP server receives EOF from a client.
* src/HttpServer.cc
* src/HttpServer.h
* src/HttpServerCommand.cc
* src/HttpServerCommand.h
* src/HttpServerResponseCommand.cc
Diffstat (limited to 'src')
| -rw-r--r-- | src/HttpServer.cc | 39 | ||||
| -rw-r--r-- | src/HttpServer.h | 5 | ||||
| -rw-r--r-- | src/HttpServerCommand.cc | 25 | ||||
| -rw-r--r-- | src/HttpServerCommand.h | 5 | ||||
| -rw-r--r-- | src/HttpServerResponseCommand.cc | 10 |
5 files changed, 77 insertions, 7 deletions
diff --git a/src/HttpServer.cc b/src/HttpServer.cc index 14cf6192..cae0a076 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -39,6 +39,8 @@ #include "DlAbortEx.h" #include "message.h" #include "Util.h" +#include "LogFactory.h" +#include "Logger.h" namespace aria2 { @@ -47,7 +49,8 @@ HttpServer::HttpServer(const SharedHandle<SocketCore>& socket, _socket(socket), _socketBuffer(socket), _e(e), - _headerProcessor(new HttpHeaderProcessor()) + _headerProcessor(new HttpHeaderProcessor()), + _logger(LogFactory::getInstance()) {} HttpServer::~HttpServer() {} @@ -69,16 +72,40 @@ SharedHandle<HttpHeader> HttpServer::receiveRequest() size -= putbackDataLength; _socket->readData(buf, size); - return _headerProcessor->getHttpRequestHeader(); + SharedHandle<HttpHeader> header = _headerProcessor->getHttpRequestHeader(); + if(!header.isNull()) { + _logger->info("HTTP Server received request\n%s", + _headerProcessor->getHeaderString().c_str()); + _lastRequestHeader = header; + _headerProcessor->clear(); + } + + return header; +} + +bool HttpServer::supportsPersistentConnection() const +{ + std::string connection = + Util::toLower(_lastRequestHeader->getFirst(HttpHeader::CONNECTION)); + + return connection.find(HttpHeader::CLOSE) == std::string::npos && + (_lastRequestHeader->getVersion() == HttpHeader::HTTP_1_1 || + connection.find("keep-alive") != std::string::npos); } void HttpServer::feedResponse(const std::string& text) { - std::string header = "HTTP/1.0 200 OK\r\n" + std::string header = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" - "Content-Length: "+Util::uitos(text.size())+"\r\n" - "Connection: close\r\n" - "\r\n"; + "Content-Length: "+Util::uitos(text.size())+"\r\n"; + + if(!supportsPersistentConnection()) { + header += "Connection: close\r\n"; + } + header += "\r\n"; + + _logger->debug("HTTP Server sends response:\n%s", header.c_str()); + _socketBuffer.feedSendBuffer(header); _socketBuffer.feedSendBuffer(text); } diff --git a/src/HttpServer.h b/src/HttpServer.h index 9b755f18..9b789260 100644 --- a/src/HttpServer.h +++ b/src/HttpServer.h @@ -48,6 +48,7 @@ class SocketCore; class HttpHeader; class HttpHeaderProcessor; class DownloadEngine; +class Logger; class HttpServer { private: @@ -55,6 +56,8 @@ private: SocketBuffer _socketBuffer; DownloadEngine* _e; SharedHandle<HttpHeaderProcessor> _headerProcessor; + Logger* _logger; + SharedHandle<HttpHeader> _lastRequestHeader; public: HttpServer(const SharedHandle<SocketCore>& socket, DownloadEngine* e); @@ -67,6 +70,8 @@ public: ssize_t sendResponse(); bool sendBufferIsEmpty() const; + + bool supportsPersistentConnection() const; }; } // namespace aria2 diff --git a/src/HttpServerCommand.cc b/src/HttpServerCommand.cc index 3670605b..4bbd0117 100644 --- a/src/HttpServerCommand.cc +++ b/src/HttpServerCommand.cc @@ -51,6 +51,7 @@ #include "HttpServerResponseCommand.h" #include "CheckIntegrityEntry.h" #include "FileAllocationEntry.h" +#include "RecoverableException.h" namespace aria2 { @@ -64,6 +65,18 @@ HttpServerCommand::HttpServerCommand(int32_t cuid, DownloadEngine* e, _e->addSocketForReadCheck(_socket, this); } +HttpServerCommand::HttpServerCommand(int32_t cuid, + const SharedHandle<HttpServer>& httpServer, + DownloadEngine* e, + const SharedHandle<SocketCore>& socket): + Command(cuid), + _e(e), + _socket(socket), + _httpServer(httpServer) +{ + _e->addSocketForReadCheck(_socket, this); +} + HttpServerCommand::~HttpServerCommand() { _e->deleteSocketForReadCheck(_socket, this); @@ -218,9 +231,19 @@ static std::string createResponse(DownloadEngine* e) bool HttpServerCommand::execute() { + if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) { + return true; + } if(_socket->isReadable(0)) { _timeout.reset(); - SharedHandle<HttpHeader> header = _httpServer->receiveRequest(); + SharedHandle<HttpHeader> header; + try { + header = _httpServer->receiveRequest(); + } catch(RecoverableException& e) { + logger->info("CUID#%d - Error occurred while reading HTTP request", + e, cuid); + return true; + } if(header.isNull()) { _e->commands.push_back(this); return false; diff --git a/src/HttpServerCommand.h b/src/HttpServerCommand.h index cfb42168..f126ab3f 100644 --- a/src/HttpServerCommand.h +++ b/src/HttpServerCommand.h @@ -55,6 +55,11 @@ public: HttpServerCommand(int32_t cuid, DownloadEngine* e, const SharedHandle<SocketCore>& socket); + HttpServerCommand(int32_t cuid, + const SharedHandle<HttpServer>& httpServer, + DownloadEngine* e, + const SharedHandle<SocketCore>& socket); + virtual ~HttpServerCommand(); virtual bool execute(); diff --git a/src/HttpServerResponseCommand.cc b/src/HttpServerResponseCommand.cc index 0578c7a8..ca096b93 100644 --- a/src/HttpServerResponseCommand.cc +++ b/src/HttpServerResponseCommand.cc @@ -37,6 +37,8 @@ #include "DownloadEngine.h" #include "HttpServer.h" #include "Logger.h" +#include "HttpServerCommand.h" +#include "RequestGroupMan.h" namespace aria2 { @@ -61,9 +63,17 @@ HttpServerResponseCommand::~HttpServerResponseCommand() bool HttpServerResponseCommand::execute() { + if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) { + return true; + } _httpServer->sendResponse(); if(_httpServer->sendBufferIsEmpty()) { logger->info("CUID#%d - HttpServer: all response transmitted.", cuid); + if(_httpServer->supportsPersistentConnection()) { + logger->info("CUID#%d - Persist connection.", cuid); + _e->commands.push_back + (new HttpServerCommand(cuid, _httpServer, _e, _socket)); + } return true; } else { if(_timeout.elapsed(10)) { |
