mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-20 08:06:18 +00:00
Compare commits
11 Commits
8378c0a83a
...
v0.16.21
| Author | SHA1 | Date | |
|---|---|---|---|
| 109a20c09c | |||
| ac1b2685d5 | |||
| d7b2cfe4f2 | |||
| dcfbf82a38 | |||
| 3ae91b6536 | |||
| af6d8a10ad | |||
| 9066afc063 | |||
| a2fabb10de | |||
| 13e073d9ff | |||
| d73f245692 | |||
| 7db356cae4 |
+3
-3
@@ -1,6 +1,6 @@
|
||||
m4_pattern_allow([PKG_CHECK_EXISTS])
|
||||
|
||||
AC_INIT([rtorrent],[0.16.20],[sundell.software@gmail.com])
|
||||
AC_INIT([rtorrent],[0.16.21],[sundell.software@gmail.com])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIRS([scripts])
|
||||
@@ -14,7 +14,7 @@ AX_CXX_COMPILE_STDCXX(20, noext, mandatory)
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
AC_DEFINE([API_VERSION], [25], [api version])
|
||||
AC_DEFINE([API_VERSION], [26], [api version])
|
||||
|
||||
RAK_CHECK_CFLAGS
|
||||
RAK_CHECK_CXXFLAGS
|
||||
@@ -49,7 +49,7 @@ fi
|
||||
|
||||
PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"])
|
||||
PKG_CHECK_MODULES([ZLIB], [zlib])
|
||||
PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.16.20])
|
||||
PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.16.21])
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
TORRENT_WITH_XMLRPC_C
|
||||
|
||||
+15
-3
@@ -3,6 +3,7 @@
|
||||
#include <cerrno>
|
||||
#include <fcntl.h>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
@@ -185,6 +186,14 @@ cmd_file_append(const torrent::Object::list_type& args) {
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
checked_socket_value(int64_t value, const char* label) {
|
||||
if (value < 0 || value > std::numeric_limits<uint32_t>::max())
|
||||
throw torrent::input_error(std::string("Invalid ") + label + " value.");
|
||||
|
||||
return static_cast<uint32_t>(value);
|
||||
}
|
||||
|
||||
void
|
||||
initialize_command_local() {
|
||||
core::DownloadList* dList = control->core()->download_list();
|
||||
@@ -241,7 +250,7 @@ initialize_command_local() {
|
||||
|
||||
CMD_ANY ("system.sockets.size", [](auto, auto) { return torrent::runtime::socket_manager()->size(); });
|
||||
CMD_ANY ("system.sockets.max_size", [](auto, auto) { return torrent::runtime::socket_manager()->max_size(); });
|
||||
CMD_ANY_VALUE_V ("system.sockets.max_size.set", [](auto, auto& value) { return torrent::runtime::socket_manager()->set_max_size_and_adjust(value); });
|
||||
CMD_ANY_VALUE_V ("system.sockets.max_size.set", [](auto, auto& value) { return torrent::runtime::socket_manager()->set_max_size_and_adjust(checked_socket_value(value, "socket max size")); });
|
||||
CMD_ANY_V ("system.sockets.adjust_alloc", [](auto, auto) { torrent::runtime::socket_manager()->adjust_allocation(); });
|
||||
CMD_ANY ("system.sockets.reserved_alloc", [](auto, auto) { return torrent::runtime::socket_manager()->reserved_allocation(); });
|
||||
CMD_ANY ("system.sockets.available_alloc", [](auto, auto) { return torrent::runtime::socket_manager()->available_allocation(); });
|
||||
@@ -262,8 +271,8 @@ initialize_command_local() {
|
||||
CMD_ANY (category_name + ".min_alloc.limit", [category](auto, auto) { return torrent::runtime::socket_manager()->category_alloc_minimum(category); });
|
||||
CMD_ANY (category_name + ".min_alloc", [category](auto, auto) { return torrent::runtime::socket_manager()->category_min_allocation(category); });
|
||||
CMD_ANY (category_name + ".max_alloc", [category](auto, auto) { return torrent::runtime::socket_manager()->category_max_allocation(category); });
|
||||
CMD_ANY_VALUE_V(category_name + ".min_alloc.set", [category](auto, auto& value) { torrent::runtime::socket_manager()->set_category_min_allocation(category, value); });
|
||||
CMD_ANY_VALUE_V(category_name + ".max_alloc.set", [category](auto, auto& value) { torrent::runtime::socket_manager()->set_category_max_allocation(category, value); });
|
||||
CMD_ANY_VALUE_V(category_name + ".min_alloc.set", [category](auto, auto& value) { torrent::runtime::socket_manager()->set_category_min_allocation(category, checked_socket_value(value, "socket min alloc")); });
|
||||
CMD_ANY_VALUE_V(category_name + ".max_alloc.set", [category](auto, auto& value) { torrent::runtime::socket_manager()->set_category_max_allocation(category, checked_socket_value(value, "socket max alloc")); });
|
||||
}
|
||||
|
||||
CMD_ANY ("pieces.sync.always_safe", [](auto, auto) { return torrent::runtime::memory_manager()->safe_sync(); });
|
||||
@@ -352,6 +361,9 @@ initialize_command_local() {
|
||||
rpc::rpc.mark_safe("system.api_version");
|
||||
rpc::rpc.mark_safe("system.client_version");
|
||||
rpc::rpc.mark_safe("system.library_version");
|
||||
rpc::rpc.mark_safe("system.time");
|
||||
rpc::rpc.mark_safe("system.time_seconds");
|
||||
rpc::rpc.mark_safe("system.time_usec");
|
||||
rpc::rpc.mark_safe("system.file.max_size");
|
||||
rpc::rpc.mark_safe("system.file.split_size");
|
||||
rpc::rpc.mark_safe("system.file.split_suffix");
|
||||
|
||||
+11
-3
@@ -3,6 +3,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <limits>
|
||||
#include <regex>
|
||||
#include <torrent/utils/log.h>
|
||||
|
||||
@@ -407,8 +408,9 @@ apply_to_time(const torrent::Object& rawArgs, int flags) {
|
||||
torrent::Object
|
||||
apply_to_elapsed_time(const torrent::Object& rawArgs) {
|
||||
auto cached_seconds = torrent::this_thread::cached_seconds().count();
|
||||
auto value = rawArgs.as_value();
|
||||
|
||||
uint64_t arg = cached_seconds - rawArgs.as_value();
|
||||
uint64_t arg = value >= 0 && value <= cached_seconds ? cached_seconds - value : 0;
|
||||
|
||||
char buffer[48];
|
||||
snprintf(buffer, 48, "%2d:%02d:%02d", (int)(arg / 3600), (int)((arg / 60) % 60), (int)(arg % 60));
|
||||
@@ -674,8 +676,13 @@ apply_math_basic(const char* name, Comp op, const torrent::Object::list_type& ar
|
||||
throw torrent::input_error(std::string(name) + ": Wrong argument type");
|
||||
}
|
||||
|
||||
if (divides && !rhs && itr != args.begin())
|
||||
throw torrent::input_error(std::string(name) + ": Division by zero!");
|
||||
if (divides && itr != args.begin()) {
|
||||
if (rhs == 0)
|
||||
throw torrent::input_error(std::string(name) + ": Division by zero!");
|
||||
|
||||
if (val == std::numeric_limits<int64_t>::min() && rhs == -1)
|
||||
throw torrent::input_error(std::string(name) + ": Division overflow!");
|
||||
}
|
||||
|
||||
val = itr == args.begin() ? rhs : op(val, rhs);
|
||||
|
||||
@@ -916,6 +923,7 @@ initialize_command_ui() {
|
||||
|
||||
rpc::rpc.mark_safe("view.set_visible");
|
||||
rpc::rpc.mark_safe("view.set_not_visible");
|
||||
rpc::rpc.mark_safe("view.list");
|
||||
|
||||
rpc::rpc.mark_safe("cat");
|
||||
rpc::rpc.mark_safe("if");
|
||||
|
||||
+9
-1
@@ -1,5 +1,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "core/download.h"
|
||||
#include "parse.h"
|
||||
|
||||
@@ -41,7 +43,13 @@ command_base_call_value_base(command_base* command_raw, target_type target, cons
|
||||
return command_base::_call<typename command_value_function<T>::type, T>(command_raw, target, val);
|
||||
}
|
||||
|
||||
return command_base::_call<typename command_value_function<T>::type, T>(command_raw, target, unit * arg.as_value());
|
||||
auto value = arg.as_value();
|
||||
|
||||
if (value > std::numeric_limits<int64_t>::max() / unit ||
|
||||
value < std::numeric_limits<int64_t>::min() / unit)
|
||||
throw torrent::input_error("Value out of range.");
|
||||
|
||||
return command_base::_call<typename command_value_function<T>::type, T>(command_raw, target, unit * value);
|
||||
}
|
||||
|
||||
template <typename T> const torrent::Object
|
||||
|
||||
+12
-4
@@ -26,10 +26,12 @@ constexpr int JSONRPC_METHOD_NOT_FOUND_ERROR = -32601;
|
||||
constexpr int JSONRPC_INVALID_PARAMS_ERROR = -32602;
|
||||
constexpr int JSONRPC_INTERNAL_ERROR = -32000;
|
||||
|
||||
constexpr uint32_t max_json_depth = 1024;
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
torrent::Object
|
||||
json_to_object(const json& value) {
|
||||
json_to_object(const json& value, uint32_t depth = 0) {
|
||||
switch (value.type()) {
|
||||
case json::value_t::number_unsigned:
|
||||
case json::value_t::number_integer:
|
||||
@@ -42,20 +44,26 @@ json_to_object(const json& value) {
|
||||
return torrent::Object(value.get<std::string>());
|
||||
|
||||
case json::value_t::array: {
|
||||
if (++depth >= max_json_depth)
|
||||
throw torrent::input_error("invalid parameters: max depth reached");
|
||||
|
||||
auto array_raw = torrent::Object::create_list();
|
||||
auto& array = array_raw.as_list();
|
||||
|
||||
for (const auto& entry : value)
|
||||
array.push_back(json_to_object(entry));
|
||||
array.push_back(json_to_object(entry, depth));
|
||||
|
||||
return array_raw;
|
||||
}
|
||||
case json::value_t::object: {
|
||||
if (++depth >= max_json_depth)
|
||||
throw torrent::input_error("invalid parameters: max depth reached");
|
||||
|
||||
auto map_raw = torrent::Object::create_map();
|
||||
auto& map = map_raw.as_map();
|
||||
|
||||
for (const auto& entry : value.items())
|
||||
map[entry.key()] = json_to_object(entry.value());
|
||||
map[entry.key()] = json_to_object(entry.value(), depth);
|
||||
|
||||
return map_raw;
|
||||
}
|
||||
@@ -138,7 +146,7 @@ jsonrpc_call_command(const std::string& method, const json& params) {
|
||||
|
||||
CommandMap::iterator itr = commands.find(method.c_str());
|
||||
|
||||
if (itr == commands.end()) {
|
||||
if (itr == commands.end() || !(itr->second.m_flags & CommandMap::flag_public_rpc)) {
|
||||
throw rpc_error(JSONRPC_METHOD_NOT_FOUND_ERROR, "method not found: " + method);
|
||||
}
|
||||
|
||||
|
||||
+37
-19
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
#include <locale>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
@@ -10,6 +11,8 @@
|
||||
|
||||
namespace rpc {
|
||||
|
||||
constexpr uint32_t max_parse_depth = 1024;
|
||||
|
||||
const char*
|
||||
parse_skip_wspace(const char* first, const char* last) {
|
||||
while (first != last && parse_is_space(*first))
|
||||
@@ -99,6 +102,12 @@ parse_whole_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
value_fits_shifted(int64_t value, int shift) {
|
||||
return value <= (std::numeric_limits<int64_t>::max() >> shift) &&
|
||||
value >= (std::numeric_limits<int64_t>::min() >> shift);
|
||||
}
|
||||
|
||||
const char*
|
||||
parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
||||
if (unit <= 0)
|
||||
@@ -121,20 +130,26 @@ parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
||||
case 'B': ++last; break;
|
||||
case 'k':
|
||||
case 'K':
|
||||
if (*value > (int64_t)0x1FFFFFFFFFFFFF) return src; // overflow guard
|
||||
if (!value_fits_shifted(*value, 10)) return src; // overflow guard
|
||||
*value = *value << 10; ++last; break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
if (*value > (int64_t)0x7FFFFFFFFFF) return src; // overflow guard
|
||||
if (!value_fits_shifted(*value, 20)) return src; // overflow guard
|
||||
*value = *value << 20; ++last; break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
if (*value > (int64_t)0x1FFFFFFFF) return src; // overflow guard
|
||||
if (!value_fits_shifted(*value, 30)) return src; // overflow guard
|
||||
*value = *value << 30; ++last; break;
|
||||
// case ' ':
|
||||
// case '\0': *value = *value * unit; break;
|
||||
// default: throw torrent::input_error("Could not parse value.");
|
||||
default: *value = *value * unit; break;
|
||||
default:
|
||||
if (*value > std::numeric_limits<int64_t>::max() / unit ||
|
||||
*value < std::numeric_limits<int64_t>::min() / unit)
|
||||
return src; // overflow guard
|
||||
|
||||
*value = *value * unit;
|
||||
break;
|
||||
}
|
||||
|
||||
return last;
|
||||
@@ -142,10 +157,13 @@ parse_value_nothrow(const char* src, int64_t* value, int base, int unit) {
|
||||
|
||||
// Somewhat ugly...
|
||||
const char*
|
||||
parse_object(const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char)) {
|
||||
parse_object(const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char), uint32_t depth) {
|
||||
if (++depth >= max_parse_depth)
|
||||
throw torrent::input_error("Max parse depth reached.");
|
||||
|
||||
if (*first == '{') {
|
||||
*dest = torrent::Object::create_list();
|
||||
first = parse_list(first + 1, last, dest, &parse_is_delim_block);
|
||||
first = parse_list(first + 1, last, dest, &parse_is_delim_block, depth);
|
||||
first = parse_skip_wspace(first, last);
|
||||
|
||||
if (first == last || *first != '}')
|
||||
@@ -154,18 +172,18 @@ parse_object(const char* first, const char* last, torrent::Object* dest, bool (*
|
||||
return ++first;
|
||||
|
||||
} else if (*first == '(') {
|
||||
int32_t depth = 1;
|
||||
int32_t parentheses = 1;
|
||||
|
||||
while (first + 1 != last && *(first + 1) == '(') {
|
||||
first++;
|
||||
depth++;
|
||||
parentheses++;
|
||||
}
|
||||
|
||||
if (depth > 3)
|
||||
if (parentheses > 3)
|
||||
throw torrent::input_error("Max 3 parentheses per object allowed.");
|
||||
|
||||
*dest = torrent::Object::create_dict_key();
|
||||
dest->set_flags(torrent::Object::flag_function << (depth - 1));
|
||||
dest->set_flags(torrent::Object::flag_function << (parentheses - 1));
|
||||
|
||||
first = parse_string(first + 1, last, &dest->as_dict_key(), &parse_is_delim_func);
|
||||
first = parse_skip_wspace(first, last);
|
||||
@@ -176,16 +194,16 @@ parse_object(const char* first, const char* last, torrent::Object* dest, bool (*
|
||||
if (*first == ',') {
|
||||
// This will always create a list even for single argument functions...
|
||||
dest->as_dict_obj() = torrent::Object::create_list();
|
||||
first = parse_list(first + 1, last, &dest->as_dict_obj(), &parse_is_delim_func);
|
||||
first = parse_list(first + 1, last, &dest->as_dict_obj(), &parse_is_delim_func, depth);
|
||||
first = parse_skip_wspace(first, last);
|
||||
}
|
||||
|
||||
while (depth != 0 && first != last && *first == ')') {
|
||||
while (parentheses != 0 && first != last && *first == ')') {
|
||||
first++;
|
||||
depth--;
|
||||
parentheses--;
|
||||
}
|
||||
|
||||
if (depth != 0)
|
||||
if (parentheses != 0)
|
||||
throw torrent::input_error("Parentheses mismatch.");
|
||||
|
||||
return first;
|
||||
@@ -198,7 +216,7 @@ parse_object(const char* first, const char* last, torrent::Object* dest, bool (*
|
||||
}
|
||||
|
||||
const char*
|
||||
parse_list(const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char)) {
|
||||
parse_list(const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char), uint32_t depth) {
|
||||
if (!dest->is_list())
|
||||
throw torrent::internal_error("parse_list(...) !dest->is_list().");
|
||||
|
||||
@@ -206,7 +224,7 @@ parse_list(const char* first, const char* last, torrent::Object* dest, bool (*de
|
||||
torrent::Object tmp;
|
||||
|
||||
first = parse_skip_wspace(first, last);
|
||||
first = parse_object(first, last, &tmp, delim);
|
||||
first = parse_object(first, last, &tmp, delim, depth);
|
||||
first = parse_skip_wspace(first, last);
|
||||
|
||||
dest->as_list().push_back(tmp);
|
||||
@@ -221,9 +239,9 @@ parse_list(const char* first, const char* last, torrent::Object* dest, bool (*de
|
||||
}
|
||||
|
||||
const char*
|
||||
parse_whole_list(const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char)) {
|
||||
parse_whole_list(const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char), uint32_t depth) {
|
||||
first = parse_skip_wspace(first, last);
|
||||
first = parse_object(first, last, dest, delim);
|
||||
first = parse_object(first, last, dest, delim, depth);
|
||||
first = parse_skip_wspace(first, last);
|
||||
|
||||
if (first != last && parse_is_seperator(*first)) {
|
||||
@@ -231,7 +249,7 @@ parse_whole_list(const char* first, const char* last, torrent::Object* dest, boo
|
||||
tmp.swap(*dest);
|
||||
|
||||
dest->as_list().push_back(tmp);
|
||||
first = parse_list(++first, last, dest, delim);
|
||||
first = parse_list(++first, last, dest, delim, depth);
|
||||
}
|
||||
|
||||
return first;
|
||||
|
||||
+3
-3
@@ -77,9 +77,9 @@ const char* parse_value_nothrow(const char* first, const char* last, int64_t* va
|
||||
void parse_whole_value(const char* src, int64_t* value, int base = 0, int unit = 1);
|
||||
bool parse_whole_value_nothrow(const char* src, int64_t* value, int base = 0, int unit = 1);
|
||||
|
||||
const char* parse_object (const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char) = &parse_is_delim_default);
|
||||
const char* parse_list (const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char) = &parse_is_delim_default);
|
||||
const char* parse_whole_list(const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char) = &parse_is_delim_default);
|
||||
const char* parse_object (const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char) = &parse_is_delim_default, uint32_t depth = 0);
|
||||
const char* parse_list (const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char) = &parse_is_delim_default, uint32_t depth = 0);
|
||||
const char* parse_whole_list(const char* first, const char* last, torrent::Object* dest, bool (*delim)(const char) = &parse_is_delim_default, uint32_t depth = 0);
|
||||
|
||||
std::string convert_to_string(const torrent::Object& src);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <torrent/runtime/socket_manager.h>
|
||||
#include <torrent/system/callbacks.h>
|
||||
#include <torrent/system/poll.h>
|
||||
#include <torrent/system/scheduler.h>
|
||||
#include <torrent/utils/log.h>
|
||||
|
||||
#include "control.h"
|
||||
@@ -27,6 +28,8 @@ namespace rpc {
|
||||
SCgiTask::SCgiTask()
|
||||
: m_callback_id(torrent::system::make_callback_id()) {
|
||||
|
||||
m_task_timeout.slot() = [this]() { close(); };
|
||||
|
||||
reset_file_descriptor();
|
||||
}
|
||||
|
||||
@@ -50,6 +53,8 @@ SCgiTask::open(SCgi* parent, int fd) {
|
||||
torrent::this_thread::poll()->open(this);
|
||||
torrent::this_thread::poll()->insert_read(this);
|
||||
|
||||
torrent::this_thread::scheduler()->update_wait_for_ceil_seconds(&m_task_timeout, timeout_request);
|
||||
|
||||
auto lock = std::lock_guard<std::mutex>(m_result_mutex);
|
||||
|
||||
// Leave room for terminating nul byte for parsing the header.
|
||||
@@ -61,6 +66,8 @@ SCgiTask::cancel_open() {
|
||||
if (!is_open())
|
||||
return;
|
||||
|
||||
torrent::this_thread::scheduler()->erase(&m_task_timeout);
|
||||
|
||||
torrent::this_thread::poll()->remove_and_close(this);
|
||||
|
||||
torrent::fd_close(file_descriptor());
|
||||
@@ -72,6 +79,8 @@ SCgiTask::close() {
|
||||
if (!is_open())
|
||||
return;
|
||||
|
||||
torrent::this_thread::scheduler()->erase(&m_task_timeout);
|
||||
|
||||
torrent::system::cancel_callback_and_wait(m_callback_id, scgi_thread::thread(), torrent::main_thread::thread());
|
||||
|
||||
torrent::runtime::socket_manager()->close_event_or_throw(this, [this]() {
|
||||
@@ -158,6 +167,8 @@ SCgiTask::event_read() {
|
||||
|
||||
torrent::this_thread::poll()->remove_read(this);
|
||||
|
||||
torrent::this_thread::scheduler()->update_wait_for_ceil_seconds(&m_task_timeout, timeout_request);
|
||||
|
||||
if (m_parent->log_fd() >= 0) {
|
||||
[[maybe_unused]] int result;
|
||||
|
||||
|
||||
+7
-2
@@ -1,10 +1,12 @@
|
||||
#ifndef RTORRENT_RPC_SCGI_TASK_H
|
||||
#define RTORRENT_RPC_SCGI_TASK_H
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <torrent/system/event.h>
|
||||
#include <torrent/system/scheduler.h>
|
||||
|
||||
namespace rpc {
|
||||
|
||||
@@ -16,6 +18,8 @@ public:
|
||||
static constexpr int max_header_size = 2000;
|
||||
static constexpr int max_content_size = (2 << 23);
|
||||
|
||||
static constexpr auto timeout_request = std::chrono::seconds(60);
|
||||
|
||||
enum ContentType { XML, JSON };
|
||||
|
||||
SCgiTask();
|
||||
@@ -54,8 +58,9 @@ private:
|
||||
void plaintext_response(const char* buffer, uint32_t content_length);
|
||||
void gzip_response(const char* buffer, uint32_t content_length);
|
||||
|
||||
SCgi* m_parent{};
|
||||
torrent::system::callback_id m_callback_id;
|
||||
SCgi* m_parent{};
|
||||
torrent::system::callback_id m_callback_id;
|
||||
torrent::system::SchedulerEntry m_task_timeout;
|
||||
|
||||
std::mutex m_result_mutex;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user