diff options
Diffstat (limited to 'src/command')
-rw-r--r-- | src/command/AllCommands.cxx | 1 | ||||
-rw-r--r-- | src/command/ClientCommands.cxx | 15 | ||||
-rw-r--r-- | src/command/ClientCommands.hxx | 3 | ||||
-rw-r--r-- | src/command/FileCommands.cxx | 33 |
4 files changed, 36 insertions, 16 deletions
diff --git a/src/command/AllCommands.cxx b/src/command/AllCommands.cxx index 96ae21e42..4508fa92f 100644 --- a/src/command/AllCommands.cxx +++ b/src/command/AllCommands.cxx @@ -87,6 +87,7 @@ static constexpr struct command commands[] = { { "addid", PERMISSION_ADD, 1, 2, handle_addid }, { "addtagid", PERMISSION_ADD, 3, 3, handle_addtagid }, { "albumart", PERMISSION_READ, 2, 2, handle_album_art }, + { "binarylimit", PERMISSION_NONE, 1, 1, handle_binary_limit }, { "channels", PERMISSION_READ, 0, 0, handle_channels }, { "clear", PERMISSION_CONTROL, 0, 0, handle_clear }, { "clearerror", PERMISSION_CONTROL, 0, 0, handle_clearerror }, diff --git a/src/command/ClientCommands.cxx b/src/command/ClientCommands.cxx index f0e3470be..01bd462f2 100644 --- a/src/command/ClientCommands.cxx +++ b/src/command/ClientCommands.cxx @@ -41,6 +41,21 @@ handle_ping([[maybe_unused]] Client &client, [[maybe_unused]] Request args, } CommandResult +handle_binary_limit(Client &client, Request args, + [[maybe_unused]] Response &r) +{ + size_t value = args.ParseUnsigned(0, client.GetOutputMaxSize() - 4096); + if (value < 64) { + r.Error(ACK_ERROR_ARG, "Value too small"); + return CommandResult::ERROR; + } + + client.binary_limit = value; + + return CommandResult::OK; +} + +CommandResult handle_password(Client &client, Request args, Response &r) { unsigned permission = 0; diff --git a/src/command/ClientCommands.hxx b/src/command/ClientCommands.hxx index fc0dc42e1..de766e802 100644 --- a/src/command/ClientCommands.hxx +++ b/src/command/ClientCommands.hxx @@ -33,6 +33,9 @@ CommandResult handle_ping(Client &client, Request request, Response &response); CommandResult +handle_binary_limit(Client &client, Request request, Response &response); + +CommandResult handle_password(Client &client, Request request, Response &response); CommandResult diff --git a/src/command/FileCommands.cxx b/src/command/FileCommands.cxx index 4ac239646..7efbb211c 100644 --- a/src/command/FileCommands.cxx +++ b/src/command/FileCommands.cxx @@ -43,6 +43,7 @@ #include "thread/Mutex.hxx" #include "Log.hxx" +#include <algorithm> #include <cassert> #include <cinttypes> /* for PRIu64 */ @@ -205,28 +206,26 @@ read_stream_art(Response &r, const char *uri, size_t offset) const offset_type art_file_size = is->GetSize(); - if (offset >= art_file_size) { - if (offset > art_file_size) { - r.Error(ACK_ERROR_ARG, "Offset too large"); - return CommandResult::ERROR; - } else { - r.Format("size: %" PRIoffset "\n", art_file_size); - r.WriteBinary(nullptr); - return CommandResult::OK; - } + if (offset > art_file_size) { + r.Error(ACK_ERROR_ARG, "Offset too large"); + return CommandResult::ERROR; } - uint8_t buffer[Response::MAX_BINARY_SIZE]; - size_t read_size; + std::size_t buffer_size = + std::min<offset_type>(art_file_size - offset, + r.GetClient().binary_limit); - { + std::unique_ptr<std::byte[]> buffer(new std::byte[buffer_size]); + + std::size_t read_size = 0; + if (buffer_size > 0) { std::unique_lock<Mutex> lock(mutex); is->Seek(lock, offset); - read_size = is->Read(lock, &buffer, sizeof(buffer)); + read_size = is->Read(lock, buffer.get(), buffer_size); } r.Format("size: %" PRIoffset "\n", art_file_size); - r.WriteBinary({buffer, read_size}); + r.WriteBinary({buffer.get(), read_size}); return CommandResult::OK; } @@ -313,8 +312,10 @@ public: response.Format("type: %s\n", mime_type); buffer.size -= offset; - if (buffer.size > Response::MAX_BINARY_SIZE) - buffer.size = Response::MAX_BINARY_SIZE; + + const std::size_t binary_limit = response.GetClient().binary_limit; + if (buffer.size > binary_limit) + buffer.size = binary_limit; buffer.data = OffsetPointer(buffer.data, offset); response.WriteBinary(buffer); |