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>
|
2009-01-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||||
|
|
||||||
Added experimental built-in HTTP server. Currently, when a client
|
Added experimental built-in HTTP server. Currently, when a client
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
#include "DlAbortEx.h"
|
#include "DlAbortEx.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
#include "LogFactory.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -47,7 +49,8 @@ HttpServer::HttpServer(const SharedHandle<SocketCore>& socket,
|
||||||
_socket(socket),
|
_socket(socket),
|
||||||
_socketBuffer(socket),
|
_socketBuffer(socket),
|
||||||
_e(e),
|
_e(e),
|
||||||
_headerProcessor(new HttpHeaderProcessor())
|
_headerProcessor(new HttpHeaderProcessor()),
|
||||||
|
_logger(LogFactory::getInstance())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
HttpServer::~HttpServer() {}
|
HttpServer::~HttpServer() {}
|
||||||
|
@ -69,16 +72,40 @@ SharedHandle<HttpHeader> HttpServer::receiveRequest()
|
||||||
size -= putbackDataLength;
|
size -= putbackDataLength;
|
||||||
_socket->readData(buf, size);
|
_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)
|
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-Type: text/html\r\n"
|
||||||
"Content-Length: "+Util::uitos(text.size())+"\r\n"
|
"Content-Length: "+Util::uitos(text.size())+"\r\n";
|
||||||
"Connection: close\r\n"
|
|
||||||
"\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(header);
|
||||||
_socketBuffer.feedSendBuffer(text);
|
_socketBuffer.feedSendBuffer(text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ class SocketCore;
|
||||||
class HttpHeader;
|
class HttpHeader;
|
||||||
class HttpHeaderProcessor;
|
class HttpHeaderProcessor;
|
||||||
class DownloadEngine;
|
class DownloadEngine;
|
||||||
|
class Logger;
|
||||||
|
|
||||||
class HttpServer {
|
class HttpServer {
|
||||||
private:
|
private:
|
||||||
|
@ -55,6 +56,8 @@ private:
|
||||||
SocketBuffer _socketBuffer;
|
SocketBuffer _socketBuffer;
|
||||||
DownloadEngine* _e;
|
DownloadEngine* _e;
|
||||||
SharedHandle<HttpHeaderProcessor> _headerProcessor;
|
SharedHandle<HttpHeaderProcessor> _headerProcessor;
|
||||||
|
Logger* _logger;
|
||||||
|
SharedHandle<HttpHeader> _lastRequestHeader;
|
||||||
public:
|
public:
|
||||||
HttpServer(const SharedHandle<SocketCore>& socket, DownloadEngine* e);
|
HttpServer(const SharedHandle<SocketCore>& socket, DownloadEngine* e);
|
||||||
|
|
||||||
|
@ -67,6 +70,8 @@ public:
|
||||||
ssize_t sendResponse();
|
ssize_t sendResponse();
|
||||||
|
|
||||||
bool sendBufferIsEmpty() const;
|
bool sendBufferIsEmpty() const;
|
||||||
|
|
||||||
|
bool supportsPersistentConnection() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "HttpServerResponseCommand.h"
|
#include "HttpServerResponseCommand.h"
|
||||||
#include "CheckIntegrityEntry.h"
|
#include "CheckIntegrityEntry.h"
|
||||||
#include "FileAllocationEntry.h"
|
#include "FileAllocationEntry.h"
|
||||||
|
#include "RecoverableException.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -64,6 +65,18 @@ HttpServerCommand::HttpServerCommand(int32_t cuid, DownloadEngine* e,
|
||||||
_e->addSocketForReadCheck(_socket, this);
|
_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()
|
HttpServerCommand::~HttpServerCommand()
|
||||||
{
|
{
|
||||||
_e->deleteSocketForReadCheck(_socket, this);
|
_e->deleteSocketForReadCheck(_socket, this);
|
||||||
|
@ -218,9 +231,19 @@ static std::string createResponse(DownloadEngine* e)
|
||||||
|
|
||||||
bool HttpServerCommand::execute()
|
bool HttpServerCommand::execute()
|
||||||
{
|
{
|
||||||
|
if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if(_socket->isReadable(0)) {
|
if(_socket->isReadable(0)) {
|
||||||
_timeout.reset();
|
_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()) {
|
if(header.isNull()) {
|
||||||
_e->commands.push_back(this);
|
_e->commands.push_back(this);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -55,6 +55,11 @@ public:
|
||||||
HttpServerCommand(int32_t cuid, DownloadEngine* e,
|
HttpServerCommand(int32_t cuid, DownloadEngine* e,
|
||||||
const SharedHandle<SocketCore>& socket);
|
const SharedHandle<SocketCore>& socket);
|
||||||
|
|
||||||
|
HttpServerCommand(int32_t cuid,
|
||||||
|
const SharedHandle<HttpServer>& httpServer,
|
||||||
|
DownloadEngine* e,
|
||||||
|
const SharedHandle<SocketCore>& socket);
|
||||||
|
|
||||||
virtual ~HttpServerCommand();
|
virtual ~HttpServerCommand();
|
||||||
|
|
||||||
virtual bool execute();
|
virtual bool execute();
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
#include "DownloadEngine.h"
|
#include "DownloadEngine.h"
|
||||||
#include "HttpServer.h"
|
#include "HttpServer.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "HttpServerCommand.h"
|
||||||
|
#include "RequestGroupMan.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -61,9 +63,17 @@ HttpServerResponseCommand::~HttpServerResponseCommand()
|
||||||
|
|
||||||
bool HttpServerResponseCommand::execute()
|
bool HttpServerResponseCommand::execute()
|
||||||
{
|
{
|
||||||
|
if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
_httpServer->sendResponse();
|
_httpServer->sendResponse();
|
||||||
if(_httpServer->sendBufferIsEmpty()) {
|
if(_httpServer->sendBufferIsEmpty()) {
|
||||||
logger->info("CUID#%d - HttpServer: all response transmitted.", cuid);
|
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;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if(_timeout.elapsed(10)) {
|
if(_timeout.elapsed(10)) {
|
||||||
|
|
Loading…
Reference in New Issue