Skip to content

Commit 03fc22d

Browse files
committed
Introduce a configurable limit to message size.
Add `max_message_size` configuration to configure limit in bytes. If message is bigger - channel exception will be thrown. Default limit is 128MB. There is still a hard limit of 521MB. [#161983593]
1 parent 794ef8d commit 03fc22d

File tree

4 files changed

+99
-2
lines changed

4 files changed

+99
-2
lines changed

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ define PROJECT_ENV
130130
{vhost_restart_strategy, continue},
131131
%% {global, prefetch count}
132132
{default_consumer_prefetch, {false, 0}},
133-
{channel_queue_cleanup_interval, 60000}
133+
{channel_queue_cleanup_interval, 60000},
134+
%% Default max message size is 128 MB
135+
{max_message_size, 134217728}
134136
]
135137
endef
136138

priv/schema/rabbit.schema

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,9 @@ end}.
554554
}.
555555

556556

557+
{mapping, "msx_message_size", "rabbit.max_message_size",
558+
[{datatype, integer}, {validators, ["less_then_512MB"]}]}.
559+
557560
%% Customising Socket Options.
558561
%%
559562
%% See (http://www.erlang.org/doc/man/inet.html#setopts-2) for
@@ -1361,6 +1364,11 @@ fun(Size) when is_integer(Size) ->
13611364
Size > 0 andalso Size < 2147483648
13621365
end}.
13631366

1367+
{validator, "less_then_512MB", "Max message size should be less than 512MB and gre than 0",
1368+
fun(Size) when is_integer(Size) ->
1369+
Size > 0 andalso Size < 536870912
1370+
end}.
1371+
13641372
{validator, "less_than_1", "Flooat is not beetween 0 and 1",
13651373
fun(Float) when is_float(Float) ->
13661374
Float > 0 andalso Float < 1

src/rabbit_channel.erl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,15 @@ check_msg_size(Content) ->
990990
case Size > ?MAX_MSG_SIZE of
991991
true -> precondition_failed("message size ~B larger than max size ~B",
992992
[Size, ?MAX_MSG_SIZE]);
993-
false -> ok
993+
false ->
994+
case application:get_env(rabbit, max_message_size) of
995+
{ok, MaxSize} when is_integer(MaxSize) andalso Size > MaxSize ->
996+
precondition_failed("message size ~B larger than"
997+
" configured max size ~B",
998+
[Size, MaxSize]);
999+
1000+
_ -> ok
1001+
end
9941002
end.
9951003

9961004
check_vhost_queue_limit(#resource{name = QueueName}, VHost) ->

test/unit_inbroker_parallel_SUITE.erl

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ groups() ->
5858
set_disk_free_limit_command,
5959
set_vm_memory_high_watermark_command,
6060
topic_matching,
61+
max_message_size,
6162
{queue_max_length, [], [
6263
{max_length_simple, [], MaxLengthTests},
6364
{max_length_mirrored, [], MaxLengthTests}]}
@@ -1299,6 +1300,84 @@ sync_mirrors(QName, Config) ->
12991300
_ -> ok
13001301
end.
13011302

1303+
gen_binary_mb(N) ->
1304+
B1M = << <<"_">> || _ <- lists:seq(1, 1024 * 1024) >>,
1305+
<< B1M || _ <- lists:seq(1, N) >>.
1306+
1307+
assert_channel_alive(Ch) ->
1308+
amqp_channel:call(Ch, #'basic.publish'{routing_key = <<"nope">>},
1309+
#amqp_msg{payload = <<"HI">>}).
1310+
1311+
assert_channel_fail_max_size(Ch, Monitor, ExpectedException) ->
1312+
receive
1313+
{'DOWN', Monitor, process, Ch,
1314+
{shutdown,
1315+
{server_initiated_close, 406, Exception}}} ->
1316+
?assertMatch(Exception, ExpectedException)
1317+
after 100000 ->
1318+
error({channel_exception_expected, max_message_size})
1319+
end.
1320+
1321+
max_message_size(Config) ->
1322+
Binary128M = gen_binary_mb(128),
1323+
{_, Ch} = rabbit_ct_client_helpers:open_connection_and_channel(Config, 0),
1324+
%% Default message size is 128MB
1325+
Size128Mb = 1024 * 1024 * 128,
1326+
Size128Mb = rabbit_ct_broker_helpers:rpc(Config, 0,
1327+
application, get_env, [rabbit, max_message_size, undefined]),
1328+
1329+
Size128Mb = byte_size(Binary128M),
1330+
%% Binary is whithin the max size limit
1331+
amqp_channel:call(Ch, #'basic.publish'{routing_key = <<"nope">>}, #amqp_msg{payload = Binary128M}),
1332+
%% Channel process is alive
1333+
assert_channel_alive(Ch),
1334+
1335+
Monitor = monitor(process, Ch),
1336+
%% This publish should cause a channel exception
1337+
BinaryBiggerThan128M = <<"_", Binary128M/binary>>,
1338+
amqp_channel:call(Ch, #'basic.publish'{routing_key = <<"nope">>}, #amqp_msg{payload = BinaryBiggerThan128M}),
1339+
ct:pal("Assert channel error 128"),
1340+
ExpectedException = <<"PRECONDITION_FAILED - message size ",
1341+
(integer_to_binary(byte_size(BinaryBiggerThan128M)))/binary,
1342+
" larger than configured max size ",
1343+
(integer_to_binary(Size128Mb))/binary>>,
1344+
assert_channel_fail_max_size(Ch, Monitor, ExpectedException),
1345+
1346+
1347+
{_, Ch1} = rabbit_ct_client_helpers:open_connection_and_channel(Config, 0),
1348+
1349+
%% Set a bigger message size
1350+
rabbit_ct_broker_helpers:rpc(Config, 0,
1351+
application, set_env, [rabbit, max_message_size, 1024 * 1024 * 256]),
1352+
1353+
amqp_channel:call(Ch1, #'basic.publish'{routing_key = <<"nope">>}, #amqp_msg{payload = Binary128M}),
1354+
assert_channel_alive(Ch1),
1355+
1356+
amqp_channel:call(Ch1, #'basic.publish'{routing_key = <<"nope">>}, #amqp_msg{payload = BinaryBiggerThan128M}),
1357+
assert_channel_alive(Ch1),
1358+
1359+
%% Set message size above 512MB.
1360+
%% The actual limit will be 512MB
1361+
rabbit_ct_broker_helpers:rpc(Config, 0,
1362+
application, set_env, [rabbit, max_message_size, 1024 * 1024 * 515]),
1363+
1364+
Binary512M = << Binary128M/binary, Binary128M/binary,
1365+
Binary128M/binary, Binary128M/binary>>,
1366+
1367+
BinaryBiggerThan512M = <<"_", Binary512M/binary>>,
1368+
1369+
amqp_channel:call(Ch1, #'basic.publish'{routing_key = <<"nope">>}, #amqp_msg{payload = Binary512M}),
1370+
assert_channel_alive(Ch1),
1371+
1372+
Monitor1 = monitor(process, Ch1),
1373+
amqp_channel:call(Ch1, #'basic.publish'{routing_key = <<"nope">>}, #amqp_msg{payload = BinaryBiggerThan512M}),
1374+
ct:pal("Assert channel error 512"),
1375+
ExpectedException1 = <<"PRECONDITION_FAILED - message size ",
1376+
(integer_to_binary(byte_size(BinaryBiggerThan512M)))/binary,
1377+
" larger than max size ",
1378+
(integer_to_binary(byte_size(Binary512M)))/binary>>,
1379+
assert_channel_fail_max_size(Ch1, Monitor1, ExpectedException1).
1380+
13021381
%% ---------------------------------------------------------------------------
13031382
%% rabbitmqctl helpers.
13041383
%% ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)