diff options
author | Michael Bridgen <mikeb@lshift.net> | 2010-02-22 17:35:32 +0000 |
---|---|---|
committer | Michael Bridgen <mikeb@lshift.net> | 2010-02-22 17:35:32 +0000 |
commit | 0f764e1d4afbce402e3264899111fd9bad5fd6e6 (patch) | |
tree | 466243cd330eeeef7330a999af92549da2db6db8 | |
parent | 8dd6e060058c530b97efc15e71b2d7d76d5fdfe8 (diff) | |
download | rabbitmq-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.erl | 28 | ||||
-rw-r--r-- | src/rabbit_exchange_type_registry.erl | 15 |
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. %%--------------------------------------------------------------------------- |