Skip to content

Commit 9587f3a

Browse files
committed
Support all-with-x in x-match binding arg for headers exchange
Similar to any-with-x. For example, this allows routing messages to different target queues based on their x-first-death-reason AND x-first-death-queue header.
1 parent 56c243a commit 9587f3a

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

deps/rabbit/src/rabbit_exchange_type_headers.erl

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ validate_binding(_X, #binding{args = Args}) ->
4545
case rabbit_misc:table_lookup(Args, <<"x-match">>) of
4646
{longstr, <<"all">>} -> ok;
4747
{longstr, <<"any">>} -> ok;
48+
{longstr, <<"all-with-x">>} -> ok;
4849
{longstr, <<"any-with-x">>} -> ok;
4950
{longstr, Other} -> {error,
5051
{binding_invalid,
5152
"Invalid x-match field value ~p; "
52-
"expected all, any, or any-with-x", [Other]}};
53+
"expected all, any, all-with-x, or any-with-x", [Other]}};
5354
{Type, Other} -> {error,
5455
{binding_invalid,
5556
"Invalid x-match field type ~p (value ~p); "
@@ -61,6 +62,7 @@ validate_binding(_X, #binding{args = Args}) ->
6162

6263
parse_x_match({longstr, <<"all">>}) -> all;
6364
parse_x_match({longstr, <<"any">>}) -> any;
65+
parse_x_match({longstr, <<"all-with-x">>}) -> all_with_x;
6466
parse_x_match({longstr, <<"any-with-x">>}) -> any_with_x;
6567
parse_x_match(_) -> all. %% legacy; we didn't validate
6668

@@ -84,18 +86,25 @@ headers_match(Args, Data) ->
8486

8587
% A bit less horrendous algorithm :)
8688
headers_match(_, _, false, _, all) -> false;
89+
headers_match(_, _, false, _, all_with_x) -> false;
8790
headers_match(_, _, _, true, any) -> true;
8891
headers_match(_, _, _, true, any_with_x) -> true;
8992

9093
% No more bindings, return current state
9194
headers_match([], _Data, AllMatch, _AnyMatch, all) -> AllMatch;
95+
headers_match([], _Data, AllMatch, _AnyMatch, all_with_x) -> AllMatch;
9296
headers_match([], _Data, _AllMatch, AnyMatch, any) -> AnyMatch;
9397
headers_match([], _Data, _AllMatch, AnyMatch, any_with_x) -> AnyMatch;
9498

95-
% Delete bindings starting with x-
99+
%% Always delete binding x-match
100+
headers_match([{<<"x-match">>, _PT, _PV} | PRest], Data,
101+
AllMatch, AnyMatch, MatchKind) ->
102+
headers_match(PRest, Data, AllMatch, AnyMatch, MatchKind);
103+
% Delete all other bindings starting with x-
104+
% unless x-match is set to all-with-x or any-with-x
96105
headers_match([{<<"x-", _/binary>>, _PT, _PV} | PRest], Data,
97106
AllMatch, AnyMatch, MatchKind)
98-
when MatchKind =/= any_with_x ->
107+
when MatchKind =/= all_with_x, MatchKind =/= any_with_x ->
99108
headers_match(PRest, Data, AllMatch, AnyMatch, MatchKind);
100109

101110
% No more data, but still bindings, false with all

0 commit comments

Comments
 (0)