mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-21 08:36:18 +00:00
* Allow i8 and apache style 64bit integer support in XMLRPC. Use
"xmlrpc_dialect" command to change. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@929 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
@@ -243,6 +243,25 @@ apply_scgi(const std::string& arg, int type) {
|
|||||||
control->scgi()->set_slot_process(rak::mem_fn(control->xmlrpc(), &rpc::XmlRpc::process));
|
control->scgi()->set_slot_process(rak::mem_fn(control->xmlrpc(), &rpc::XmlRpc::process));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
apply_xmlrpc_dialect(const std::string& arg) {
|
||||||
|
if (control->xmlrpc() == NULL)
|
||||||
|
initialize_xmlrpc();
|
||||||
|
|
||||||
|
int value;
|
||||||
|
|
||||||
|
if (arg == "i8")
|
||||||
|
value = rpc::XmlRpc::dialect_i8;
|
||||||
|
else if (arg == "apache")
|
||||||
|
value = rpc::XmlRpc::dialect_apache;
|
||||||
|
else if (arg == "generic")
|
||||||
|
value = rpc::XmlRpc::dialect_generic;
|
||||||
|
else
|
||||||
|
value = -1;
|
||||||
|
|
||||||
|
control->xmlrpc()->set_dialect(value);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
initialize_command_network() {
|
initialize_command_network() {
|
||||||
// core::DownloadList* downloadList = control->core()->download_list();
|
// core::DownloadList* downloadList = control->core()->download_list();
|
||||||
@@ -299,6 +318,7 @@ initialize_command_network() {
|
|||||||
ADD_COMMAND_STRING_UN("scgi_port", rak::bind2nd(std::ptr_fun(&apply_scgi), 1));
|
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_STRING_UN("scgi_local", rak::bind2nd(std::ptr_fun(&apply_scgi), 2));
|
||||||
ADD_VARIABLE_BOOL("scgi_dont_route", false);
|
ADD_VARIABLE_BOOL("scgi_dont_route", false);
|
||||||
|
ADD_COMMAND_STRING_UN("xmlrpc_dialect", std::ptr_fun(&apply_xmlrpc_dialect));
|
||||||
|
|
||||||
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_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));
|
ADD_COMMAND_VALUE_TRI("hash_interval", std::ptr_fun(&apply_hash_interval), rak::ptr_fun(torrent::hash_interval));
|
||||||
|
|||||||
+84
-23
@@ -49,10 +49,23 @@
|
|||||||
|
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
|
|
||||||
|
// Ugly...
|
||||||
|
#ifdef XMLRPC_HAVE_I8
|
||||||
|
int XmlRpc::m_dialect = dialect_i8;
|
||||||
|
#else
|
||||||
|
int XmlRpc::m_dialect = dialect_generic;
|
||||||
|
#endif
|
||||||
|
|
||||||
XmlRpc::slot_find_download XmlRpc::m_slotFindDownload;
|
XmlRpc::slot_find_download XmlRpc::m_slotFindDownload;
|
||||||
|
|
||||||
#ifdef HAVE_XMLRPC_C
|
#ifdef HAVE_XMLRPC_C
|
||||||
|
|
||||||
|
xmlrpc_value* xmlrpc_call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo);
|
||||||
|
xmlrpc_value* xmlrpc_call_command_d(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo);
|
||||||
|
|
||||||
|
core::Download* xmlrpc_to_download(xmlrpc_env* env, xmlrpc_value* value);
|
||||||
|
torrent::Object xmlrpc_to_object_d(xmlrpc_env* env, xmlrpc_value* value, core::Download** download);
|
||||||
|
|
||||||
torrent::Object
|
torrent::Object
|
||||||
xmlrpc_to_object(xmlrpc_env* env, xmlrpc_value* value) {
|
xmlrpc_to_object(xmlrpc_env* env, xmlrpc_value* value) {
|
||||||
switch (xmlrpc_value_type(value)) {
|
switch (xmlrpc_value_type(value)) {
|
||||||
@@ -62,6 +75,14 @@ xmlrpc_to_object(xmlrpc_env* env, xmlrpc_value* value) {
|
|||||||
|
|
||||||
return torrent::Object((int64_t)v);
|
return torrent::Object((int64_t)v);
|
||||||
|
|
||||||
|
#ifdef XMLRPC_HAVE_I8
|
||||||
|
case XMLRPC_TYPE_I8:
|
||||||
|
long long v2;
|
||||||
|
xmlrpc_read_i8(env, value, &v2);
|
||||||
|
|
||||||
|
return torrent::Object((int64_t)v2);
|
||||||
|
#endif
|
||||||
|
|
||||||
// case XMLRPC_TYPE_BOOL:
|
// case XMLRPC_TYPE_BOOL:
|
||||||
// case XMLRPC_TYPE_DOUBLE:
|
// case XMLRPC_TYPE_DOUBLE:
|
||||||
// case XMLRPC_TYPE_DATETIME:
|
// case XMLRPC_TYPE_DATETIME:
|
||||||
@@ -119,7 +140,7 @@ xmlrpc_to_object(xmlrpc_env* env, xmlrpc_value* value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
core::Download*
|
core::Download*
|
||||||
XmlRpc::xmlrpc_to_download(xmlrpc_env* env, xmlrpc_value* value) {
|
xmlrpc_to_download(xmlrpc_env* env, xmlrpc_value* value) {
|
||||||
core::Download* download = NULL;
|
core::Download* download = NULL;
|
||||||
|
|
||||||
switch (xmlrpc_value_type(value)) {
|
switch (xmlrpc_value_type(value)) {
|
||||||
@@ -131,7 +152,7 @@ XmlRpc::xmlrpc_to_download(xmlrpc_env* env, xmlrpc_value* value) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (std::strlen(valueString) != 40 ||
|
if (std::strlen(valueString) != 40 ||
|
||||||
(download = m_slotFindDownload(valueString)) == NULL)
|
(download = XmlRpc::get_slot_find_download()(valueString)) == NULL)
|
||||||
xmlrpc_env_set_fault(env, XMLRPC_TYPE_ERROR, "Could not find info-hash.");
|
xmlrpc_env_set_fault(env, XMLRPC_TYPE_ERROR, "Could not find info-hash.");
|
||||||
|
|
||||||
// Urgh, seriously?
|
// Urgh, seriously?
|
||||||
@@ -147,7 +168,7 @@ XmlRpc::xmlrpc_to_download(xmlrpc_env* env, xmlrpc_value* value) {
|
|||||||
// This should really be cleaned up and support for an array of
|
// This should really be cleaned up and support for an array of
|
||||||
// downloads should be added.
|
// downloads should be added.
|
||||||
torrent::Object
|
torrent::Object
|
||||||
XmlRpc::xmlrpc_to_object_d(xmlrpc_env* env, xmlrpc_value* value, core::Download** download) {
|
xmlrpc_to_object_d(xmlrpc_env* env, xmlrpc_value* value, core::Download** download) {
|
||||||
switch (xmlrpc_value_type(value)) {
|
switch (xmlrpc_value_type(value)) {
|
||||||
case XMLRPC_TYPE_STRING:
|
case XMLRPC_TYPE_STRING:
|
||||||
*download = xmlrpc_to_download(env, value);
|
*download = xmlrpc_to_download(env, value);
|
||||||
@@ -223,19 +244,21 @@ XmlRpc::xmlrpc_to_object_d(xmlrpc_env* env, xmlrpc_value* value, core::Download*
|
|||||||
|
|
||||||
xmlrpc_value*
|
xmlrpc_value*
|
||||||
object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) {
|
object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) {
|
||||||
xmlrpc_value* result;
|
|
||||||
xmlrpc_int32 tmpInt;
|
|
||||||
|
|
||||||
switch (object.type()) {
|
switch (object.type()) {
|
||||||
case torrent::Object::TYPE_VALUE:
|
case torrent::Object::TYPE_VALUE:
|
||||||
tmpInt = object.as_value();
|
|
||||||
return xmlrpc_build_value(env, "i", tmpInt);
|
#ifdef XMLRPC_HAVE_I8
|
||||||
|
if (XmlRpc::dialect() != XmlRpc::dialect_generic)
|
||||||
|
return xmlrpc_i8_new(env, object.as_value());
|
||||||
|
#else
|
||||||
|
return xmlrpc_int_new(env, object.as_value());
|
||||||
|
#endif
|
||||||
|
|
||||||
case torrent::Object::TYPE_STRING:
|
case torrent::Object::TYPE_STRING:
|
||||||
return xmlrpc_string_new(env, object.as_string().c_str());
|
return xmlrpc_string_new(env, object.as_string().c_str());
|
||||||
|
|
||||||
case torrent::Object::TYPE_LIST:
|
case torrent::Object::TYPE_LIST:
|
||||||
result = xmlrpc_array_new(env);
|
xmlrpc_value* result = xmlrpc_array_new(env);
|
||||||
|
|
||||||
for (torrent::Object::list_type::const_iterator itr = object.as_list().begin(), last = object.as_list().end(); itr != last; itr++)
|
for (torrent::Object::list_type::const_iterator itr = object.as_list().begin(), last = object.as_list().end(); itr != last; itr++)
|
||||||
xmlrpc_array_append_item(env, result, object_to_xmlrpc(env, *itr));
|
xmlrpc_array_append_item(env, result, object_to_xmlrpc(env, *itr));
|
||||||
@@ -243,13 +266,12 @@ object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) {
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
tmpInt = 0;
|
return xmlrpc_int_new(env, 0);
|
||||||
return xmlrpc_build_value(env, "i", tmpInt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlrpc_value*
|
xmlrpc_value*
|
||||||
XmlRpc::call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
|
xmlrpc_call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
|
||||||
torrent::Object object = xmlrpc_to_object(env, args);
|
torrent::Object object = xmlrpc_to_object(env, args);
|
||||||
|
|
||||||
if (env->fault_occurred)
|
if (env->fault_occurred)
|
||||||
@@ -265,7 +287,7 @@ XmlRpc::call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
xmlrpc_value*
|
xmlrpc_value*
|
||||||
XmlRpc::call_command_d(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
|
xmlrpc_call_command_d(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
|
||||||
core::Download* download = NULL;
|
core::Download* download = NULL;
|
||||||
torrent::Object object = xmlrpc_to_object_d(env, args, &download);
|
torrent::Object object = xmlrpc_to_object_d(env, args, &download);
|
||||||
|
|
||||||
@@ -281,15 +303,23 @@ XmlRpc::call_command_d(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlRpc::XmlRpc() : m_env(new xmlrpc_env) {
|
XmlRpc::XmlRpc() :
|
||||||
xmlrpc_env_init(m_env);
|
m_env(new xmlrpc_env) {
|
||||||
m_registry = xmlrpc_registry_new(m_env);
|
|
||||||
|
// #ifdef XMLRPC_HAVE_I8
|
||||||
|
// m_dialect(dialect_i8) {
|
||||||
|
// #else
|
||||||
|
// m_dialect(dialect_generic) {
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
xmlrpc_env_init((xmlrpc_env*)m_env);
|
||||||
|
m_registry = xmlrpc_registry_new((xmlrpc_env*)m_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlRpc::~XmlRpc() {
|
XmlRpc::~XmlRpc() {
|
||||||
xmlrpc_registry_free(m_registry);
|
xmlrpc_registry_free((xmlrpc_registry*)m_registry);
|
||||||
xmlrpc_env_clean(m_env);
|
xmlrpc_env_clean((xmlrpc_env*)m_env);
|
||||||
delete m_env;
|
delete (xmlrpc_env*)m_env;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -297,7 +327,7 @@ XmlRpc::process(const char* inBuffer, uint32_t length, slot_write slotWrite) {
|
|||||||
xmlrpc_env localEnv;
|
xmlrpc_env localEnv;
|
||||||
xmlrpc_env_init(&localEnv);
|
xmlrpc_env_init(&localEnv);
|
||||||
|
|
||||||
xmlrpc_mem_block* memblock = xmlrpc_registry_process_call(&localEnv, m_registry, NULL, inBuffer, length);
|
xmlrpc_mem_block* memblock = xmlrpc_registry_process_call(&localEnv, (xmlrpc_registry*)m_registry, NULL, inBuffer, length);
|
||||||
|
|
||||||
bool result = slotWrite((const char*)xmlrpc_mem_block_contents(memblock),
|
bool result = slotWrite((const char*)xmlrpc_mem_block_contents(memblock),
|
||||||
xmlrpc_mem_block_size(memblock));
|
xmlrpc_mem_block_size(memblock));
|
||||||
@@ -312,8 +342,8 @@ XmlRpc::insert_command(const char* name, const char* parm, const char* doc, bool
|
|||||||
xmlrpc_env localEnv;
|
xmlrpc_env localEnv;
|
||||||
xmlrpc_env_init(&localEnv);
|
xmlrpc_env_init(&localEnv);
|
||||||
|
|
||||||
xmlrpc_registry_add_method_w_doc(&localEnv, m_registry, NULL, name,
|
xmlrpc_registry_add_method_w_doc(&localEnv, (xmlrpc_registry*)m_registry, NULL, name,
|
||||||
onDownload ? &XmlRpc::call_command_d : &XmlRpc::call_command,
|
onDownload ? &xmlrpc_call_command_d : &xmlrpc_call_command,
|
||||||
const_cast<char*>(name), parm, doc);
|
const_cast<char*>(name), parm, doc);
|
||||||
|
|
||||||
if (localEnv.fault_occurred)
|
if (localEnv.fault_occurred)
|
||||||
@@ -322,9 +352,40 @@ XmlRpc::insert_command(const char* name, const char* parm, const char* doc, bool
|
|||||||
xmlrpc_env_clean(&localEnv);
|
xmlrpc_env_clean(&localEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XmlRpc::set_dialect(int dialect) {
|
||||||
|
xmlrpc_env localEnv;
|
||||||
|
xmlrpc_env_init(&localEnv);
|
||||||
|
|
||||||
|
switch (dialect) {
|
||||||
|
case dialect_generic:
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef XMLRPC_HAVE_I8
|
||||||
|
case dialect_i8:
|
||||||
|
xmlrpc_registry_set_dialect(&localEnv, (xmlrpc_registry*)m_registry, xmlrpc_dialect_i8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case dialect_apache:
|
||||||
|
xmlrpc_registry_set_dialect(&localEnv, (xmlrpc_registry*)m_registry, xmlrpc_dialect_apache);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
xmlrpc_env_clean(&localEnv);
|
||||||
|
throw torrent::input_error("Unsupported XMLRPC dialect selected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localEnv.fault_occurred)
|
||||||
|
throw torrent::input_error("Unsupported XMLRPC dialect selected.");
|
||||||
|
|
||||||
|
xmlrpc_env_clean(&localEnv);
|
||||||
|
m_dialect = dialect;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
XmlRpc::XmlRpc() { throw torrent::resource_error("XMLRPC not supported."); }
|
XmlRpc::XmlRpc() : m_dialect(dialect_generic) { throw torrent::resource_error("XMLRPC not supported."); }
|
||||||
XmlRpc::~XmlRpc() {}
|
XmlRpc::~XmlRpc() {}
|
||||||
|
|
||||||
void XmlRpc::insert_command(const char* name, const char* parm, const char* doc, bool onDownload) {}
|
void XmlRpc::insert_command(const char* name, const char* parm, const char* doc, bool onDownload) {}
|
||||||
|
|||||||
+15
-11
@@ -39,10 +39,6 @@
|
|||||||
|
|
||||||
#include <rak/functional_fun.h>
|
#include <rak/functional_fun.h>
|
||||||
|
|
||||||
typedef struct _xmlrpc_env xmlrpc_env;
|
|
||||||
typedef struct _xmlrpc_value xmlrpc_value;
|
|
||||||
typedef struct _xmlrpc_registry xmlrpc_registry;
|
|
||||||
|
|
||||||
namespace core {
|
namespace core {
|
||||||
class Download;
|
class Download;
|
||||||
}
|
}
|
||||||
@@ -58,6 +54,10 @@ public:
|
|||||||
typedef rak::function1<core::Download*, const char*> slot_find_download;
|
typedef rak::function1<core::Download*, const char*> slot_find_download;
|
||||||
typedef rak::function2<bool, const char*, uint32_t> slot_write;
|
typedef rak::function2<bool, const char*, uint32_t> slot_write;
|
||||||
|
|
||||||
|
static const int dialect_generic = 0;
|
||||||
|
static const int dialect_i8 = 1;
|
||||||
|
static const int dialect_apache = 2;
|
||||||
|
|
||||||
XmlRpc();
|
XmlRpc();
|
||||||
~XmlRpc();
|
~XmlRpc();
|
||||||
|
|
||||||
@@ -65,17 +65,21 @@ public:
|
|||||||
|
|
||||||
void insert_command(const char* name, const char* parm, const char* doc, bool onDownload);
|
void insert_command(const char* name, const char* parm, const char* doc, bool onDownload);
|
||||||
|
|
||||||
|
static int dialect() { return m_dialect; }
|
||||||
|
void set_dialect(int dialect);
|
||||||
|
|
||||||
|
static slot_find_download& get_slot_find_download() { return m_slotFindDownload; }
|
||||||
static void set_slot_find_download(slot_find_download::base_type* slot) { m_slotFindDownload.set(slot); }
|
static void set_slot_find_download(slot_find_download::base_type* slot) { m_slotFindDownload.set(slot); }
|
||||||
|
|
||||||
static xmlrpc_value* call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo);
|
|
||||||
static xmlrpc_value* call_command_d(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static core::Download* xmlrpc_to_download(xmlrpc_env* env, xmlrpc_value* value);
|
// xmlrpc_env* m_env;
|
||||||
static torrent::Object xmlrpc_to_object_d(xmlrpc_env* env, xmlrpc_value* value, core::Download** download);
|
// xmlrpc_registry* m_registry;
|
||||||
|
|
||||||
xmlrpc_env* m_env;
|
void* m_env;
|
||||||
xmlrpc_registry* m_registry;
|
void* m_registry;
|
||||||
|
|
||||||
|
// Meh.
|
||||||
|
static int m_dialect;
|
||||||
|
|
||||||
static slot_find_download m_slotFindDownload;
|
static slot_find_download m_slotFindDownload;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user