mirror of https://github.com/aria2/aria2
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.ccpull/1/head
parent
0742e3921f
commit
5def96906f
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
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
|
||||
|
||||
2009-01-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Added experimental built-in HTTP server. Currently, when a client
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Reference in New Issue