summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Bridgen <mikeb@lshift.net>2010-02-22 17:35:32 +0000
committerMichael Bridgen <mikeb@lshift.net>2010-02-22 17:35:32 +0000
commit0f764e1d4afbce402e3264899111fd9bad5fd6e6 (patch)
tree466243cd330eeeef7330a999af92549da2db6db8
parent8dd6e060058c530b97efc15e71b2d7d76d5fdfe8 (diff)
downloadrabbitmq-server-0f764e1d4afbce402e3264899111fd9bad5fd6e6.tar.gz
Distinguish between situations in which we're checking if a
client-supplied binary corresponds to an exchange type (the type may be bogus), and just looking up the module for the type in an exchange record (we expect the type, and the module, to exist). There'll be a better way of doing both the lookup and the sanity check in check_type.
-rw-r--r--src/rabbit_exchange.erl28
-rw-r--r--src/rabbit_exchange_type_registry.erl15
2 files changed, 31 insertions, 12 deletions
diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl
index 2c5ea99c..f6cc030b 100644
--- a/src/rabbit_exchange.erl
+++ b/src/rabbit_exchange.erl
@@ -162,6 +162,7 @@ declare(ExchangeName, Type, Durable, AutoDelete, Args) ->
Err -> Err
end.
+%% Used with atoms from records; e.g., the type is expected to exist.
type_to_module(T) ->
case rabbit_exchange_type_registry:lookup_module(T) of
{ok, Module} -> Module;
@@ -170,18 +171,25 @@ type_to_module(T) ->
"invalid exchange type '~s'", [T])
end.
+%% Used with binaries sent over the wire; the type may not exist.
check_type(TypeBin) ->
- T = rabbit_exchange_type_registry:binary_to_type(TypeBin),
- Module = type_to_module(T),
- case catch Module:description() of
- {'EXIT', {undef, [{_, description, []} | _]}} ->
+ case rabbit_exchange_type_registry:binary_to_type(TypeBin) of
+ {error, not_found} ->
rabbit_misc:protocol_error(
- command_invalid, "invalid exchange type '~s'", [T]);
- {'EXIT', _} ->
- rabbit_misc:protocol_error(
- command_invalid, "problem loading exchange type '~s'", [T]);
- _ ->
- T
+ command_invalid, "unknown exchange type '~s'", [TypeBin]);
+ T ->
+ Module = type_to_module(T),
+ %% sanity check
+ case catch Module:description() of
+ {'EXIT', {undef, [{_, description, []} | _]}} ->
+ rabbit_misc:protocol_error(
+ command_invalid, "invalid exchange type '~s'", [T]);
+ {'EXIT', _} ->
+ rabbit_misc:protocol_error(
+ command_invalid, "problem loading exchange type '~s'", [T]);
+ _ ->
+ T
+ end
end.
assert_type(#exchange{ type = ActualType }, RequiredType)
diff --git a/src/rabbit_exchange_type_registry.erl b/src/rabbit_exchange_type_registry.erl
index 722a926e..56ce9dc9 100644
--- a/src/rabbit_exchange_type_registry.erl
+++ b/src/rabbit_exchange_type_registry.erl
@@ -55,8 +55,15 @@ start_link() ->
register(TypeName, ModuleName) ->
gen_server:call(?SERVER, {register, TypeName, ModuleName}).
+%% This is used with user-supplied arguments (e.g., on exchange
+%% declare), so we restrict it to existing atoms only. This means it
+%% can throw a badarg, indicating that the type cannot have been
+%% registered.
binary_to_type(TypeBin) when is_binary(TypeBin) ->
- list_to_atom(binary_to_list(TypeBin)).
+ case catch list_to_existing_atom(binary_to_list(TypeBin)) of
+ {'EXIT', {badarg, _}} -> {error, not_found};
+ TypeAtom -> TypeAtom
+ end.
lookup_module(T) when is_atom(T) ->
case ets:lookup(?ETS_NAME, T) of
@@ -68,9 +75,13 @@ lookup_module(T) when is_atom(T) ->
%%---------------------------------------------------------------------------
+internal_binary_to_type(TypeBin) when is_binary(TypeBin) ->
+ list_to_atom(binary_to_list(TypeBin)).
+
internal_register(TypeName, ModuleName)
when is_binary(TypeName), is_atom(ModuleName) ->
- true = ets:insert(?ETS_NAME, {binary_to_type(TypeName), ModuleName}),
+ true = ets:insert(?ETS_NAME,
+ {internal_binary_to_type(TypeName), ModuleName}),
ok.
%%---------------------------------------------------------------------------