mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-22 09:06:18 +00:00
Store copies of command names added to xmlrpc-c.
This commit is contained in:
@@ -4,10 +4,27 @@
|
|||||||
|
|
||||||
#include "parse_commands.h"
|
#include "parse_commands.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <torrent/exceptions.h>
|
#include <torrent/exceptions.h>
|
||||||
|
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<const char>> XmlRpc::m_command_names;
|
||||||
|
|
||||||
|
const char*
|
||||||
|
XmlRpc::store_command_name(const char* name) {
|
||||||
|
if (::strnlen(name, 8192) == 8192)
|
||||||
|
throw torrent::input_error("XMLRPC command name too long, limit is 8192 characters.");
|
||||||
|
|
||||||
|
for (const auto& itr : m_command_names) {
|
||||||
|
if (::strcmp(itr.get(), name) == 0)
|
||||||
|
return itr.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_command_names.push_back(std::unique_ptr<const char>(::strdup(name)));
|
||||||
|
return m_command_names.back().get();
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef HAVE_XMLRPC_C
|
#ifndef HAVE_XMLRPC_C
|
||||||
#ifndef HAVE_XMLRPC_TINYXML2
|
#ifndef HAVE_XMLRPC_TINYXML2
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -59,6 +59,10 @@ public:
|
|||||||
void set_size_limit(uint64_t size);
|
void set_size_limit(uint64_t size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static const char* store_command_name(const char* name);
|
||||||
|
|
||||||
|
static std::vector<std::unique_ptr<const char>> m_command_names;
|
||||||
|
|
||||||
slot_download m_slotFindDownload;
|
slot_download m_slotFindDownload;
|
||||||
slot_file m_slotFindFile;
|
slot_file m_slotFindFile;
|
||||||
slot_tracker m_slotFindTracker;
|
slot_tracker m_slotFindTracker;
|
||||||
@@ -73,7 +77,6 @@ private:
|
|||||||
// Only used by tinyxml2
|
// Only used by tinyxml2
|
||||||
bool m_isValid;
|
bool m_isValid;
|
||||||
uint64_t m_sizeLimit{SCgiTask::max_content_size};
|
uint64_t m_sizeLimit{SCgiTask::max_content_size};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-24
@@ -357,10 +357,12 @@ object_to_xmlrpc(xmlrpc_env* env, const torrent::Object& object) {
|
|||||||
|
|
||||||
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) {
|
||||||
CommandMap::iterator itr = commands.find((const char*)voidServerInfo);
|
auto server_info = static_cast<const char*>(voidServerInfo);
|
||||||
|
|
||||||
|
CommandMap::iterator itr = commands.find(server_info);
|
||||||
|
|
||||||
if (itr == commands.end()) {
|
if (itr == commands.end()) {
|
||||||
xmlrpc_env_set_fault(env, XMLRPC_PARSE_ERROR, ("Command \"" + std::string((const char*)voidServerInfo) + "\" does not exist.").c_str());
|
xmlrpc_env_set_fault(env, XMLRPC_PARSE_ERROR, ("Command \"" + std::string(server_info) + "\" does not exist.").c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,6 +395,11 @@ xmlrpc_call_command(xmlrpc_env* env, xmlrpc_value* args, void* voidServerInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
XmlRpc::is_valid() const {
|
||||||
|
return m_env != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
XmlRpc::initialize() {
|
XmlRpc::initialize() {
|
||||||
#ifndef XMLRPC_HAVE_I8
|
#ifndef XMLRPC_HAVE_I8
|
||||||
@@ -417,34 +424,42 @@ XmlRpc::cleanup() {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
XmlRpc::process(const char* inBuffer, uint32_t length, slot_write slotWrite) {
|
XmlRpc::process(const char* inBuffer, uint32_t length, slot_write slotWrite) {
|
||||||
xmlrpc_env localEnv;
|
xmlrpc_env local_env;
|
||||||
xmlrpc_env_init(&localEnv);
|
xmlrpc_env_init(&local_env);
|
||||||
|
|
||||||
xmlrpc_mem_block* memblock = xmlrpc_registry_process_call(&localEnv, (xmlrpc_registry*)m_registry, NULL, inBuffer, length);
|
xmlrpc_mem_block* memblock = xmlrpc_registry_process_call(&local_env, (xmlrpc_registry*)m_registry, NULL, inBuffer, length);
|
||||||
|
|
||||||
if (localEnv.fault_occurred && localEnv.fault_code == XMLRPC_INTERNAL_ERROR)
|
if (local_env.fault_occurred && local_env.fault_code == XMLRPC_INTERNAL_ERROR)
|
||||||
throw torrent::internal_error("Internal error in XMLRPC.");
|
throw torrent::internal_error("Internal error in XMLRPC.");
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
xmlrpc_mem_block_free(memblock);
|
xmlrpc_mem_block_free(memblock);
|
||||||
xmlrpc_env_clean(&localEnv);
|
xmlrpc_env_clean(&local_env);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
XmlRpc::insert_command(const char* name, const char* parm, const char* doc) {
|
XmlRpc::insert_command(const char* name, const char* parm, const char* doc) {
|
||||||
xmlrpc_env localEnv;
|
xmlrpc_env local_env;
|
||||||
xmlrpc_env_init(&localEnv);
|
xmlrpc_env_init(&local_env);
|
||||||
|
|
||||||
xmlrpc_registry_add_method_w_doc(&localEnv, (xmlrpc_registry*)m_registry, NULL, name,
|
auto stored_name = store_command_name(name);
|
||||||
&xmlrpc_call_command, const_cast<char*>(name), parm, doc);
|
|
||||||
|
|
||||||
if (localEnv.fault_occurred)
|
xmlrpc_registry_add_method_w_doc(&local_env,
|
||||||
|
(xmlrpc_registry*)m_registry,
|
||||||
|
nullptr,
|
||||||
|
stored_name,
|
||||||
|
&xmlrpc_call_command,
|
||||||
|
(void*)stored_name,
|
||||||
|
parm,
|
||||||
|
doc);
|
||||||
|
|
||||||
|
if (local_env.fault_occurred)
|
||||||
throw torrent::internal_error("Fault occured while inserting xmlrpc call.");
|
throw torrent::internal_error("Fault occured while inserting xmlrpc call.");
|
||||||
|
|
||||||
xmlrpc_env_clean(&localEnv);
|
xmlrpc_env_clean(&local_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -452,8 +467,8 @@ XmlRpc::set_dialect(int dialect) {
|
|||||||
if (!is_valid())
|
if (!is_valid())
|
||||||
throw torrent::input_error("Cannot select XMLRPC dialect before it is initialized.");
|
throw torrent::input_error("Cannot select XMLRPC dialect before it is initialized.");
|
||||||
|
|
||||||
xmlrpc_env localEnv;
|
xmlrpc_env local_env;
|
||||||
xmlrpc_env_init(&localEnv);
|
xmlrpc_env_init(&local_env);
|
||||||
|
|
||||||
switch (dialect) {
|
switch (dialect) {
|
||||||
case dialect_generic:
|
case dialect_generic:
|
||||||
@@ -461,25 +476,25 @@ XmlRpc::set_dialect(int dialect) {
|
|||||||
|
|
||||||
#ifdef XMLRPC_HAVE_I8
|
#ifdef XMLRPC_HAVE_I8
|
||||||
case dialect_i8:
|
case dialect_i8:
|
||||||
xmlrpc_registry_set_dialect(&localEnv, (xmlrpc_registry*)m_registry, xmlrpc_dialect_i8);
|
xmlrpc_registry_set_dialect(&local_env, (xmlrpc_registry*)m_registry, xmlrpc_dialect_i8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dialect_apache:
|
case dialect_apache:
|
||||||
xmlrpc_registry_set_dialect(&localEnv, (xmlrpc_registry*)m_registry, xmlrpc_dialect_apache);
|
xmlrpc_registry_set_dialect(&local_env, (xmlrpc_registry*)m_registry, xmlrpc_dialect_apache);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
xmlrpc_env_clean(&localEnv);
|
xmlrpc_env_clean(&local_env);
|
||||||
throw torrent::input_error("Unsupported XMLRPC dialect selected.");
|
throw torrent::input_error("Unsupported XMLRPC dialect selected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localEnv.fault_occurred) {
|
if (local_env.fault_occurred) {
|
||||||
xmlrpc_env_clean(&localEnv);
|
xmlrpc_env_clean(&local_env);
|
||||||
throw torrent::input_error("Unsupported XMLRPC dialect selected.");
|
throw torrent::input_error("Unsupported XMLRPC dialect selected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlrpc_env_clean(&localEnv);
|
xmlrpc_env_clean(&local_env);
|
||||||
m_dialect = dialect;
|
m_dialect = dialect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,9 +511,6 @@ XmlRpc::set_size_limit(uint64_t size) {
|
|||||||
xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, size);
|
xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
XmlRpc::is_valid() const { return m_env != NULL; }
|
|
||||||
|
|
||||||
} // namespace rpc
|
} // namespace rpc
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user