Projects
Kolab:16:Enterprise
guam
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 42
View file
guam.spec
Changed
@@ -18,7 +18,7 @@ %define lock_version() %{1}%{?_isa} = %(rpm -q --queryformat "%%{VERSION}" %{1}) Name: guam -Version: 0.9.7 +Version: 0.9.8 Release: 1%{?dist} Summary: A Smart Reverse IMAP Proxy @@ -225,8 +225,11 @@ %changelog +* Mon Oct 26 2020 Christian Mollekopf <mollekopf@kolabsys.com> - 0.9.8-1 +- Release of version 0.9.8 + * Wed Apr 15 2020 Christian Mollekopf <mollekopf@kolabsys.com> - 0.9.7-1 -- Release of version 0.9.6 +- Release of version 0.9.7 * Tue Mar 31 2020 Christian Mollekopf <mollekopf@kolabsys.com> - 0.9.6-1 - Release of version 0.9.6
View file
debian.changelog
Changed
@@ -1,3 +1,9 @@ +guam (0.9.8-1) unstable; urgency=medium + + * Release of version 0.9.8 + + -- Christian Mollekopf (Kolab Systems) <mollekopf@kolabsys.com> Mon, 26 Oct 2020 09:31:31 +0200 + guam (0.9.7-3) unstable; urgency=medium * Updated debian/postinst script
View file
guam-0.9.7.tar.gz/CHANGELOG.md -> guam-0.9.8.tar.gz/CHANGELOG.md
Changed
@@ -11,10 +11,18 @@ ### Fixed ### Security +## 0.9.8 - 2020-10-26 +### Added +### Fixed +- Fixed performance regression with literals containing CRLFs. +- Avoid buffering entire literal continuations + ## 0.9.7 - 2020-04-15 ### Added ### Fixed - Fixed processing of multiple commands arriving in the same packet. +- Enable keepalive on incoming socket +- Enabled full IMAP traffic logging on debug log level ## 0.9.6 - 2020-03-31 ### Added
View file
guam-0.9.7.tar.gz/apps/kolab_guam/src/kolab_guam.app.src -> guam-0.9.8.tar.gz/apps/kolab_guam/src/kolab_guam.app.src
Changed
@@ -2,7 +2,7 @@ {application, kolab_guam, {description, "IMAP session proxy"}, - {vsn, "0.9.7"}, + {vsn, "0.9.8"}, {registered, }, {applications, kernel,
View file
guam-0.9.7.tar.gz/apps/kolab_guam/src/kolab_guam_session.erl -> guam-0.9.8.tar.gz/apps/kolab_guam/src/kolab_guam_session.erl
Changed
@@ -25,6 +25,8 @@ %% gen_server callbacks -export(init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3). +%% tests +-export( process_client_data/3 ). -include("kolab_guam_session.hrl"). @@ -67,11 +69,19 @@ %lager:debug("Socket error"), { stop, normal, State }; handle_info({ tcp, Socket, Data }, #state{ client_tls_active = false } = State) -> - %lager:debug("Data coming in from client over TCP ~s", Data), - process_client_data(Socket, Data, State); + % lager:debug("Data coming in from client over TCP ~s", Data), + {Acc, NewState} = process_client_data(Socket, Data, State), + forward_literal_data(Acc, NewState), + inet:setopts(Socket, { active, once }), + { noreply, NewState }; + handle_info({ ssl, Socket, Data }, State) -> - %lager:debug("Data coming in from client over SSL, ~p", Data), - process_client_data(Socket, Data, State); + % lager:debug("Data coming in from client over SSL, ~p", Data), + {Acc, NewState} = process_client_data(Socket, Data, State), + forward_literal_data(Acc, NewState), + ssl:setopts(Socket, { active, once }), + { noreply, NewState }; + handle_info({ server_hello, ServerHello }, #state{ imap_session = ImapSession, tls_config = TLSConfig, socket = Socket, client_implicit_tls = ImplicitTLS, client_tls_active = TLSActive, deflator = Deflator } = State) -> CorrectedHello = correct_hello(TLSActive, ImplicitTLS, TLSConfig, ServerHello), ServerIdent = proplists:get_value(server_id, ServerHello, <<>>), @@ -146,6 +156,22 @@ update_split_command_state(_Data, _State) -> undefined. +update_split_command_state_client(ClientDataComponents, #state{ command_split_reset_trigger = reset_for_next_client_command, current_command_split = CurrentCommandSplit }) -> + %If we have a currently active command (CurrentCommandSplit), then we reset only if we find a new command (and not just on any new line). + %This is relevant for multi-line commands such as APPEND, which follow up with a continuation which we want to avoid buffering. + case CurrentCommandSplit of + undefined -> undefined; + _ -> + case ClientDataComponents of + { <<>>, <<>>, <<>> } -> CurrentCommandSplit; + { _Tag, <<>>, <<>> } -> CurrentCommandSplit; + { <<>>, _Command, <<>> } -> CurrentCommandSplit; + { _Tag, _Command, _Data } -> undefined + end + end; +update_split_command_state_client(_ClientDataComponents, _State) -> + undefined. + accept_client(#state{ client_implicit_tls = true, tls_config = TLSConfig, listen_socket = ListenSocket, super_pid = SupervisorPID }) -> AcceptSocket = accept_socket(ListenSocket, SupervisorPID), %% prep for the next listen @@ -175,72 +201,84 @@ close_socket(_ImplicitTLS, _TLS, Socket) -> gen_tcp:close(Socket). -read_line(Data) -> - case binary:match(Data, <<"\r\n">>) of - nomatch -> - {Data, <<>>}; - {SplitPos, SplitSize} -> - {binary:part(Data, 0, SplitPos + SplitSize), binary:part(Data, SplitPos + SplitSize, size(Data)-(SplitPos + SplitSize))} - end. - - -process_preprocessed_client_data(Socket, PreprocessData, #state{ command_split_reset_trigger = CurrentCommandSplitResetTrigger, current_command_split = CurrentCommandSplit } = State) -> - NewSplitCommand = case CurrentCommandSplitResetTrigger of - reset_for_next_client_command -> undefined; - _ -> CurrentCommandSplit - end, - - % TODO Maybe we should prepend buffered data here instead. - {Line, Remainder} = read_line(PreprocessData), - NewState = process_client_line(Line, Socket, State#state{ current_command_split = NewSplitCommand }), - +forward_literal_data(<<>>, _State) -> + {}; +forward_literal_data(Data, #state{imap_session = ImapSession} = _State) -> + eimap:passthrough_data(ImapSession, Data). + +process_lines(_Socket, State, , ContinuationBytes, Acc) -> + {Acc, State#state{ continuation_bytes = ContinuationBytes }}; +process_lines(Socket, State, Line|MoreLines, 0, Acc) -> + { _StrippedNextLine, NextContinuationBytes } = eimap_utils:num_literal_continuation_bytes(binary:part(Line, 0, byte_size(Line)-2)), + {NewAcc, NewState} = process_client_line(Line, Socket, State, Acc), + process_lines(Socket, NewState, MoreLines, NextContinuationBytes, NewAcc); +process_lines(Socket, State, Line|MoreLines, ContinuationBytes, Acc) -> + {LiteralPartOfLine, Remainder} = split_binary(Line, min(ContinuationBytes, size(Line))), + Lines = case Remainder of - <<>> -> NewState; - _ -> process_preprocessed_client_data(Socket, Remainder, NewState) - end. - + <<>> -> MoreLines; + _ -> Remainder|MoreLines + end, + process_lines(Socket, State, Lines, ContinuationBytes - size(LiteralPartOfLine), <<Acc/binary, LiteralPartOfLine/binary>>). + +split(Lines, Data, Pattern) -> + case binary:match(Data, Pattern) of + nomatch -> {lists:reverse(Lines), Data}; + { Start, Length } -> + Num = Start + Length, + <<Line:Num/binary, Remainder/binary>> = Data, + split(Line|Lines, Remainder, Pattern) + end. +split(Lines, Data) -> + split(Lines, Data, binary:compile_pattern(<<"\r\n">>)). + +split_lines(Data) -> + split(, Data). % Client data is processed as it comes in, but split up by lines if more than one line comes in at a time. -% The processing interanly buffers data as necessary if it encounters incomplete lines. -process_client_data(Socket, Data, #state{ inflator = Inflator } = State) -> +% The processing internally buffers data as necessary if it encounters incomplete lines. +process_client_data(Socket, Data, #state{ inflator = Inflator, continuation_bytes = ContinuationBytes } = State) -> % TODO: refactor so starttls and compress commands can be made into rules PreprocessData = preprocess_client_data(Inflator, Data, State), lager:debug("FROM CLIENT: ~p", PreprocessData), - { noreply, process_preprocessed_client_data(Socket, PreprocessData, State) }. + {Lines, NewLastPartialLine} = split_lines(PreprocessData), + {Acc, NewState} = process_lines(Socket, State#state{ buffered_client_data = <<>> }, Lines, ContinuationBytes, <<>>), + #state{ buffered_client_data = DataToBuffer, continuation_bytes = NewContinuationBytes} = NewState, + + NewBuffer = <<DataToBuffer/binary, NewLastPartialLine/binary>>, + %If we are inside a continuation, forward up to NewContinuationBytes + {LiteralPartOfBuffer, NonLiteralPart} = split_binary(NewBuffer, min(NewContinuationBytes, size(NewBuffer))), -process_client_line(Data, Socket, #state{ rules_deciding = UndecidedRules, tls_config = TLSConfig, client_tls_active = TLS, rules_active = ActiveRules, socket = Socket, imap_session = ImapSession, inflator = Inflator, deflator = Deflator, server_config = ServerConfig, current_command_split = CurrentCommandSplit } = State) -> - { TLSActive, CurrentSocket, CurrentInflator, CurrentDeflator, CurrentUndecidedRules, CurrentActiveRules, DataToBuffer, SplitCommand, SplitResetTrigger } = - case check_for_transmission_change_commands(TLS, TLSConfig, Data, Deflator, Socket) of + {<<Acc/binary, LiteralPartOfBuffer/binary>>, NewState#state{ buffered_client_data = NonLiteralPart, continuation_bytes = NewContinuationBytes - size(LiteralPartOfBuffer)}}. + + +process_client_line(Data, Socket, #state{ rules_deciding = UndecidedRules, tls_config = TLSConfig, client_tls_active = TLS, rules_active = ActiveRules, socket = Socket, imap_session = ImapSession, deflator = Deflator, server_config = ServerConfig} = State, Acc) -> + ClientDataComponents = eimap_utils:split_command_into_components(Data), + case check_for_transmission_change_commands(TLS, TLSConfig, ClientDataComponents, Deflator, Socket) of { socket_upgraded, SSLSocket } -> %% if we have upgraded our socket, then do so to the backend if that hasn't happened auomatically case proplists:get_value(implicit_tls, ServerConfig, false) of false -> eimap:starttls(ImapSession, undefined, undefined); _ -> ok end, - { true, SSLSocket, Inflator, Deflator, UndecidedRules, ActiveRules, <<>>, undefined, undefined }; + { Acc, State#state{ client_tls_active = true, socket = SSLSocket, buffered_client_data = <<>>, current_command_split = undefined, command_split_reset_trigger = undefined } }; { compression, NewInflator, NewDeflator } -> eimap:compress(ImapSession), % TODO: make optional - { TLS, Socket, NewInflator, NewDeflator, UndecidedRules, ActiveRules, <<>>, undefined, undefined }; + { Acc, State#state{ inflator = NewInflator, deflator = NewDeflator, buffered_client_data = <<>>, current_command_split = undefined, command_split_reset_trigger = undefined } }; nochange -> - { ModifiedData, NewSplitCommand, NewSplitResetTrigger, NewUndecidedRules, NewActiveRules, PostAction } = apply_ruleset_clientside(ImapSession, Socket, Data, CurrentCommandSplit, UndecidedRules, ActiveRules), - BufferThisData = + %We first check if we have to reset the split command before we process the new command in apply_ruleset_clientside + NewSplit = update_split_command_state_client(ClientDataComponents, State), + { ModifiedData, NewSplitCommand, NewSplitResetTrigger, NewUndecidedRules, NewActiveRules, PostAction } = apply_ruleset_clientside(ImapSession, Socket, Data, ClientDataComponents, NewSplit, UndecidedRules, ActiveRules), + { SendThisData, BufferThisData } = case PostAction of perform_passthrough -> - eimap:passthrough_data(ImapSession, ModifiedData), - <<>>; + {ModifiedData, <<>>}; buffer_data -> - Data + {<<>>, Data} end, - { TLS, Socket, Inflator, Deflator, NewUndecidedRules, NewActiveRules, BufferThisData, NewSplitCommand, NewSplitResetTrigger } - end, - set_socket_active(TLSActive, CurrentSocket), - State#state{ rules_deciding = CurrentUndecidedRules, rules_active = CurrentActiveRules, - socket = CurrentSocket, client_tls_active = TLSActive, - inflator = CurrentInflator, deflator = CurrentDeflator, - buffered_client_data = DataToBuffer, - current_command_split = SplitCommand, - command_split_reset_trigger = SplitResetTrigger }. + { <<Acc/binary, SendThisData/binary>>, State#state{ rules_deciding = NewUndecidedRules, rules_active = NewActiveRules, buffered_client_data = BufferThisData, current_command_split = NewSplitCommand, command_split_reset_trigger = NewSplitResetTrigger } } + end. preprocess_client_data(undefined, Data, #state{ buffered_client_data = Buffered }) -> <<Buffered/binary, Data/binary>>; @@ -282,13 +320,13 @@ { ModifiedData, ModifiedRuleState } = Module:apply_to_server_message(ImapSession, ServerData, RuleState), apply_next_rule_serverside(ImapSession, ModifiedData, { Module, ModifiedRuleState } | ActiveRulesAcc, ActiveRules). -apply_ruleset_clientside(_ImapSession, _Socket, ClientData, _CurrentCommandSplit, , ) -> +apply_ruleset_clientside(_ImapSession, _Socket, ClientData, _ClientDataComponents, _CurrentCommandSplit, , ) -> { ClientData, undefined, , , , perform_passthrough }; -apply_ruleset_clientside(ImapSession, Socket, ClientData, CurrentCommandSplit, UndecidedRules, CurrentlyActiveRules) -> +apply_ruleset_clientside(ImapSession, Socket, ClientData, ClientDataComponents, CurrentCommandSplit, UndecidedRules, CurrentlyActiveRules) -> { PostAction, SplitCommand, SplitResetTrigger } = case CurrentCommandSplit of undefined -> - case eimap_utils:split_command_into_components(ClientData) of + case ClientDataComponents of
View file
guam-0.9.7.tar.gz/apps/kolab_guam/src/kolab_guam_session.hrl -> guam-0.9.8.tar.gz/apps/kolab_guam/src/kolab_guam_session.hrl
Changed
@@ -1,4 +1,4 @@ -record(state, { listen_socket, socket = undefined, super_pid, tls_config = , client_implicit_tls = false, client_tls_active = false, server_config = , rules_active = , rules_deciding = , imap_session = undefined, inflator = undefined, deflator = undefined, buffered_client_data = <<>>, - current_command_split = undefined, command_split_reset_trigger = reset_for_next_client_command }). + current_command_split = undefined, command_split_reset_trigger = reset_for_next_client_command, continuation_bytes = 0}).
View file
guam-0.9.7.tar.gz/apps/kolab_guam/test/kolab_guam_session_SUITE.erl -> guam-0.9.8.tar.gz/apps/kolab_guam/test/kolab_guam_session_SUITE.erl
Changed
@@ -31,7 +31,9 @@ % Specify a list of all unit test functions all() -> - kolab_guam_session_test + kolab_guam_session_test_client, + kolab_guam_session_test_server, + kolab_guam_session_test_client_benchmark . % required, but can just return Config. this is a suite level setup function. @@ -53,7 +55,7 @@ Config. -kolab_guam_session_test(_TestConfig) -> +kolab_guam_session_test_client(_TestConfig) -> %% setup boilerplate ServerConfig = kolab_guam_sup:default_imap_server_config(), { ok, ImapSession } = eimap:start_link(ServerConfig), @@ -70,8 +72,7 @@ imap_session = ImapSession }, - - % Run without rules + %handle_info {noreply, #state{ server_config = ServerConfig, buffered_client_data = <<>>, @@ -79,67 +80,130 @@ command_split_reset_trigger = %FIXME ? }} = kolab_guam_session:handle_info({tcp, Socket, <<"y1 ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\ny3 LIST \"\" \"%\" RETURN (SUBSCRIBED))\r\n">>}, State#state{ rules_deciding = }), + % Run without rules + {<<"y1 ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\ny3 LIST \"\" \"%\" RETURN (SUBSCRIBED))\r\n">>, #state{ + server_config = ServerConfig, + buffered_client_data = <<>>, + current_command_split = undefined, + command_split_reset_trigger = %FIXME ? + }} = kolab_guam_session:process_client_data(Socket, <<"y1 ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\ny3 LIST \"\" \"%\" RETURN (SUBSCRIBED))\r\n">>, State#state{ rules_deciding = }), + % Activate filtering - {noreply, #state{ + {<<"y1 ID (\"name\" \"Test\")\r\n">>, #state{ server_config = ServerConfig, buffered_client_data = <<>>, current_command_split = {<<"y1">>,<<"ID">>,<<"(\"name\" \"Test\")">>}, command_split_reset_trigger = reset_for_next_client_command, rules_deciding = , rules_active = {kolab_guam_rule_filter_groupware, _} - }} = kolab_guam_session:handle_info({tcp, Socket, <<"y1 ID (\"name\" \"Test\")\r\n">>}, State#state{ rules_deciding = ActiveRules }), + }} = kolab_guam_session:process_client_data(Socket, <<"y1 ID (\"name\" \"Test\")\r\n">>, State#state{ rules_deciding = ActiveRules }), + + + % Append + {<<"y1 APPEND INBOX {30}\r\n0123">>, #state{ + server_config = ServerConfig, + buffered_client_data = <<>>, + current_command_split = {<<"y1">>,<<"APPEND">>,<<"INBOX {30}">>}, + command_split_reset_trigger = reset_for_next_client_command + } = IntermediateState4} = kolab_guam_session:process_client_data(Socket, <<"y1 APPEND INBOX {30}\r\n0123">>, State#state{ rules_deciding = ActiveRules }), + + {<<"456789">>, #state{ + server_config = ServerConfig, + buffered_client_data = <<>>, %This ensures we aren't buffering during the continuation + current_command_split = {<<"y1">>,<<"APPEND">>,<<"INBOX {30}">>}, + command_split_reset_trigger = reset_for_next_client_command + } = IntermediateState5} = kolab_guam_session:process_client_data(Socket, <<"456789">>, IntermediateState4), + + {<<"0123456789012345678">>, #state{ + server_config = ServerConfig, + buffered_client_data = <<>>, %This ensures we aren't buffering during the continuation + current_command_split = {<<"y1">>,<<"APPEND">>,<<"INBOX {30}">>}, + command_split_reset_trigger = reset_for_next_client_command + } = IntermediateState6} = kolab_guam_session:process_client_data(Socket, <<"0123456789012345678">>, IntermediateState5), + + {<<"9\r\ny2 ENABLE QRESYNC\r\n">>, #state{ + server_config = ServerConfig, + buffered_client_data = <<>>, + current_command_split = {<<"y2">>,<<"ENABLE">>,<<"QRESYNC">>}, + command_split_reset_trigger = reset_for_next_client_command + }} = kolab_guam_session:process_client_data(Socket, <<"9\r\ny2 ENABLE QRESYNC\r\n">>, IntermediateState6), + + % Append2 + {<<"y1 APPEND INBOX {36}\r\n0123">>, #state{ + server_config = ServerConfig, + buffered_client_data = <<>>, + current_command_split = {<<"y1">>,<<"APPEND">>,<<"INBOX {36}">>}, + command_split_reset_trigger = reset_for_next_client_command, + continuation_bytes = 32 + } = IntermediateState7} = kolab_guam_session:process_client_data(Socket, <<"y1 APPEND INBOX {36}\r\n0123">>, State#state{ rules_deciding = ActiveRules }), + + {<<"456789\r\n0123456789\r\n0123456789">>, #state{ + server_config = ServerConfig, + buffered_client_data = <<>>, %This ensures we aren't buffering during the continuation + current_command_split = {<<"y1">>,<<"APPEND">>,<<"INBOX {36}">>}, + command_split_reset_trigger = reset_for_next_client_command, + continuation_bytes = 2 + } = IntermediateState8} = kolab_guam_session:process_client_data(Socket, <<"456789\r\n0123456789\r\n0123456789">>, IntermediateState7), + + {<<"\r\n">>, #state{ + server_config = ServerConfig, + buffered_client_data = <<>>, %This ensures we aren't buffering during the continuation + current_command_split = {<<"y1">>,<<"APPEND">>,<<"INBOX {36}">>}, + command_split_reset_trigger = reset_for_next_client_command, + continuation_bytes = 0 + }} = kolab_guam_session:process_client_data(Socket, <<"\r\n">>, IntermediateState8), % Don't activate filtering - {noreply, #state{ + {<<"y1 ID (\"name\" \"Test/KOLAB\")\r\n">>, #state{ server_config = ServerConfig, buffered_client_data = <<>>, current_command_split = {<<"y1">>,<<"ID">>,<<"(\"name\" \"Test/KOLAB\")">>}, command_split_reset_trigger = reset_for_next_client_command, rules_deciding = , rules_active = - }} = kolab_guam_session:handle_info({tcp, Socket, <<"y1 ID (\"name\" \"Test/KOLAB\")\r\n">>}, State#state{ rules_deciding = ActiveRules }), + }} = kolab_guam_session:process_client_data(Socket, <<"y1 ID (\"name\" \"Test/KOLAB\")\r\n">>, State#state{ rules_deciding = ActiveRules }), % Lone tag in a packet. Can/Could happen with iPhone apparently. (See commit 89f9dc93757c68032ed17f42838858bdfaefa408) - {noreply, #state{ buffered_client_data = <<"y1">>, rules_active = } = IntermediateState1} = kolab_guam_session:handle_info({tcp, Socket, <<"y1">>}, State#state{ rules_deciding = ActiveRules }), - {noreply, #state{ + {<<>>, #state{ buffered_client_data = <<"y1">>, rules_active = } = IntermediateState1} = kolab_guam_session:process_client_data(Socket, <<"y1">>, State#state{ rules_deciding = ActiveRules }), + {<<"y1 ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\n">>, #state{ server_config = ServerConfig, buffered_client_data = <<>>, current_command_split = {<<"y2">>,<<"ENABLE">>,<<"QRESYNC">>}, command_split_reset_trigger = reset_for_next_client_command, rules_deciding = , rules_active = {kolab_guam_rule_filter_groupware, _} - }} = kolab_guam_session:handle_info({tcp, Socket, <<" ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\n">>}, IntermediateState1), + }} = kolab_guam_session:process_client_data(Socket, <<" ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\n">>, IntermediateState1), % Lone tag in a packet, but with a \r\n before. See guam-0.9.2-stalling-client-buffer-and-split-command-handling.patch (This triggers the odd List buffering case) - {noreply, #state{ buffered_client_data = <<"y1 ">>, rules_active = } = IntermediateState2} = kolab_guam_session:handle_info({tcp, Socket, <<"\r\ny1 ">>}, State#state{ rules_deciding = ActiveRules }), - {noreply, #state{ + {<<"\r\n">>, #state{ buffered_client_data = <<"y1 ">>, rules_active = } = IntermediateState2} = kolab_guam_session:process_client_data(Socket, <<"\r\ny1 ">>, State#state{ rules_deciding = ActiveRules }), + {<<"y1 ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\n">>, #state{ server_config = ServerConfig, buffered_client_data = <<>>, current_command_split = {<<"y2">>,<<"ENABLE">>,<<"QRESYNC">>}, command_split_reset_trigger = reset_for_next_client_command, rules_deciding = , rules_active = {kolab_guam_rule_filter_groupware, _} - }} = kolab_guam_session:handle_info({tcp, Socket, <<"ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\n">>}, IntermediateState2), + }} = kolab_guam_session:process_client_data(Socket, <<"ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\n">>, IntermediateState2), % Empty line (should be considered a complete command and should not be buffered) - {noreply, #state{ buffered_client_data = <<>>, rules_active = } = IntermediateState3} = kolab_guam_session:handle_info({tcp, Socket, <<"\r\n">>}, State#state{ rules_deciding = ActiveRules }), - {noreply, #state{ + {<<"\r\n">>, #state{ buffered_client_data = <<>>, rules_active = } = IntermediateState3} = kolab_guam_session:process_client_data(Socket, <<"\r\n">>, State#state{ rules_deciding = ActiveRules }), + {<<"y1 ID (\"name\" \"Test\")\r\n">>, #state{ server_config = ServerConfig, buffered_client_data = <<>>, current_command_split = {<<"y1">>,<<"ID">>,<<"(\"name\" \"Test\")">>}, command_split_reset_trigger = reset_for_next_client_command, rules_deciding = , rules_active = {kolab_guam_rule_filter_groupware, _} - }} = kolab_guam_session:handle_info({tcp, Socket, <<"y1 ID (\"name\" \"Test\")\r\n">>}, IntermediateState3), + }} = kolab_guam_session:process_client_data(Socket, <<"y1 ID (\"name\" \"Test\")\r\n">>, IntermediateState3), % Activate with multi-line packet - {noreply, #state{ + {<<"y1 ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\ny3 LIST \"\" \"%\" RETURN (SUBSCRIBED))\r\n">>, #state{ server_config = ServerConfig, buffered_client_data = <<>>, current_command_split = {<<"y3">>,<<"LIST">>,<<"\"\" \"%\" RETURN (SUBSCRIBED))">>}, @@ -148,7 +212,7 @@ % Make sure that we have processed y3 in here (and don't stop processing at y1) rules_active = {kolab_guam_rule_filter_groupware, {state,undefined,<<"y3">>,true,<<>>,<<"LIST">>,<<"list">>,<<"XLIST">>,<<"xlist">>,<<"LSUB">>,<<"lsub">>}} % rules_active = {kolab_guam_rule_filter_groupware, _} - }} = kolab_guam_session:handle_info({tcp, Socket, <<"y1 ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\ny3 LIST \"\" \"%\" RETURN (SUBSCRIBED))\r\n">>}, State#state{ rules_deciding = ActiveRules }), + }} = kolab_guam_session:process_client_data(Socket, <<"y1 ID (\"name\" \"Test\")\r\ny2 ENABLE QRESYNC\r\ny3 LIST \"\" \"%\" RETURN (SUBSCRIBED))\r\n">>, State#state{ rules_deciding = ActiveRules }), % Test various packet splits @@ -185,3 +249,122 @@ end, State, Packets). + + +kolab_guam_session_test_server(_TestConfig) -> + %% setup boilerplate + % gen_tcp:connect + ServerConfig = kolab_guam_sup:default_imap_server_config(), + { ok, ImapSession } = eimap:start_link(ServerConfig), + { ok, Socket } = gen_tcp:listen(9964, { reuseaddr, true }, {active, false}, inet6 ), + + lager:start(), + lager:set_loglevel(lager_console_backend, debug), +
View file
guam-0.9.7.tar.gz/rebar.config -> guam-0.9.8.tar.gz/rebar.config
Changed
@@ -23,7 +23,7 @@ { eunit_opts, verbose, {skip_deps, true } }. { eunit_exclude_deps, true }. { cover_enabled, true }. -{ relx, { release, { guam, "0.9.7" }, kolab_guam}, +{ relx, { release, { guam, "0.9.8" }, kolab_guam}, { dev_mode, false }, { include_erts, false }, { extended_start_script, true },
View file
guam.dsc
Changed
@@ -2,7 +2,7 @@ Source: guam Binary: guam Architecture: any -Version: 0.9.7-3 +Version: 0.9.8-1 Maintainer: Christoph Erhardt <kolab@sicherha.de> Homepage: https://kolab.org/about/guam Standards-Version: 3.9.6 @@ -10,5 +10,5 @@ Package-List: guam deb mail extra Files: - 00000000000000000000000000000000 0 guam-0.9.7.tar.gz + 00000000000000000000000000000000 0 guam-0.9.8.tar.gz 00000000000000000000000000000000 0 debian.tar.gz
View file
plesk.sys.config
Changed
@@ -160,7 +160,7 @@ lager, { handlers, - { lager_console_backend, debug }, + { lager_console_backend, info }, { lager_file_backend, { file, "log/error.log"}, { level, error } }, { lager_file_backend, { file, "log/console.log"}, { level, info } }
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.