* Added "http_ca{path/cert}" options. Patch by Johan Gunnarsson,

public domain.

* Minor bugfixes to SCgi.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@907 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2007-05-23 14:03:02 +00:00
parent 2db205a89d
commit bebce18368
6 changed files with 84 additions and 21 deletions
+35 -8
View File
@@ -37,6 +37,7 @@
#include "config.h"
#include <functional>
#include <rak/address_info.h>
#include <rak/file_stat.h>
#include <rak/path.h>
#include <torrent/connection_manager.h>
@@ -176,9 +177,9 @@ apply_fast_cgi(const std::string& arg) {
}
void
apply_scgi(const std::string& arg) {
apply_scgi(const std::string& arg, int type) {
if (control->fast_cgi() != NULL)
throw torrent::input_error("FastCGI already enabled.");
throw torrent::input_error("SCGI already enabled.");
if (control->xmlrpc() == NULL)
initialize_xmlrpc();
@@ -189,15 +190,38 @@ apply_scgi(const std::string& arg) {
try {
int port;
char dummy;
char address[1024];
if (std::sscanf(arg.c_str(), ":%i%c", &port, &dummy) == 1) {
if (port <= 0 || port >= (1 << 16))
throw torrent::input_error("Invalid port number.");
switch (type) {
case 1:
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);
control->scgi()->open_port(port);
} else {
} else if (std::sscanf(arg.c_str(), "%1023[^:]:%i%c", address, &port, &dummy) == 2) {
if (port <= 0 || port >= (1 << 16))
throw torrent::input_error("Invalid port number.");
int err;
rak::address_info* ai;
if ((err = rak::address_info::get_address_info(address, PF_INET, SOCK_STREAM, &ai)) != 0)
throw torrent::input_error("Could not bind address: " + std::string(rak::address_info::strerror(err)) + ".");
control->scgi()->open(ai->address()->c_sockaddr(), ai->address()->length());
} else {
throw torrent::input_error("Could not parse address.");
}
break;
case 2:
default:
control->scgi()->open_named(rak::path_expand(arg));
break;
}
} catch (torrent::local_error& e) {
@@ -248,6 +272,8 @@ initialize_command_network() {
ADD_COMMAND_STRING_TRI("ip", rak::make_mem_fun(control->core(), &core::Manager::set_local_address), rak::make_mem_fun(control->core(), &core::Manager::local_address));
ADD_COMMAND_STRING_TRI("proxy_address", rak::make_mem_fun(control->core(), &core::Manager::set_proxy_address), rak::make_mem_fun(control->core(), &core::Manager::proxy_address));
ADD_COMMAND_STRING_TRI("http_proxy", rak::make_mem_fun(httpStack, &core::CurlStack::set_http_proxy), rak::make_mem_fun(httpStack, &core::CurlStack::http_proxy));
ADD_COMMAND_STRING_TRI("http_capath", rak::make_mem_fun(httpStack, &core::CurlStack::set_http_capath), rak::make_mem_fun(httpStack, &core::CurlStack::http_capath));
ADD_COMMAND_STRING_TRI("http_cacert", rak::make_mem_fun(httpStack, &core::CurlStack::set_http_cacert), rak::make_mem_fun(httpStack, &core::CurlStack::http_cacert));
ADD_COMMAND_VALUE_TRI("send_buffer_size", rak::make_mem_fun(cm, &torrent::ConnectionManager::set_send_buffer_size), rak::make_mem_fun(cm, &torrent::ConnectionManager::send_buffer_size));
ADD_COMMAND_VALUE_TRI("receive_buffer_size", rak::make_mem_fun(cm, &torrent::ConnectionManager::set_receive_buffer_size), rak::make_mem_fun(cm, &torrent::ConnectionManager::receive_buffer_size));
@@ -261,7 +287,8 @@ initialize_command_network() {
ADD_COMMAND_VALUE_TRI("max_open_http", rak::make_mem_fun(httpStack, &core::CurlStack::set_max_active), rak::make_mem_fun(httpStack, &core::CurlStack::max_active));
ADD_COMMAND_STRING_UN("fast_cgi", std::ptr_fun(&apply_fast_cgi));
ADD_COMMAND_STRING_UN("scgi", std::ptr_fun(&apply_scgi));
ADD_COMMAND_STRING_UN("scgi_port", rak::bind2nd(std::ptr_fun(&apply_scgi), 1));
ADD_COMMAND_STRING_UN("scgi_local", rak::bind2nd(std::ptr_fun(&apply_scgi), 2));
ADD_COMMAND_VALUE_TRI("hash_read_ahead", std::ptr_fun(&apply_hash_read_ahead), rak::ptr_fun(torrent::hash_read_ahead));
ADD_COMMAND_VALUE_TRI("hash_interval", std::ptr_fun(&apply_hash_interval), rak::ptr_fun(torrent::hash_interval));
+6
View File
@@ -121,6 +121,12 @@ CurlStack::add_get(CurlGet* get) {
if (!m_bindAddress.empty())
curl_easy_setopt(get->handle(), CURLOPT_INTERFACE, m_bindAddress.c_str());
if (!m_httpCaPath.empty())
curl_easy_setopt(get->handle(), CURLOPT_CAPATH, m_httpCaPath.c_str());
if (!m_httpCaCert.empty())
curl_easy_setopt(get->handle(), CURLOPT_CAINFO, m_httpCaCert.c_str());
base_type::push_back(get);
if (m_active >= m_maxActive)
+8
View File
@@ -98,6 +98,12 @@ class CurlStack : std::deque<CurlGet*> {
const std::string& bind_address() const { return m_bindAddress; }
void set_bind_address(const std::string& s) { m_bindAddress = s; }
const std::string& http_capath() const { return m_httpCaPath; }
void set_http_capath(const std::string& s) { m_httpCaPath = s; }
const std::string& http_cacert() const { return m_httpCaCert; }
void set_http_cacert(const std::string& s) { m_httpCaCert = s; }
static void global_init();
static void global_cleanup();
@@ -118,6 +124,8 @@ class CurlStack : std::deque<CurlGet*> {
std::string m_userAgent;
std::string m_httpProxy;
std::string m_bindAddress;
std::string m_httpCaPath;
std::string m_httpCaCert;
};
}
+11 -3
View File
@@ -55,12 +55,19 @@ SCgi::~SCgi() {
if (!get_fd().is_valid())
return;
for (SCgiTask* itr = m_task, *last = m_task + max_tasks; itr != last; ++itr)
if (itr->is_open())
itr->close();
control->poll()->remove_read(this);
control->poll()->remove_error(this);
control->poll()->close(this);
get_fd().close();
get_fd().clear();
if (!m_path.empty())
::unlink(m_path.c_str());
}
void
@@ -90,6 +97,7 @@ SCgi::open_named(const std::string& filename) {
throw torrent::resource_error("Could not open socket for listening.");
open(sa, offsetof(struct sockaddr_un, sun_path) + filename.size() + 1);
m_path = filename;
}
void
@@ -98,7 +106,7 @@ SCgi::open(void* sa, unsigned int length) {
if (!get_fd().set_nonblock() ||
!get_fd().set_reuse_address(true) ||
!get_fd().bind(*reinterpret_cast<rak::socket_address*>(sa), length) ||
!get_fd().listen(10))
!get_fd().listen(max_tasks))
throw torrent::resource_error("Could not prepare socket for listening.");
torrent::connection_manager()->inc_socket_count();
@@ -121,9 +129,9 @@ SCgi::event_read() {
utils::SocketFd fd;
while ((fd = get_fd().accept(&sa)).is_valid()) {
SCgiTask* task = std::find_if(m_task, m_task + 10, std::mem_fun_ref(&SCgiTask::is_available));
SCgiTask* task = std::find_if(m_task, m_task + max_tasks, std::mem_fun_ref(&SCgiTask::is_available));
if (task == task + 10) {
if (task == task + max_tasks) {
// Ergh... just closing for now.
fd.close();
continue;
+5 -3
View File
@@ -54,9 +54,13 @@ public:
typedef rak::function2<bool, const char*, uint32_t> slot_write;
typedef rak::function3<bool, const char*, uint32_t, slot_write> slot_process;
static const int max_tasks = 10;
SCgi() {}
virtual ~SCgi();
void open(void* sa, unsigned int length);
void open_port(uint16_t port);
void open_named(const std::string& filename);
@@ -73,11 +77,9 @@ 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];
SCgiTask m_task[max_tasks];
};
}
+19 -7
View File
@@ -48,6 +48,12 @@
#include "globals.h"
#include "scgi.h"
// Test:
// #include "core/manager.h"
// #include <rak/timer.h>
// static rak::timer scgiTimer;
namespace rpc {
void
@@ -60,6 +66,8 @@ SCgiTask::open(SCgi* parent, int fd) {
control->poll()->open(this);
control->poll()->insert_read(this);
control->poll()->insert_error(this);
scgiTimer = rak::timer::current();
}
void
@@ -77,6 +85,11 @@ SCgiTask::close() {
delete [] m_buffer;
m_buffer = NULL;
// Test
// char buffer[512];
// sprintf(buffer, "SCgi system call processed: %i", (int)(rak::timer::current() - scgiTimer).usec());
// control->core()->push_log(std::string(buffer));
}
void
@@ -162,19 +175,18 @@ SCgiTask::event_error() {
bool
SCgiTask::receive_write(const char* buffer, uint32_t length) {
if (length + 44 > m_bufferSize) {
if (length + 256 > m_bufferSize) {
delete [] m_buffer;
m_buffer = new char[length + 44];
m_buffer = new char[length + 256];
}
// Try writing as much as possible from here, before copying
// anything.
// Who ever bothers to check the return value?
int headerSize = sprintf(m_buffer, "Status: 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %i\r\n\r\n", length);
m_position = m_buffer;
m_bufferSize = length + 44;
m_bufferSize = length + headerSize;
std::memcpy(m_buffer, "Status: 200 OK\r\nContent-Type: text/plain\r\n\r\n", 44);
std::memcpy(m_buffer + 44, buffer, length);
std::memcpy(m_buffer + headerSize, buffer, length);
event_write();