Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None
diff --git a/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl b/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl
index 6d9feaa..7f024ed 100644
--- a/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl
+++ b/apps/kolab_guam/src/rules/kolab_guam_rule_filter_groupware.erl
@@ -1,115 +1,129 @@
%% Copyright 2015 Kolab Systems AG (http://www.kolabsys.com)
%%
%% Aaron Seigo (Kolab Systems) <seigo a kolabsys.com>
%%
%% This program is free software: you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by
%% the Free Software Foundation, either version 3 of the License, or
%% (at your option) any later version.
%%
%% This program is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%% GNU General Public License for more details.
%%
%% You should have received a copy of the GNU General Public License
%% along with this program. If not, see <http://www.gnu.org/licenses/>.
-module(kolab_guam_rule_filter_groupware).
-export([new/1, applies/3, apply_to_client_message/2, apply_to_server_message/2]).
-behavior(kolab_guam_rule).
--record(state, { blacklist = [], active = false }).
+-record(state, { blacklist = [], tag = <<>>, active = false }).
new(_Config) -> #state { blacklist = [{ <<"Calendar">>, <<"Calendar/">> },
{ <<"Configuration">>, <<"Configuration/">> },
{ <<"Contacts">>, <<"Contacts/">> },
{ <<"Files">>, <<"Files/">> },
{ <<"Freebusy">>, <<"Freebusy/">> },
{ <<"Journal">>, <<"Journal/">> },
{ <<"Notes">>, <<"Notes/">> },
{ <<"Tasks">>, <<"Tasks/">> }] }.
+
applies(_ConnectionDetails, Buffer, State) ->
{ _Tag, Command, Data } = eimap_utils:split_command_into_components(Buffer),
%%lager:debug("********** Checking ...~n Socket: ~p~n Command: ~s ~s", [ConnectionDetails, Command, Data]),
{ apply_if_id_matches(Command, Data), State }.
+
apply_to_client_message(Buffer, State) ->
- { _Tag, Command, Data } = eimap_utils:split_command_into_components(Buffer),
- Active =
+ { Tag, Command, Data } = eimap_utils:split_command_into_components(Buffer),
+ { Active, StateTag }=
if Command =:= <<"LIST">>; Command =:= <<"list">>; Command =:= <<"XLIST">>; Command =:= <<"xlist">> ->
case binary:match(Data, <<"\"*\"">>) of
- nomatch -> false;
- _ -> true
+ nomatch -> { false, <<>> };
+ _ -> { true, Tag }
end;
- true -> false
+ true -> { false, <<>> }
end,
%lager:info("Client sent: ~s ~s ~p", [Command, Data, Active]),
- { Buffer, State#state{ active = Active } }.
+ { Buffer, State#state{ active = Active, tag = StateTag }}.
+
apply_to_server_message(Buffer, #state{ active = true } = State) ->
%lager:info("Server responded: ~p", [Buffer]),
filter_folders(Buffer, State);
apply_to_server_message(Buffer, State) -> { Buffer, State }.
%%PRIVATE
-apply_if_id_matches(<<"LIST">>, Data) ->
+apply_if_id_matches(<<"LIST">>, _Data) ->
true;
-apply_if_id_matches(<<"XLIST">>, Data) ->
+apply_if_id_matches(<<"XLIST">>, _Data) ->
true;
-apply_if_id_matches(<<"list">>, Data) ->
+apply_if_id_matches(<<"list">>, _Data) ->
true;
-apply_if_id_matches(<<"xlist">>, Data) ->
+apply_if_id_matches(<<"xlist">>, _Data) ->
true;
apply_if_id_matches(<<"ID">>, Data) ->
apply_if_found_kolab(binary:match(Data, <<"/Kolab">>));
apply_if_id_matches(_Command, _Data) -> notyet.
apply_if_found_kolab(nomatch) -> true;
apply_if_found_kolab(_) -> false.
filter_folders(Buffer, State) ->
ListResponses = binary:split(Buffer, <<"\r\n">>, [ global ]),
%io:format("Must filter out ... ~p~n", [ListResponses]),
- Response = filter_folders(State, ListResponses, <<>>),
+ { Response, More } = filter_folders(State, ListResponses, { <<>>, true }),
%io:format("Filtered ... ~p~n", [Response]),
- More = false,
{ Response, State#state { active = More } }.
-filter_folders(_State, [], Acc) -> Acc;
-filter_folders(State, [Unfiltered|Folders], Acc) -> filter_folders(State, Folders, filter_folder(State, Unfiltered, Acc)).
+filter_folders(_State, [], Return) -> Return;
+filter_folders(_State, _Folders, { Acc, false }) -> { <<Acc/binary, "\r\n">>, false };
+filter_folders(State, [Unfiltered|Folders], { Acc, _More }) -> filter_folders(State, Folders, filter_folder(State, Unfiltered, Acc)).
-filter_folder(State, <<"* LIST ", Details/binary>> = Response, Acc) -> filter_on_details(State, Response, Acc, Details);
-filter_folder(State, <<"* XLIST ", Details/binary>> = Response, Acc) -> filter_on_details(State, Response, Acc, Details);
-filter_folder(_State, Response, Acc) -> add_response(Response, Acc).
+filter_folder(State, <<>>, Acc) -> { Acc, true };
+filter_folder(State, <<"* LIST ", Details/binary>> = Response, Acc) -> { filter_on_details(State, Response, Acc, Details), true };
+filter_folder(State, <<"* XLIST ", Details/binary>> = Response, Acc) -> { filter_on_details(State, Response, Acc, Details), true };
+filter_folder(#state{ tag = Tag }, Response, Acc) ->
+ HasMore =
+ case byte_size(Tag) =< byte_size(Response) of
+ true ->
+ case binary:match(Response, Tag, [{ scope, { 0, byte_size(Tag) } }]) of
+ nomatch -> true;
+ _ -> false % we have found our closing tag!
+ end;
+ false -> true
+ end,
+ { add_response(Response, Acc), HasMore }.
filter_on_details(#state{ blacklist = Blacklist }, Response, Acc, Details) ->
%% first determine if we have a quoted item or a non-quoted item and start from there
DetailsSize = byte_size(Details),
{ Quoted, Start } = case binary:at(Details, DetailsSize - 1) of $" -> { quoted, DetailsSize - 2 }; _ -> { unquoted, DetailsSize - 1 } end,
Folder = find_folder_name(Details, Quoted, Start, Start, binary:at(Details, Start)),
%io:format("COMPARING ~p ??? ~p~n", [Folder, in_blacklist(Folder, Blacklist)]),
case in_blacklist(Folder, Blacklist) of
true -> Acc;
_ -> add_response(Response, Acc)
end.
find_folder_name(Details, quoted, End, Start, $") ->
binary:part(Details, Start + 1, End - Start);
find_folder_name(Details, unquoted, End, Start, $ ) ->
binary:part(Details, Start + 1, End - Start);
find_folder_name(Details, _Quoted, _End, 0, _) ->
Details;
find_folder_name(Details, Quoted, End, Start, _) ->
find_folder_name(Details, Quoted, End, Start - 1, binary:at(Details, Start - 1)).
add_response(Response, <<>>) -> Response;
add_response(Response, Acc) -> <<Acc/binary, "\r\n", Response/binary>>.
-in_blacklist(Folder, []) -> false;
+in_blacklist(_Folder, []) -> false;
in_blacklist(Folder, [{ Literal, Prefix }|List]) ->
case Literal == Folder of
true -> true;
_ -> case binary:match(Folder, Prefix) of
{ 0, _ } -> true;
_ -> in_blacklist(Folder, List)
end
end.

File Metadata

Mime Type
text/x-diff
Expires
Fri, Apr 24, 1:40 PM (2 d, 2 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18824440
Default Alt Text
(7 KB)

Event Timeline