diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 7bd5688..f55e0a2 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -1,4 +1,4 @@ -name: Build +name: rabbitmq-email on: pull_request: @@ -10,12 +10,12 @@ on: jobs: CI: - name: Build and test on Erlang/OTP ${{ matrix.otp-version }} + name: build/test on Erlang/OTP ${{ matrix.otp-version }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: - otp-version: [23, 24, 25] + otp-version: [25] elixir-version: ['1.14'] steps: - uses: actions/checkout@v3 diff --git a/Makefile b/Makefile index 45f9a9f..f219e15 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ DEP_RANCH_VERSION = 2.1.0 dep_ranch = ranch $(DEP_RANCH_VERSION) dep_eiconv = hex 1.0.0 -dep_gen_smtp = git https://github.com/gen-smtp/gen_smtp.git 1.1.1 +dep_gen_smtp = hex 1.2.0 DEPS = gen_smtp rabbit_common amqp_client rabbit eiconv diff --git a/README.md b/README.md index d12ff1d..b70457f 100644 --- a/README.md +++ b/README.md @@ -17,16 +17,22 @@ contributions are encouraged. [![Build Status](https://github.com/gotthardp/rabbitmq-email/actions/workflows/main.yaml/badge.svg?branch=master)](https://github.com/gotthardp/rabbitmq-email/actions) + +## RabbitMQ and Erlang Compatibility + +**Note:** As of version `1.1.0`, this plugin has been tested with RabbitMQ `v3.11.x` versions and Erlang/OTP `25.x` + + ## Installation -Due to the dependency on the `eiconv` library, which has a C source code component, this plugin must be compiled from source. If you are planning to use RabbitMQ version 3.9.13: +Due to the dependency on the `eiconv` library, which has a C source code component, this plugin must be compiled from source. If you are planning to use RabbitMQ version `3.11.1`: ``` git clone https://github.com/gotthardp/rabbitmq-email.git cd rabbitmq-email make make tests # optional -make RABBITMQ_VERSION=v3.9.13 dist +make RABBITMQ_VERSION=v3.11.1 dist ``` Copy the following directories to your RabbitMQ `plugins/` directory: @@ -37,8 +43,6 @@ plugins/gen_smtp-1.1.1 plugins/rabbitmq_email-1.0.1 ``` -Note that as of version 1.0.1 this plugin has been tested with RabbitMQ v3.9.x versions only. - ## Documentation The mapping between SMTP and AMQP 0-9-1 works in both directions. Before we provide a specific @@ -287,6 +291,12 @@ since this is a NIF (native code) its module is not portable between platforms. ### Change Log +* 1.1.0 (Oct 18, 2022) + * Compatibility with recent RabbitMQ versions. + * `3.11.x` + * `3.10.x` + * Update `gen_smtp` to `1.2.0` + * Add ability to set max message size in [PR #54](https://github.com/gotthardp/rabbitmq-email/pull/54) * 1.0.0 (Nov 23, 2021) * Compatibility with recent RabbitMQ versions. * `3.9.x` diff --git a/src/rabbit_email_handler.erl b/src/rabbit_email_handler.erl index 5508346..91d1902 100644 --- a/src/rabbit_email_handler.erl +++ b/src/rabbit_email_handler.erl @@ -23,6 +23,7 @@ options = [] :: list() }). -define(AUTH_REQUIRED, "530 SMTP authentication is required"). +-define(DEFAULT_MAXSIZE, 10485760). % 10MiB init(Hostname, SessionCount, Address, Options) when SessionCount < 20 -> rabbit_log:info("~s SMTP connection from ~p~n", [Hostname, Address]), @@ -44,18 +45,22 @@ handle_HELO(Hostname, State) -> {ok, 655360, set_user_as_anonymous(State)}; % 640kb should be enough for anyone _Else -> % we expect EHLO will come - {ok, State} % use the default 10mb limit + MaxSize = application:get_env(rabbitmq_email, server_maxsize, ?DEFAULT_MAXSIZE), + {ok, MaxSize, State} end. -handle_EHLO(Hostname, Extensions, State) -> +handle_EHLO(Hostname, Ext0, State0) -> rabbit_log:info("EHLO from ~s~n", [Hostname]), - ExtensionsTLS = starttls_extension(Extensions), - case application:get_env(rabbitmq_email, server_auth) of - {ok, false} -> - {ok, ExtensionsTLS, set_user_as_anonymous(State)}; - {ok, rabbitmq} -> - {ok, [{"AUTH", "PLAIN LOGIN"} | ExtensionsTLS], State} - end. + Ext1 = starttls_extension(Ext0), + MaxSize = application:get_env(rabbitmq_email, server_maxsize, ?DEFAULT_MAXSIZE), + Ext2 = [{"SIZE", integer_to_list(MaxSize)} | Ext1], + {Ext3, State1} = case application:get_env(rabbitmq_email, server_auth) of + {ok, false} -> + {Ext2, set_user_as_anonymous(State0)}; + {ok, rabbitmq} -> + {[{"AUTH", "PLAIN LOGIN"} | Ext2], State0} + end, + {ok, Ext3, State1}. set_user_as_anonymous(State) -> State#state{auth_user=anonymous}. diff --git a/src/rabbitmq_email.app.src b/src/rabbitmq_email.app.src index bac401b..4929f1d 100644 --- a/src/rabbitmq_email.app.src +++ b/src/rabbitmq_email.app.src @@ -20,6 +20,7 @@ ]}, {server_auth, rabbitmq}, {server_starttls, false}, + {server_maxsize, 10485760}, % 10MiB {email_domains, [{<<"example.com">>, {<<"/">>, <<"email-in">>}} ]}, diff --git a/test/system_SUITE.erl b/test/system_SUITE.erl index 7912635..6905294 100644 --- a/test/system_SUITE.erl +++ b/test/system_SUITE.erl @@ -149,18 +149,18 @@ filter_email(Config, Filename, Expect) -> routing_key = <<"">>}), %% send an e-mail {ok, Email} = read_data_sample(Config, Filename), - ct:pal("Read a sample from ~s", [Filename]), + ct:pal("Read a sample from ~ts", [Filename]), Res = case gen_smtp_client:send_blocking({"whatever@example.com", ["test@example.com"], Email}, [{relay, "127.0.0.1"}, {port, 2525}, {username, "guest"}, {password, "guest"}]) of Answer when is_binary(Answer) -> % expect a delivery - ct:pal("SMTP server response: ~p, will wait for a delivery...", [Answer]), + ct:pal("SMTP server response: ~tp, will wait for a delivery...", [Answer]), wait_for_message(Ch, Queue, 500, Expect); {error, Reason} -> - ct:pal("SMTP server reported an error: ~p...", [Reason]), + ct:pal("SMTP server reported an error: ~tp...", [Reason]), expect_error(Reason, Expect); {error, _, Reason} -> - ct:pal("SMTP server reported an error: ~p...", [Reason]), + ct:pal("SMTP server reported an error: ~tp...", [Reason]), expect_error(Reason, Expect) end, rabbit_ct_client_helpers:close_channel(Ch), @@ -181,13 +181,13 @@ wait_for_message(Ch, Queue, Wait, Expect) -> expect(#'P_basic'{content_type = Expected}, {content_type, Expected}) -> true; expect(#'P_basic'{content_type = Received}, {content_type, Expected}) -> - ct:pal("Content-Type mismatch: expected ~s, received ~s", [Expected, Received]), + ct:pal("Content-Type mismatch: expected ~ts, received ~ts", [Expected, Received]), false; expect(#'P_basic'{headers = Headers}, {Header, undefined}) -> case lists:keyfind(Header, 1, Headers) of {_,_,Received} -> - ct:pal("~s not expected: received ~s", [Header, Received]), + ct:pal("~ts not expected: received ~ts", [Header, Received]), false; false -> true @@ -198,10 +198,10 @@ expect(#'P_basic'{headers = Headers}, {Header, Expected}) -> {_,_,Expected} -> true; {_,_,Received} -> - ct:pal("~s mismatch: expected ~s, received ~s", [Header, Expected, Received]), + ct:pal("~ts mismatch: expected ~ts, received ~ts", [Header, Expected, Received]), false; false -> - ct:pal("~s missing, expected ~s", [Header, Expected]), + ct:pal("~ts missing, expected ~ts", [Header, Expected]), false end; @@ -214,5 +214,5 @@ expect_error(_Reason, error) -> expect_error(_Reason, {error, _}) -> true; expect_error(Reason, Expected) -> - ct:pal("unexpected error, expected ~p, received ~p", [Expected, Reason]), + ct:pal("unexpected error, expected ~tp, received ~tp", [Expected, Reason]), false.