Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
995aafe9
Commit
995aafe9
authored
Jan 21, 2021
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
protocol: add command "binarylimit"
Increasing the protocol version to 0.22.4 to allow clients to detect this feature. Closes
https://github.com/MusicPlayerDaemon/MPD/issues/1038
parent
6e33566c
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
66 additions
and
25 deletions
+66
-25
NEWS
NEWS
+1
-0
protocol.rst
doc/protocol.rst
+20
-5
meson.build
meson.build
+1
-1
Client.hxx
src/client/Client.hxx
+7
-0
Response.cxx
src/client/Response.cxx
+1
-1
Response.hxx
src/client/Response.hxx
+0
-2
AllCommands.cxx
src/command/AllCommands.cxx
+1
-0
ClientCommands.cxx
src/command/ClientCommands.cxx
+15
-0
ClientCommands.hxx
src/command/ClientCommands.hxx
+3
-0
FileCommands.cxx
src/command/FileCommands.cxx
+17
-16
No files found.
NEWS
View file @
995aafe9
ver 0.22.4 (not yet released)
ver 0.22.4 (not yet released)
* protocol
* protocol
- add command "binarylimit" to allow larger chunk sizes
- fix "readpicture" on 32 bit machines
- fix "readpicture" on 32 bit machines
- show duration and tags of songs in virtual playlist (CUE) folders
- show duration and tags of songs in virtual playlist (CUE) folders
* storage
* storage
...
...
doc/protocol.rst
View file @
995aafe9
...
@@ -69,11 +69,14 @@ that, the specified number of bytes of binary data follows, then a
...
@@ -69,11 +69,14 @@ that, the specified number of bytes of binary data follows, then a
newline, and finally the ``OK`` line.
newline, and finally the ``OK`` line.
If the object to be transmitted is large, the server may choose a
If the object to be transmitted is large, the server may choose a
reasonable chunk size and transmit only a portion. Usually, the
reasonable chunk size and transmit only a portion. The maximum chunk
response also contains a ``size`` line which specifies the total
size can be changed by clients with the :ref:`binarylimit
(uncropped) size, and the command usually has a way to specify an
<command_binarylimit>` command.
offset into the object; this way, the client can copy the whole file
without blocking the connection for too long.
Usually, the response also contains a ``size`` line which specifies
the total (uncropped) size, and the command usually has a way to
specify an offset into the object; this way, the client can copy the
whole file without blocking the connection for too long.
Example::
Example::
...
@@ -1355,6 +1358,17 @@ Connection settings
...
@@ -1355,6 +1358,17 @@ Connection settings
:command:`ping`
:command:`ping`
Does nothing but return "OK".
Does nothing but return "OK".
.. _command_binarylimit:
:command:`binarylimit SIZE` [#since_0_22_4]_
Set the maximum :ref:`binary response <binary>` size for the
current connection to the specified number of bytes.
A bigger value means less overhead for transmitting large
entities, but it also means that the connection is blocked for a
longer time.
.. _command_tagtypes:
.. _command_tagtypes:
:command:`tagtypes`
:command:`tagtypes`
...
@@ -1583,3 +1597,4 @@ client-to-client messages are local to the current partition.
...
@@ -1583,3 +1597,4 @@ client-to-client messages are local to the current partition.
.. [#since_0_19] Since :program:`MPD` 0.19
.. [#since_0_19] Since :program:`MPD` 0.19
.. [#since_0_20] Since :program:`MPD` 0.20
.. [#since_0_20] Since :program:`MPD` 0.20
.. [#since_0_21] Since :program:`MPD` 0.21
.. [#since_0_21] Since :program:`MPD` 0.21
.. [#since_0_22_4] Since :program:`MPD` 0.22.4
meson.build
View file @
995aafe9
...
@@ -32,7 +32,7 @@ version_conf = configuration_data()
...
@@ -32,7 +32,7 @@ version_conf = configuration_data()
version_conf.set_quoted('PACKAGE', meson.project_name())
version_conf.set_quoted('PACKAGE', meson.project_name())
version_conf.set_quoted('PACKAGE_NAME', meson.project_name())
version_conf.set_quoted('PACKAGE_NAME', meson.project_name())
version_conf.set_quoted('VERSION', meson.project_version())
version_conf.set_quoted('VERSION', meson.project_version())
version_conf.set_quoted('PROTOCOL_VERSION', '0.22.
0
')
version_conf.set_quoted('PROTOCOL_VERSION', '0.22.
4
')
configure_file(output: 'Version.h', configuration: version_conf)
configure_file(output: 'Version.h', configuration: version_conf)
conf = configuration_data()
conf = configuration_data()
...
...
src/client/Client.hxx
View file @
995aafe9
...
@@ -84,6 +84,12 @@ public:
...
@@ -84,6 +84,12 @@ public:
*/
*/
TagMask
tag_mask
=
TagMask
::
All
();
TagMask
tag_mask
=
TagMask
::
All
();
/**
* The maximum number of bytes transmitted in a binary
* response. Can be changed with the "binarylimit" command.
*/
size_t
binary_limit
=
8192
;
private
:
private
:
static
constexpr
size_t
MAX_SUBSCRIPTIONS
=
16
;
static
constexpr
size_t
MAX_SUBSCRIPTIONS
=
16
;
...
@@ -122,6 +128,7 @@ public:
...
@@ -122,6 +128,7 @@ public:
~
Client
()
noexcept
;
~
Client
()
noexcept
;
using
FullyBufferedSocket
::
GetEventLoop
;
using
FullyBufferedSocket
::
GetEventLoop
;
using
FullyBufferedSocket
::
GetOutputMaxSize
;
gcc_pure
gcc_pure
bool
IsExpired
()
const
noexcept
{
bool
IsExpired
()
const
noexcept
{
...
...
src/client/Response.cxx
View file @
995aafe9
...
@@ -59,7 +59,7 @@ Response::Format(const char *fmt, ...) noexcept
...
@@ -59,7 +59,7 @@ Response::Format(const char *fmt, ...) noexcept
bool
bool
Response
::
WriteBinary
(
ConstBuffer
<
void
>
payload
)
noexcept
Response
::
WriteBinary
(
ConstBuffer
<
void
>
payload
)
noexcept
{
{
assert
(
payload
.
size
<=
MAX_BINARY_SIZE
);
assert
(
payload
.
size
<=
client
.
binary_limit
);
return
Format
(
"binary: %zu
\n
"
,
payload
.
size
)
&&
return
Format
(
"binary: %zu
\n
"
,
payload
.
size
)
&&
Write
(
payload
.
data
,
payload
.
size
)
&&
Write
(
payload
.
data
,
payload
.
size
)
&&
...
...
src/client/Response.hxx
View file @
995aafe9
...
@@ -79,8 +79,6 @@ public:
...
@@ -79,8 +79,6 @@ public:
gcc_printf
(
2
,
3
)
gcc_printf
(
2
,
3
)
bool
Format
(
const
char
*
fmt
,
...)
noexcept
;
bool
Format
(
const
char
*
fmt
,
...)
noexcept
;
static
constexpr
size_t
MAX_BINARY_SIZE
=
8192
;
/**
/**
* Write a binary chunk; this writes the "binary" line, the
* Write a binary chunk; this writes the "binary" line, the
* given chunk and the trailing newline.
* given chunk and the trailing newline.
...
...
src/command/AllCommands.cxx
View file @
995aafe9
...
@@ -87,6 +87,7 @@ static constexpr struct command commands[] = {
...
@@ -87,6 +87,7 @@ static constexpr struct command commands[] = {
{
"addid"
,
PERMISSION_ADD
,
1
,
2
,
handle_addid
},
{
"addid"
,
PERMISSION_ADD
,
1
,
2
,
handle_addid
},
{
"addtagid"
,
PERMISSION_ADD
,
3
,
3
,
handle_addtagid
},
{
"addtagid"
,
PERMISSION_ADD
,
3
,
3
,
handle_addtagid
},
{
"albumart"
,
PERMISSION_READ
,
2
,
2
,
handle_album_art
},
{
"albumart"
,
PERMISSION_READ
,
2
,
2
,
handle_album_art
},
{
"binarylimit"
,
PERMISSION_NONE
,
1
,
1
,
handle_binary_limit
},
{
"channels"
,
PERMISSION_READ
,
0
,
0
,
handle_channels
},
{
"channels"
,
PERMISSION_READ
,
0
,
0
,
handle_channels
},
{
"clear"
,
PERMISSION_CONTROL
,
0
,
0
,
handle_clear
},
{
"clear"
,
PERMISSION_CONTROL
,
0
,
0
,
handle_clear
},
{
"clearerror"
,
PERMISSION_CONTROL
,
0
,
0
,
handle_clearerror
},
{
"clearerror"
,
PERMISSION_CONTROL
,
0
,
0
,
handle_clearerror
},
...
...
src/command/ClientCommands.cxx
View file @
995aafe9
...
@@ -41,6 +41,21 @@ handle_ping([[maybe_unused]] Client &client, [[maybe_unused]] Request args,
...
@@ -41,6 +41,21 @@ handle_ping([[maybe_unused]] Client &client, [[maybe_unused]] Request args,
}
}
CommandResult
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
)
handle_password
(
Client
&
client
,
Request
args
,
Response
&
r
)
{
{
unsigned
permission
=
0
;
unsigned
permission
=
0
;
...
...
src/command/ClientCommands.hxx
View file @
995aafe9
...
@@ -33,6 +33,9 @@ CommandResult
...
@@ -33,6 +33,9 @@ CommandResult
handle_ping
(
Client
&
client
,
Request
request
,
Response
&
response
);
handle_ping
(
Client
&
client
,
Request
request
,
Response
&
response
);
CommandResult
CommandResult
handle_binary_limit
(
Client
&
client
,
Request
request
,
Response
&
response
);
CommandResult
handle_password
(
Client
&
client
,
Request
request
,
Response
&
response
);
handle_password
(
Client
&
client
,
Request
request
,
Response
&
response
);
CommandResult
CommandResult
...
...
src/command/FileCommands.cxx
View file @
995aafe9
...
@@ -43,6 +43,7 @@
...
@@ -43,6 +43,7 @@
#include "thread/Mutex.hxx"
#include "thread/Mutex.hxx"
#include "Log.hxx"
#include "Log.hxx"
#include <algorithm>
#include <cassert>
#include <cassert>
#include <cinttypes>
/* for PRIu64 */
#include <cinttypes>
/* for PRIu64 */
...
@@ -205,28 +206,26 @@ read_stream_art(Response &r, const char *uri, size_t offset)
...
@@ -205,28 +206,26 @@ read_stream_art(Response &r, const char *uri, size_t offset)
const
offset_type
art_file_size
=
is
->
GetSize
();
const
offset_type
art_file_size
=
is
->
GetSize
();
if
(
offset
>=
art_file_size
)
{
if
(
offset
>
art_file_size
)
{
if
(
offset
>
art_file_size
)
{
r
.
Error
(
ACK_ERROR_ARG
,
"Offset too large"
);
r
.
Error
(
ACK_ERROR_ARG
,
"Offset too large"
);
return
CommandResult
::
ERROR
;
return
CommandResult
::
ERROR
;
}
else
{
r
.
Format
(
"size: %"
PRIoffset
"
\n
"
,
art_file_size
);
r
.
WriteBinary
(
nullptr
);
return
CommandResult
::
OK
;
}
}
}
uint8_t
buffer
[
Response
::
MAX_BINARY_SIZE
];
std
::
size_t
buffer_size
=
size_t
read_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
);
std
::
unique_lock
<
Mutex
>
lock
(
mutex
);
is
->
Seek
(
lock
,
offset
);
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
.
Format
(
"size: %"
PRIoffset
"
\n
"
,
art_file_size
);
r
.
WriteBinary
({
buffer
,
read_size
});
r
.
WriteBinary
({
buffer
.
get
()
,
read_size
});
return
CommandResult
::
OK
;
return
CommandResult
::
OK
;
}
}
...
@@ -313,8 +312,10 @@ public:
...
@@ -313,8 +312,10 @@ public:
response
.
Format
(
"type: %s
\n
"
,
mime_type
);
response
.
Format
(
"type: %s
\n
"
,
mime_type
);
buffer
.
size
-=
offset
;
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
);
buffer
.
data
=
OffsetPointer
(
buffer
.
data
,
offset
);
response
.
WriteBinary
(
buffer
);
response
.
WriteBinary
(
buffer
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment