* Added support for named pipes and proper parseing of arguments for

SCGI.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@906 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2007-05-21 01:51:52 +00:00
parent 5f274b2619
commit 2db205a89d
6 changed files with 75 additions and 18 deletions
+20 -1
View File
@@ -38,6 +38,7 @@
#include <functional>
#include <rak/file_stat.h>
#include <rak/path.h>
#include <torrent/connection_manager.h>
#include <torrent/tracker.h>
#include <torrent/tracker_list.h>
@@ -184,7 +185,25 @@ apply_scgi(const std::string& arg) {
// Fix this...
control->set_scgi(new rpc::SCgi);
control->scgi()->open(5000);
try {
int port;
char dummy;
if (std::sscanf(arg.c_str(), ":%i%c", &port, &dummy) == 1) {
if (port <= 0 || port >= (1 << 16))
throw torrent::input_error("Invalid port number.");
control->scgi()->open_port(port);
} else {
control->scgi()->open_named(rak::path_expand(arg));
}
} catch (torrent::local_error& e) {
throw torrent::input_error(e.what());
}
control->scgi()->set_slot_process(rak::mem_fn(control->xmlrpc(), &rpc::XmlRpc::process));
}
+33 -12
View File
@@ -36,10 +36,11 @@
#include "config.h"
#include <rak/socket_address.h>
#include <sys/un.h>
#include <torrent/connection_manager.h>
#include <torrent/poll.h>
#include <torrent/torrent.h>
#include <rak/socket_address.h>
#include <torrent/exceptions.h>
#include "utils/socket_fd.h"
@@ -62,21 +63,43 @@ SCgi::~SCgi() {
get_fd().clear();
}
bool
SCgi::open(uint16_t port) {
void
SCgi::open_port(uint16_t port) {
rak::socket_address sa;
sa.sa_inet()->clear();
sa.sa_inet()->set_port(port);
if (!get_fd().open_stream())
throw torrent::resource_error("Could not allocate socket for listening.");
throw torrent::resource_error("Could not open socket for listening.");
open(sa.c_sockaddr(), sa.length());
}
void
SCgi::open_named(const std::string& filename) {
if (filename.empty() || filename.size() > 4096)
throw torrent::resource_error("Invalid filename length.");
char buffer[sizeof(sockaddr_un) + filename.size()];
sockaddr_un* sa = reinterpret_cast<sockaddr_un*>(buffer);
sa->sun_family = AF_LOCAL;
std::memcpy(sa->sun_path, filename.c_str(), filename.size() + 1);
if (!get_fd().open_local())
throw torrent::resource_error("Could not open socket for listening.");
open(sa, offsetof(struct sockaddr_un, sun_path) + filename.size() + 1);
}
void
SCgi::open(void* sa, unsigned int length) {
try {
rak::socket_address sa;
sa.sa_inet()->clear();
sa.sa_inet()->set_port(port);
if (!get_fd().set_nonblock() ||
!get_fd().set_reuse_address(true) ||
!get_fd().bind(sa) ||
!get_fd().bind(*reinterpret_cast<rak::socket_address*>(sa), length) ||
!get_fd().listen(10))
throw torrent::resource_error("Could not allocate socket for listening.");
throw torrent::resource_error("Could not prepare socket for listening.");
torrent::connection_manager()->inc_socket_count();
@@ -90,8 +113,6 @@ SCgi::open(uint16_t port) {
throw e;
}
return true;
}
void
+4 -3
View File
@@ -57,7 +57,8 @@ public:
SCgi() {}
virtual ~SCgi();
bool open(uint16_t port);
void open_port(uint16_t port);
void open_named(const std::string& filename);
const std::string path() const { return m_path; }
@@ -72,10 +73,10 @@ public:
utils::SocketFd& get_fd() { return *reinterpret_cast<utils::SocketFd*>(&m_fileDesc); }
private:
void open(void* sa, unsigned int length);
std::string m_path;
slot_process m_slotProcess;
SCgiTask m_task[10];
};
+4 -2
View File
@@ -96,7 +96,10 @@ SCgiTask::event_read() {
// Don't bother caching the parsed values, as we're likely to
// receive all the data we need the first time.
char* current;
char* contentPos;
int headerSize = strtol(m_buffer, &current, 0);
int contentSize;
if (current == m_buffer || current == m_position)
// Need to validate the header size.
@@ -111,8 +114,7 @@ SCgiTask::event_read() {
if (std::memcmp(current, "CONTENT_LENGTH", 15) != 0)
goto event_read_failed;
char* contentPos;
int contentSize = strtol(current + 15, &contentPos, 0);
contentSize = strtol(current + 15, &contentPos, 0);
if (*contentPos != '\0' || contentSize <= 0)
goto event_read_failed;
+12
View File
@@ -120,6 +120,11 @@ SocketFd::open_datagram() {
return (m_fd = socket(PF_INET, SOCK_DGRAM, 0)) != -1;
}
bool
SocketFd::open_local() {
return (m_fd = socket(PF_LOCAL, SOCK_DGRAM, 0)) != -1;
}
void
SocketFd::close() {
if (::close(m_fd) && errno == EBADF)
@@ -133,6 +138,13 @@ SocketFd::bind(const rak::socket_address& sa) {
return !::bind(m_fd, sa.c_sockaddr(), sa.length());
}
bool
SocketFd::bind(const rak::socket_address& sa, unsigned int length) {
check_valid();
return !::bind(m_fd, sa.c_sockaddr(), length);
}
bool
SocketFd::connect(const rak::socket_address& sa) {
check_valid();
+2
View File
@@ -69,11 +69,13 @@ public:
bool open_stream();
bool open_datagram();
bool open_local();
void close();
void clear() { m_fd = -1; }
bool bind(const rak::socket_address& sa);
bool bind(const rak::socket_address& sa, unsigned int length);
bool connect(const rak::socket_address& sa);
bool listen(int size);