Page MenuHomePhorge

guam workaround for stalling client buffer (not fixing split and buffer handling)
Closed, ResolvedPublic

Description

Tried out guam 0.9.2 from kolab 16 for debian. Had problems connecting with some clients like claws mail (not kolab aware) or kolab notes for android (kolab aware).
It turned out buffer handling is faulty. I did write a simple patch which modifies buffer handling without touching repairing other things I do not understand (I'm simply _not_ an Erlang developer).

Details

Ticket Type
Task

Event Timeline

First I tried to branch guam like it's common on github (pull requests, you know...). I'm not allowed to do so so I opened a ticket^H^H... task. But it seems it's not possible to add files here either. So here it is:

--- kolab_guam_session.erl.ori      2017-12-01 12:30:06.981924214 +0100
+++ kolab_guam_session.erl     2017-12-01 12:16:28.302513953 +0100
@@ -195,25 +195,47 @@ process_client_data(Socket, Data, #state
             { TLS, Socket, NewInflator, NewDeflator, UndecidedRules, ActiveRules, <<>>, undefined, undefined };
         nochange ->
             %%lager:debug("... now applying rules"),
+            %lager:info("now applying rules..."),
             { ModifiedData, NewSplitCommand, NewSplitResetTrigger, NewUndecidedRules, NewActiveRules, PostAction } = apply_ruleset_clientside(ImapSession, Socket, PreprocessData, CurrentCommandSplit, UndecidedRules, ActiveRules),
             %%lager:info("The modified data is: ~s", [ModifiedData]),
             %lager:info("The post-processed data is: ~s", [PostProcessed]),
             BufferThisData =
             case PostAction of
                 perform_passthrough ->
+                    %lager:info("sending (no buffer): ~s", [ModifiedData]),
                     eimap:passthrough_data(ImapSession, ModifiedData),
                     <<>>;
                 buffer_data ->
-                    Data
+                    %Data
+                    % Originally Aaron uses Data here, but later on this buffer is assumed to be
+                    % already decoded, so we do have to use PreprocessData here, I think.
+                    case binary:matches(PreprocessData, <<"\r\n">>) of
+                        [] -> 
+                            %lager:info("buffering: ~s", [PreprocessData]),
+                            PreprocessData;
+                        List ->
+                            {FoundPos, _} = lists:last(List),
+                            % I would like to have some binary:match for the last instead of the
+                            % first occurrence; but I'm really inexperienced in erlang so I don't 
+                            % know how to solve this efficient, so I'm using binary:matches with
+                            % using the last element only
+                            SplitPos = FoundPos + 2,
+                            eimap:passthrough_data(ImapSession, binary:part(PreprocessData, 0, SplitPos)),
+                            %lager:info("sending first part: ~s", [binary:part(PreprocessData, 0, SplitPos)] ),
+                            %lager:info("buffering second part: ~s", [binary:part(PreprocessData, SplitPos, size(PreprocessData)-SplitPos)]),
+                            binary:part(PreprocessData, SplitPos, size(PreprocessData)-SplitPos)
+                    end
             end,
             { TLS, Socket, Inflator, Deflator, NewUndecidedRules, NewActiveRules, BufferThisData, NewSplitCommand, NewSplitResetTrigger }
     end,
     set_socket_active(TLSActive, CurrentSocket),
-    PrevBuffered = State#state.buffered_client_data,
+    %buffered_client_data is already in DataToBuffer via preprocess_client_data
+    %PrevBuffered = State#state.buffered_client_data,
     { noreply, State#state{ rules_deciding = CurrentUndecidedRules, rules_active = CurrentActiveRules,
                             socket = CurrentSocket, client_tls_active = TLSActive,
                             inflator = CurrentInflator, deflator = CurrentDeflator,
-                            buffered_client_data = <<PrevBuffered/binary, DataToBuffer/binary>>,
+                            %buffered_client_data = <<PrevBuffered/binary, DataToBuffer/binary>>,
+                            buffered_client_data = <<DataToBuffer/binary>>,
                             current_command_split = SplitCommand,
                             command_split_reset_trigger = SplitResetTrigger } }.
 
@@ -261,7 +283,7 @@ apply_next_rule_serverside(ImapSession,
     apply_next_rule_serverside(ImapSession, ModifiedData, [{ Module, ModifiedRuleState } | ActiveRulesAcc], ActiveRules).
 
 apply_ruleset_clientside(_ImapSession, _Socket, ClientData, _CurrentCommandSplit, [], []) ->
-    { ClientData, [], [], [], [], perform_passthrough };
+    { ClientData, undefined, [], [], [], perform_passthrough }; 
 apply_ruleset_clientside(ImapSession, Socket, ClientData, CurrentCommandSplit, UndecidedRules, CurrentlyActiveRules) ->
     { PostAction, SplitCommand, SplitResetTrigger } =
         case CurrentCommandSplit of
mollekopf claimed this task.
mollekopf subscribed.

Available since 0.9.5.