commit
819b80bfc9
|
@ -129,7 +129,7 @@ endef
|
|||
LOCAL_DEPS = sasl os_mon inets compiler public_key crypto ssl syntax_tools xmerl
|
||||
|
||||
BUILD_DEPS = rabbitmq_cli
|
||||
DEPS = ranch rabbit_common amqp10_common rabbitmq_prelaunch ra sysmon_handler stdout_formatter recon redbug observer_cli osiris syslog systemd seshat horus khepri khepri_mnesia_migration cuttlefish gen_batch_server
|
||||
DEPS = ranch cowlib rabbit_common amqp10_common rabbitmq_prelaunch ra sysmon_handler stdout_formatter recon redbug observer_cli osiris syslog systemd seshat horus khepri khepri_mnesia_migration cuttlefish gen_batch_server
|
||||
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers meck proper amqp_client rabbitmq_amqp_client rabbitmq_amqp1_0
|
||||
|
||||
# We pin a version of Horus even if we don't use it directly (it is a
|
||||
|
|
|
@ -80,7 +80,7 @@ handle_http_req(<<"GET">>,
|
|||
_User,
|
||||
_ConnPid,
|
||||
PermCaches) ->
|
||||
QNameBin = rabbit_uri:urldecode(QNameBinQuoted),
|
||||
QNameBin = cow_uri:urldecode(QNameBinQuoted),
|
||||
QName = queue_resource(Vhost, QNameBin),
|
||||
case rabbit_amqqueue:with(
|
||||
QName,
|
||||
|
@ -110,7 +110,7 @@ handle_http_req(HttpMethod = <<"PUT">>,
|
|||
exclusive := Exclusive,
|
||||
arguments := QArgs0
|
||||
} = decode_queue(ReqPayload),
|
||||
QNameBin = rabbit_uri:urldecode(QNameBinQuoted),
|
||||
QNameBin = cow_uri:urldecode(QNameBinQuoted),
|
||||
Owner = case Exclusive of
|
||||
true -> ConnPid;
|
||||
false -> none
|
||||
|
@ -190,7 +190,7 @@ handle_http_req(<<"PUT">>,
|
|||
User = #user{username = Username},
|
||||
_ConnPid,
|
||||
{PermCache0, TopicPermCache}) ->
|
||||
XNameBin = rabbit_uri:urldecode(XNameBinQuoted),
|
||||
XNameBin = cow_uri:urldecode(XNameBinQuoted),
|
||||
#{type := XTypeBin,
|
||||
durable := Durable,
|
||||
auto_delete := AutoDelete,
|
||||
|
@ -240,7 +240,7 @@ handle_http_req(<<"DELETE">>,
|
|||
User,
|
||||
ConnPid,
|
||||
{PermCache0, TopicPermCache}) ->
|
||||
QNameBin = rabbit_uri:urldecode(QNameBinQuoted),
|
||||
QNameBin = cow_uri:urldecode(QNameBinQuoted),
|
||||
QName = queue_resource(Vhost, QNameBin),
|
||||
PermCache = check_resource_access(QName, read, User, PermCache0),
|
||||
try rabbit_amqqueue:with_exclusive_access_or_die(
|
||||
|
@ -270,7 +270,7 @@ handle_http_req(<<"DELETE">>,
|
|||
User = #user{username = Username},
|
||||
ConnPid,
|
||||
{PermCache0, TopicPermCache}) ->
|
||||
QNameBin = rabbit_uri:urldecode(QNameBinQuoted),
|
||||
QNameBin = cow_uri:urldecode(QNameBinQuoted),
|
||||
QName = queue_resource(Vhost, QNameBin),
|
||||
ok = prohibit_cr_lf(QNameBin),
|
||||
PermCache = check_resource_access(QName, configure, User, PermCache0),
|
||||
|
@ -290,7 +290,7 @@ handle_http_req(<<"DELETE">>,
|
|||
User = #user{username = Username},
|
||||
_ConnPid,
|
||||
{PermCache0, TopicPermCache}) ->
|
||||
XNameBin = rabbit_uri:urldecode(XNameBinQuoted),
|
||||
XNameBin = cow_uri:urldecode(XNameBinQuoted),
|
||||
XName = exchange_resource(Vhost, XNameBin),
|
||||
ok = prohibit_cr_lf(XNameBin),
|
||||
ok = prohibit_default_exchange(XName),
|
||||
|
@ -630,9 +630,9 @@ decode_binding_path_segment(Segment) ->
|
|||
end,
|
||||
case re:run(Segment, MP, [{capture, all_but_first, binary}]) of
|
||||
{match, [SrcQ, <<DstKindChar>>, DstQ, KeyQ, ArgsHash]} ->
|
||||
Src = rabbit_uri:urldecode(SrcQ),
|
||||
Dst = rabbit_uri:urldecode(DstQ),
|
||||
Key = rabbit_uri:urldecode(KeyQ),
|
||||
Src = cow_uri:urldecode(SrcQ),
|
||||
Dst = cow_uri:urldecode(DstQ),
|
||||
Key = cow_uri:urldecode(KeyQ),
|
||||
DstKind = destination_char_to_kind(DstKindChar),
|
||||
{Src, DstKind, Dst, Key, ArgsHash};
|
||||
nomatch ->
|
||||
|
|
|
@ -2699,7 +2699,7 @@ ensure_source(Source = #'v1_0.source'{address = Address,
|
|||
{utf8, <<"/queues/", QNameBinQuoted/binary>>} ->
|
||||
%% The only possible v2 source address format is:
|
||||
%% /queues/:queue
|
||||
try rabbit_uri:urldecode(QNameBinQuoted) of
|
||||
try cow_uri:urldecode(QNameBinQuoted) of
|
||||
QNameBin ->
|
||||
QName = queue_resource(Vhost, QNameBin),
|
||||
ok = exit_if_absent(QName),
|
||||
|
@ -2907,11 +2907,11 @@ parse_target_v2_string0(<<"/exchanges/", Rest/binary>>) ->
|
|||
[<<"amq.default">> | _] ->
|
||||
{error, bad_address};
|
||||
[XNameBinQuoted] ->
|
||||
XNameBin = rabbit_uri:urldecode(XNameBinQuoted),
|
||||
XNameBin = cow_uri:urldecode(XNameBinQuoted),
|
||||
{ok, XNameBin, <<>>, undefined};
|
||||
[XNameBinQuoted, RKeyQuoted] ->
|
||||
XNameBin = rabbit_uri:urldecode(XNameBinQuoted),
|
||||
RKey = rabbit_uri:urldecode(RKeyQuoted),
|
||||
XNameBin = cow_uri:urldecode(XNameBinQuoted),
|
||||
RKey = cow_uri:urldecode(RKeyQuoted),
|
||||
{ok, XNameBin, RKey, undefined};
|
||||
_ ->
|
||||
{error, bad_address}
|
||||
|
@ -2920,7 +2920,7 @@ parse_target_v2_string0(<<"/queues/">>) ->
|
|||
%% empty queue name is invalid
|
||||
{error, bad_address};
|
||||
parse_target_v2_string0(<<"/queues/", QNameBinQuoted/binary>>) ->
|
||||
QNameBin = rabbit_uri:urldecode(QNameBinQuoted),
|
||||
QNameBin = cow_uri:urldecode(QNameBinQuoted),
|
||||
{ok, ?DEFAULT_EXCHANGE_NAME, QNameBin, QNameBin};
|
||||
parse_target_v2_string0(_) ->
|
||||
{error, bad_address}.
|
||||
|
|
|
@ -1,154 +0,0 @@
|
|||
%% Copyright (c) 2016-2024, Loïc Hoguin <essen@ninenines.eu>
|
||||
%%
|
||||
%% Permission to use, copy, modify, and/or distribute this software for any
|
||||
%% purpose with or without fee is hereby granted, provided that the above
|
||||
%% copyright notice and this permission notice appear in all copies.
|
||||
%%
|
||||
%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
%% ------------------------------------------------------------------------- %%
|
||||
%% This file is a partial copy of
|
||||
%% https://github.com/ninenines/cowlib/blob/optimise-urldecode/src/cow_uri.erl
|
||||
%% We use this copy because:
|
||||
%% 1. uri_string:unquote/1 is lax: It doesn't validate that characters that are
|
||||
%% required to be percent encoded are indeed percent encoded. In RabbitMQ,
|
||||
%% we want to enforce that proper percent encoding is done by AMQP clients.
|
||||
%% 2. uri_string:unquote/1 and cow_uri:urldecode/1 in cowlib v2.13.0 are both
|
||||
%% slow because they allocate a new binary for the common case where no
|
||||
%% character was percent encoded.
|
||||
%% When a new cowlib version is released, we should make app rabbit depend on
|
||||
%% app cowlib calling cow_uri:urldecode/1 and delete this file (rabbit_uri.erl).
|
||||
%% ------------------------------------------------------------------------- %%
|
||||
|
||||
-module(rabbit_uri).
|
||||
|
||||
-export([urldecode/1]).
|
||||
|
||||
-define(UNHEX(H, L), (?UNHEX(H) bsl 4 bor ?UNHEX(L))).
|
||||
|
||||
-define(UNHEX(C),
|
||||
case C of
|
||||
$0 -> 0;
|
||||
$1 -> 1;
|
||||
$2 -> 2;
|
||||
$3 -> 3;
|
||||
$4 -> 4;
|
||||
$5 -> 5;
|
||||
$6 -> 6;
|
||||
$7 -> 7;
|
||||
$8 -> 8;
|
||||
$9 -> 9;
|
||||
$A -> 10;
|
||||
$B -> 11;
|
||||
$C -> 12;
|
||||
$D -> 13;
|
||||
$E -> 14;
|
||||
$F -> 15;
|
||||
$a -> 10;
|
||||
$b -> 11;
|
||||
$c -> 12;
|
||||
$d -> 13;
|
||||
$e -> 14;
|
||||
$f -> 15
|
||||
end
|
||||
).
|
||||
|
||||
%% Decode a percent encoded string. (RFC3986 2.1)
|
||||
%%
|
||||
%% Inspiration for some of the optimisations done here come
|
||||
%% from the new `json` module as it was in mid-2024.
|
||||
%%
|
||||
%% Possible input includes:
|
||||
%%
|
||||
%% * nothing encoded (no % character):
|
||||
%% We want to return the binary as-is to avoid an allocation.
|
||||
%%
|
||||
%% * small number of encoded characters:
|
||||
%% We can "skip" words of text.
|
||||
%%
|
||||
%% * mostly encoded characters (non-ascii languages)
|
||||
%% We can decode characters in bulk.
|
||||
|
||||
-define(IS_PLAIN(C), (
|
||||
(C =:= $!) orelse (C =:= $$) orelse (C =:= $&) orelse (C =:= $') orelse
|
||||
(C =:= $() orelse (C =:= $)) orelse (C =:= $*) orelse (C =:= $+) orelse
|
||||
(C =:= $,) orelse (C =:= $-) orelse (C =:= $.) orelse (C =:= $0) orelse
|
||||
(C =:= $1) orelse (C =:= $2) orelse (C =:= $3) orelse (C =:= $4) orelse
|
||||
(C =:= $5) orelse (C =:= $6) orelse (C =:= $7) orelse (C =:= $8) orelse
|
||||
(C =:= $9) orelse (C =:= $:) orelse (C =:= $;) orelse (C =:= $=) orelse
|
||||
(C =:= $@) orelse (C =:= $A) orelse (C =:= $B) orelse (C =:= $C) orelse
|
||||
(C =:= $D) orelse (C =:= $E) orelse (C =:= $F) orelse (C =:= $G) orelse
|
||||
(C =:= $H) orelse (C =:= $I) orelse (C =:= $J) orelse (C =:= $K) orelse
|
||||
(C =:= $L) orelse (C =:= $M) orelse (C =:= $N) orelse (C =:= $O) orelse
|
||||
(C =:= $P) orelse (C =:= $Q) orelse (C =:= $R) orelse (C =:= $S) orelse
|
||||
(C =:= $T) orelse (C =:= $U) orelse (C =:= $V) orelse (C =:= $W) orelse
|
||||
(C =:= $X) orelse (C =:= $Y) orelse (C =:= $Z) orelse (C =:= $_) orelse
|
||||
(C =:= $a) orelse (C =:= $b) orelse (C =:= $c) orelse (C =:= $d) orelse
|
||||
(C =:= $e) orelse (C =:= $f) orelse (C =:= $g) orelse (C =:= $h) orelse
|
||||
(C =:= $i) orelse (C =:= $j) orelse (C =:= $k) orelse (C =:= $l) orelse
|
||||
(C =:= $m) orelse (C =:= $n) orelse (C =:= $o) orelse (C =:= $p) orelse
|
||||
(C =:= $q) orelse (C =:= $r) orelse (C =:= $s) orelse (C =:= $t) orelse
|
||||
(C =:= $u) orelse (C =:= $v) orelse (C =:= $w) orelse (C =:= $x) orelse
|
||||
(C =:= $y) orelse (C =:= $z) orelse (C =:= $~)
|
||||
)).
|
||||
|
||||
urldecode(Binary) ->
|
||||
skip_dec(Binary, Binary, 0).
|
||||
|
||||
%% This functions helps avoid a binary allocation when
|
||||
%% there is nothing to decode.
|
||||
skip_dec(Binary, Orig, Len) ->
|
||||
case Binary of
|
||||
<<C1, C2, C3, C4, Rest/bits>>
|
||||
when ?IS_PLAIN(C1) andalso ?IS_PLAIN(C2)
|
||||
andalso ?IS_PLAIN(C3) andalso ?IS_PLAIN(C4) ->
|
||||
skip_dec(Rest, Orig, Len + 4);
|
||||
_ ->
|
||||
dec(Binary, [], Orig, 0, Len)
|
||||
end.
|
||||
|
||||
-dialyzer({no_improper_lists, [dec/5]}).
|
||||
%% This clause helps speed up decoding of highly encoded values.
|
||||
dec(<<$%, H1, L1, $%, H2, L2, $%, H3, L3, $%, H4, L4, Rest/bits>>, Acc, Orig, Skip, Len) ->
|
||||
C1 = ?UNHEX(H1, L1),
|
||||
C2 = ?UNHEX(H2, L2),
|
||||
C3 = ?UNHEX(H3, L3),
|
||||
C4 = ?UNHEX(H4, L4),
|
||||
case Len of
|
||||
0 ->
|
||||
dec(Rest, [Acc|<<C1, C2, C3, C4>>], Orig, Skip + 12, 0);
|
||||
_ ->
|
||||
Part = binary_part(Orig, Skip, Len),
|
||||
dec(Rest, [Acc, Part|<<C1, C2, C3, C4>>], Orig, Skip + Len + 12, 0)
|
||||
end;
|
||||
dec(<<$%, H, L, Rest/bits>>, Acc, Orig, Skip, Len) ->
|
||||
C = ?UNHEX(H, L),
|
||||
case Len of
|
||||
0 ->
|
||||
dec(Rest, [Acc|<<C>>], Orig, Skip + 3, 0);
|
||||
_ ->
|
||||
Part = binary_part(Orig, Skip, Len),
|
||||
dec(Rest, [Acc, Part|<<C>>], Orig, Skip + Len + 3, 0)
|
||||
end;
|
||||
%% This clause helps speed up decoding of barely encoded values.
|
||||
dec(<<C1, C2, C3, C4, Rest/bits>>, Acc, Orig, Skip, Len)
|
||||
when ?IS_PLAIN(C1) andalso ?IS_PLAIN(C2)
|
||||
andalso ?IS_PLAIN(C3) andalso ?IS_PLAIN(C4) ->
|
||||
dec(Rest, Acc, Orig, Skip, Len + 4);
|
||||
dec(<<C, Rest/bits>>, Acc, Orig, Skip, Len) when ?IS_PLAIN(C) ->
|
||||
dec(Rest, Acc, Orig, Skip, Len + 1);
|
||||
dec(<<>>, _, Orig, 0, _) ->
|
||||
Orig;
|
||||
dec(<<>>, Acc, _, _, 0) ->
|
||||
iolist_to_binary(Acc);
|
||||
dec(<<>>, Acc, Orig, Skip, Len) ->
|
||||
Part = binary_part(Orig, Skip, Len),
|
||||
iolist_to_binary([Acc|Part]);
|
||||
dec(_, _, Orig, Skip, Len) ->
|
||||
error({invalid_byte, binary:at(Orig, Skip + Len)}).
|
|
@ -92,7 +92,7 @@ convert_from(mc_amqp, Sections, Env) ->
|
|||
MqttX:(byte_size(MqttX))/binary,
|
||||
"/",
|
||||
RoutingKeyQuoted/binary>> ->
|
||||
try rabbit_uri:urldecode(RoutingKeyQuoted) of
|
||||
try cow_uri:urldecode(RoutingKeyQuoted) of
|
||||
RoutingKey ->
|
||||
MqttTopic = rabbit_mqtt_util:amqp_to_mqtt(RoutingKey),
|
||||
#{'Response-Topic' => MqttTopic}
|
||||
|
|
Loading…
Reference in New Issue