mirror of https://github.com/aria2/aria2
2009-05-10 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added BASIC authentication for XML-RPC. Added --xml-rpc-user and --xml-rpc-passwd option. * src/HttpServer.cc * src/HttpServer.h * src/HttpServerCommand.cc * src/OptionHandlerFactory.cc * src/prefs.cc * src/prefs.h * src/usage_text.hpull/1/head
parent
d237c5e442
commit
7aefbb7338
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2009-05-10 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Added BASIC authentication for XML-RPC. Added --xml-rpc-user and
|
||||
--xml-rpc-passwd option.
|
||||
* src/HttpServer.cc
|
||||
* src/HttpServer.h
|
||||
* src/HttpServerCommand.cc
|
||||
* src/OptionHandlerFactory.cc
|
||||
* src/prefs.cc
|
||||
* src/prefs.h
|
||||
* src/usage_text.h
|
||||
|
||||
2009-05-10 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
|
||||
|
||||
Fixed the bug that SocketCore::isReadable() prevents aria2 from
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "Util.h"
|
||||
#include "LogFactory.h"
|
||||
#include "Logger.h"
|
||||
#include "Base64.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -133,13 +134,28 @@ bool HttpServer::supportsPersistentConnection() const
|
|||
|
||||
void HttpServer::feedResponse(const std::string& text, const std::string& contentType)
|
||||
{
|
||||
std::string header = "HTTP/1.1 200 OK\r\n"
|
||||
feedResponse("200 OK", "", text, contentType);
|
||||
}
|
||||
|
||||
void HttpServer::feedResponse(const std::string& status,
|
||||
const std::string& headers,
|
||||
const std::string& text,
|
||||
const std::string& contentType)
|
||||
{
|
||||
std::string header = "HTTP/1.1 "+status+"\r\n"
|
||||
"Content-Type: "+contentType+"\r\n"
|
||||
"Content-Length: "+Util::uitos(text.size())+"\r\n";
|
||||
|
||||
if(!supportsPersistentConnection()) {
|
||||
header += "Connection: close\r\n";
|
||||
}
|
||||
if(!headers.empty()) {
|
||||
header += headers;
|
||||
if(!Util::endsWith(headers, "\r\n")) {
|
||||
header += "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
header += "\r\n";
|
||||
|
||||
_logger->debug("HTTP Server sends response:\n%s", header.c_str());
|
||||
|
@ -158,4 +174,23 @@ bool HttpServer::sendBufferIsEmpty() const
|
|||
return _socketBuffer.sendBufferIsEmpty();
|
||||
}
|
||||
|
||||
bool HttpServer::authenticate()
|
||||
{
|
||||
if(_username.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string authHeader = _lastRequestHeader->getFirst("Authorization");
|
||||
if(authHeader.empty()) {
|
||||
return false;
|
||||
}
|
||||
std::pair<std::string, std::string> p = Util::split(authHeader, " ");
|
||||
if(p.first != "Basic") {
|
||||
return false;
|
||||
}
|
||||
std::string userpass = Base64::decode(p.second);
|
||||
std::pair<std::string, std::string> userpassPair = Util::split(userpass, ":");
|
||||
return _username == userpassPair.first && _password == userpassPair.second;
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -62,6 +62,8 @@ private:
|
|||
uint64_t _lastContentLength;
|
||||
std::stringstream _lastBody;
|
||||
bool _keepAlive;
|
||||
std::string _username;
|
||||
std::string _password;
|
||||
public:
|
||||
HttpServer(const SharedHandle<SocketCore>& socket, DownloadEngine* e);
|
||||
|
||||
|
@ -77,6 +79,20 @@ public:
|
|||
|
||||
void feedResponse(const std::string& text, const std::string& contentType);
|
||||
|
||||
void feedResponse(const std::string& status,
|
||||
const std::string& headers,
|
||||
const std::string& text,
|
||||
const std::string& contentType);
|
||||
|
||||
bool authenticate();
|
||||
|
||||
void setUsernamePassword
|
||||
(const std::string& username, const std::string& password)
|
||||
{
|
||||
_username = username;
|
||||
_password = password;
|
||||
}
|
||||
|
||||
ssize_t sendResponse();
|
||||
|
||||
bool sendBufferIsEmpty() const;
|
||||
|
@ -86,6 +102,8 @@ public:
|
|||
void enableKeepAlive() { _keepAlive = true; }
|
||||
|
||||
void disableKeepAlive() { _keepAlive = false; }
|
||||
|
||||
uint64_t getContentLength() const { return _lastContentLength; }
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -41,7 +41,10 @@
|
|||
#include "RequestGroup.h"
|
||||
#include "RequestGroupMan.h"
|
||||
#include "HttpServerBodyCommand.h"
|
||||
#include "HttpServerResponseCommand.h"
|
||||
#include "RecoverableException.h"
|
||||
#include "prefs.h"
|
||||
#include "Option.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -53,6 +56,8 @@ HttpServerCommand::HttpServerCommand(int32_t cuid, DownloadEngine* e,
|
|||
_httpServer(new HttpServer(socket, e))
|
||||
{
|
||||
_e->addSocketForReadCheck(_socket, this);
|
||||
_httpServer->setUsernamePassword(_e->option->get(PREF_XML_RPC_USER),
|
||||
_e->option->get(PREF_XML_RPC_PASSWD));
|
||||
}
|
||||
|
||||
HttpServerCommand::HttpServerCommand(int32_t cuid,
|
||||
|
@ -87,6 +92,18 @@ bool HttpServerCommand::execute()
|
|||
e, cuid);
|
||||
return true;
|
||||
}
|
||||
if(!_httpServer->authenticate()) {
|
||||
_httpServer->disableKeepAlive();
|
||||
_httpServer->feedResponse("401 Unauthorized",
|
||||
"WWW-Authenticate: Basic realm=\"aria2\"",
|
||||
"","text/html");
|
||||
Command* command =
|
||||
new HttpServerResponseCommand(cuid, _httpServer, _e, _socket);
|
||||
command->setStatus(Command::STATUS_ONESHOT_REALTIME);
|
||||
_e->commands.push_back(command);
|
||||
_e->setNoWait(true);
|
||||
return true;
|
||||
}
|
||||
if(header.isNull()) {
|
||||
_e->commands.push_back(this);
|
||||
return false;
|
||||
|
|
|
@ -364,6 +364,20 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
|
|||
op->addTag(TAG_ADVANCED);
|
||||
handlers.push_back(op);
|
||||
}
|
||||
{
|
||||
SharedHandle<OptionHandler> op(new DefaultOptionHandler
|
||||
(PREF_XML_RPC_USER,
|
||||
TEXT_XML_RPC_USER));
|
||||
op->addTag(TAG_ADVANCED);
|
||||
handlers.push_back(op);
|
||||
}
|
||||
{
|
||||
SharedHandle<OptionHandler> op(new DefaultOptionHandler
|
||||
(PREF_XML_RPC_PASSWD,
|
||||
TEXT_XML_RPC_PASSWD));
|
||||
op->addTag(TAG_ADVANCED);
|
||||
handlers.push_back(op);
|
||||
}
|
||||
#endif // ENABLE_XML_RPC
|
||||
// HTTP/FTP options
|
||||
{
|
||||
|
|
|
@ -163,6 +163,10 @@ const std::string PREF_RESET_URI("reset-uri");
|
|||
const std::string PREF_DRY_RUN("dry-run");
|
||||
// value: true | false
|
||||
const std::string PREF_REUSE_URI("reuse-uri");
|
||||
// value: string
|
||||
const std::string PREF_XML_RPC_USER("xml-rpc-user");
|
||||
// value: string
|
||||
const std::string PREF_XML_RPC_PASSWD("xml-rpc-passwd");
|
||||
|
||||
/**
|
||||
* FTP related preferences
|
||||
|
|
|
@ -167,6 +167,10 @@ extern const std::string PREF_RESET_URI;
|
|||
extern const std::string PREF_DRY_RUN;
|
||||
// value: true | false
|
||||
extern const std::string PREF_REUSE_URI;
|
||||
// value: string
|
||||
extern const std::string PREF_XML_RPC_USER;
|
||||
// value: string
|
||||
extern const std::string PREF_XML_RPC_PASSWD;
|
||||
|
||||
/**
|
||||
* FTP related preferences
|
||||
|
|
|
@ -481,10 +481,15 @@ _(" --event-poll=POLL Specify the method for polling events.")
|
|||
#define TEXT_XML_RPC_LISTEN_PORT \
|
||||
_(" --xml-rpc-listen-port=PORT Specify a port number for XML-RPC server to listen\n"\
|
||||
" to.")
|
||||
// Excluded from translation candidiates because it is subject to change.
|
||||
#define TEXT_ENABLE_XML_RPC \
|
||||
_(" --enable-xml-rpc[=true|false] Enable XML-RPC server.\n"\
|
||||
" See also --xml-rpc-listen-port option.")
|
||||
" It is strongly recommended to set username and\n"\
|
||||
" password using --xml-rpc-user and --xml-rpc-passwd\n"\
|
||||
" option. See also --xml-rpc-listen-port option.")
|
||||
#define TEXT_XML_RPC_USER \
|
||||
_(" --xml-rpc-user=USER Set XML-RPC user.")
|
||||
#define TEXT_XML_RPC_PASSWD \
|
||||
_(" --xml-rpc-passwd=PASSWD Set XML-RPC password.")
|
||||
#define TEXT_BT_EXTERNAL_IP \
|
||||
_(" --bt-external-ip=IPADDRESS Specify the external IP address to report to a\n"\
|
||||
" BitTorrent tracker. Although this function is\n"\
|
||||
|
|
Loading…
Reference in New Issue