|
76 | 76 | }).
|
77 | 77 |
|
78 | 78 | -record(incoming_link, {
|
79 |
| - exchange :: rabbit_exchange:name(), |
| 79 | + exchange :: rabbit_types:exchange() | rabbit_exchange:name(), |
80 | 80 | routing_key :: undefined | rabbit_types:routing_key(),
|
81 | 81 | %% queue_name_bin is only set if the link target address refers to a queue.
|
82 | 82 | queue_name_bin :: undefined | rabbit_misc:resource_name(),
|
@@ -713,9 +713,9 @@ handle_control(#'v1_0.attach'{role = ?SEND_ROLE,
|
713 | 713 | user = User}}) ->
|
714 | 714 | ok = validate_attach(Attach),
|
715 | 715 | case ensure_target(Target, Vhost, User) of
|
716 |
| - {ok, XName, RoutingKey, QNameBin} -> |
| 716 | + {ok, Exchange, RoutingKey, QNameBin} -> |
717 | 717 | IncomingLink = #incoming_link{
|
718 |
| - exchange = XName, |
| 718 | + exchange = Exchange, |
719 | 719 | routing_key = RoutingKey,
|
720 | 720 | queue_name_bin = QNameBin,
|
721 | 721 | delivery_count = DeliveryCountInt,
|
@@ -1529,7 +1529,7 @@ incoming_link_transfer(
|
1529 | 1529 | rcv_settle_mode = RcvSettleMode,
|
1530 | 1530 | handle = Handle = ?UINT(HandleInt)},
|
1531 | 1531 | MsgPart,
|
1532 |
| - #incoming_link{exchange = XName = #resource{name = XNameBin}, |
| 1532 | + #incoming_link{exchange = Exchange, |
1533 | 1533 | routing_key = LinkRKey,
|
1534 | 1534 | delivery_count = DeliveryCount0,
|
1535 | 1535 | incoming_unconfirmed_map = U0,
|
@@ -1560,20 +1560,20 @@ incoming_link_transfer(
|
1560 | 1560 | Sections = amqp10_framing:decode_bin(MsgBin),
|
1561 | 1561 | ?DEBUG("~s Inbound content:~n ~tp",
|
1562 | 1562 | [?MODULE, [amqp10_framing:pprint(Section) || Section <- Sections]]),
|
1563 |
| - Anns0 = #{?ANN_EXCHANGE => XNameBin}, |
1564 |
| - Anns = case LinkRKey of |
1565 |
| - undefined -> Anns0; |
1566 |
| - _ -> Anns0#{?ANN_ROUTING_KEYS => [LinkRKey]} |
1567 |
| - end, |
1568 |
| - Mc0 = mc:init(mc_amqp, Sections, Anns), |
1569 |
| - Mc1 = rabbit_message_interceptor:intercept(Mc0), |
1570 |
| - {Mc, RoutingKey} = ensure_routing_key(Mc1), |
1571 |
| - check_user_id(Mc, User), |
1572 |
| - messages_received(Settled), |
1573 |
| - case rabbit_exchange:lookup(XName) of |
1574 |
| - {ok, Exchange} -> |
1575 |
| - check_write_permitted_on_topic(Exchange, User, RoutingKey), |
1576 |
| - QNames = rabbit_exchange:route(Exchange, Mc, #{return_binding_keys => true}), |
| 1563 | + case rabbit_exchange_lookup(Exchange) of |
| 1564 | + {ok, X = #exchange{name = #resource{name = XNameBin}}} -> |
| 1565 | + Anns0 = #{?ANN_EXCHANGE => XNameBin}, |
| 1566 | + Anns = case LinkRKey of |
| 1567 | + undefined -> Anns0; |
| 1568 | + _ -> Anns0#{?ANN_ROUTING_KEYS => [LinkRKey]} |
| 1569 | + end, |
| 1570 | + Mc0 = mc:init(mc_amqp, Sections, Anns), |
| 1571 | + Mc1 = rabbit_message_interceptor:intercept(Mc0), |
| 1572 | + {Mc, RoutingKey} = ensure_routing_key(Mc1), |
| 1573 | + check_user_id(Mc, User), |
| 1574 | + messages_received(Settled), |
| 1575 | + check_write_permitted_on_topic(X, User, RoutingKey), |
| 1576 | + QNames = rabbit_exchange:route(X, Mc, #{return_binding_keys => true}), |
1577 | 1577 | rabbit_trace:tap_in(Mc, QNames, ConnName, ChannelNum, Username, Trace),
|
1578 | 1578 | case not Settled andalso
|
1579 | 1579 | RcvSettleMode =:= ?V_1_0_RECEIVER_SETTLE_MODE_SECOND of
|
@@ -1615,6 +1615,11 @@ incoming_link_transfer(
|
1615 | 1615 | {error, [Disposition, Detach]}
|
1616 | 1616 | end.
|
1617 | 1617 |
|
| 1618 | +rabbit_exchange_lookup(X = #exchange{}) -> |
| 1619 | + {ok, X}; |
| 1620 | +rabbit_exchange_lookup(XName = #resource{}) -> |
| 1621 | + rabbit_exchange:lookup(XName). |
| 1622 | + |
1618 | 1623 | ensure_routing_key(Mc) ->
|
1619 | 1624 | case mc:routing_keys(Mc) of
|
1620 | 1625 | [RoutingKey] ->
|
@@ -1688,16 +1693,25 @@ ensure_target(#'v1_0.target'{address = Address,
|
1688 | 1693 | {ok, Dest} ->
|
1689 | 1694 | QNameBin = ensure_terminus(target, Dest, Vhost, User, Durable),
|
1690 | 1695 | {XNameList1, RK} = rabbit_routing_parser:parse_routing(Dest),
|
1691 |
| - XName = rabbit_misc:r(Vhost, exchange, list_to_binary(XNameList1)), |
| 1696 | + XNameBin = list_to_binary(XNameList1), |
| 1697 | + XName = rabbit_misc:r(Vhost, exchange, XNameBin), |
1692 | 1698 | {ok, X} = rabbit_exchange:lookup(XName),
|
1693 | 1699 | check_internal_exchange(X),
|
1694 | 1700 | check_write_permitted(XName, User),
|
| 1701 | + %% Pre-declared exchanges are protected against deletion and modification. |
| 1702 | + %% Let's cache the whole #exchange{} record to save a |
| 1703 | + %% rabbit_exchange:lookup(XName) call each time we receive a message. |
| 1704 | + Exchange = case XNameBin of |
| 1705 | + <<>> -> X; |
| 1706 | + <<"amq.", _/binary>> -> X; |
| 1707 | + _ -> XName |
| 1708 | + end, |
1695 | 1709 | RoutingKey = case RK of
|
1696 | 1710 | undefined -> undefined;
|
1697 | 1711 | [] -> undefined;
|
1698 | 1712 | _ -> list_to_binary(RK)
|
1699 | 1713 | end,
|
1700 |
| - {ok, XName, RoutingKey, QNameBin}; |
| 1714 | + {ok, Exchange, RoutingKey, QNameBin}; |
1701 | 1715 | {error, _} = E ->
|
1702 | 1716 | E
|
1703 | 1717 | end;
|
|
0 commit comments