Merge tag 'v0.22.4'

release v0.22.4
This commit is contained in:
Max Kellermann
2021-01-21 17:42:26 +01:00
33 changed files with 353 additions and 101 deletions

View File

@@ -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 },

View File

@@ -40,6 +40,21 @@ handle_ping([[maybe_unused]] Client &client, [[maybe_unused]] Request args,
return CommandResult::OK;
}
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)
{

View File

@@ -32,6 +32,9 @@ handle_close(Client &client, Request request, Response &response);
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);

View File

@@ -43,6 +43,7 @@
#include "thread/Mutex.hxx"
#include "Log.hxx"
#include <algorithm>
#include <cassert>
#include <cinttypes> /* for PRIu64 */
@@ -202,17 +203,26 @@ read_stream_art(Response &r, const char *uri, size_t offset)
const offset_type art_file_size = is->GetSize();
uint8_t buffer[Response::MAX_BINARY_SIZE];
size_t read_size;
if (offset > art_file_size) {
r.Error(ACK_ERROR_ARG, "Offset too large");
return CommandResult::ERROR;
}
{
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;
}
@@ -293,14 +303,16 @@ public:
return;
}
response.Format("size: %" PRIoffset "\n", buffer.size);
response.Format("size: %zu\n", buffer.size);
if (mime_type != nullptr)
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);

View File

@@ -54,12 +54,12 @@ public:
return ParseCommandArgInt(data[idx], min_value, max_value);
}
int ParseUnsigned(unsigned idx) const {
unsigned ParseUnsigned(unsigned idx) const {
assert(idx < size);
return ParseCommandArgUnsigned(data[idx]);
}
int ParseUnsigned(unsigned idx, unsigned max_value) const {
unsigned ParseUnsigned(unsigned idx, unsigned max_value) const {
assert(idx < size);
return ParseCommandArgUnsigned(data[idx], max_value);
}