diff options
Diffstat (limited to 'src/frontend.erl')
-rw-r--r-- | src/frontend.erl | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/frontend.erl b/src/frontend.erl new file mode 100644 index 0000000..8d0eccd --- /dev/null +++ b/src/frontend.erl @@ -0,0 +1,102 @@ +%%% Copyright (c) 2014, NORDUnet A/S. +%%% See LICENSE for licensing information. + +%%% @doc Frontend node API + +-module(frontend). +%% API (URL) +-export([sendlog/3, missingentries/3, sendentry/3, sendsth/3, currentposition/3]). + +sendentry(SessionID, _Env, Input) -> + R = (catch case (catch jiffy:decode(Input)) of + {error, E} -> + html("sendentry: bad input:", E); + {PropList} -> + LogEntry = base64:decode(proplists:get_value(<<"entry">>, PropList)), + TreeLeafHash = base64:decode(proplists:get_value(<<"treeleafhash">>, PropList)), + + ok = db:add(TreeLeafHash, LogEntry), + binary_to_list( + jiffy:encode( + {[{result, <<"ok">>}]})) + end), + deliver(SessionID, R). + +sendlog(SessionID, _Env, Input) -> + R = (catch case (catch jiffy:decode(Input)) of + {error, E} -> + html("sendentry: bad input:", E); + {PropList} -> + Start = proplists:get_value(<<"start">>, PropList), + Hashes = lists:map(fun (S) -> base64:decode(S) end, proplists:get_value(<<"hashes">>, PropList)), + + Indices = lists:seq(Start, Start + length(Hashes) - 1), + lists:foreach(fun ({Hash, Index}) -> + ok = db:add_index(Hash, Index) + end, lists:zip(Hashes, Indices)), + binary_to_list( + jiffy:encode( + {[{result, <<"ok">>}]})) + end), + deliver(SessionID, R). + +sendsth(SessionID, _Env, Input) -> + R = (catch case (catch jiffy:decode(Input)) of + {error, E} -> + html("sendentry: bad input:", E); + {PropList} -> + Treesize = proplists:get_value(<<"tree_size">>, PropList), + + ok = db:set_treesize(Treesize), + + ht:reset_tree([db:size() - 1]), + + binary_to_list( + jiffy:encode( + {[{result, <<"ok">>}]})) + end), + deliver(SessionID, R). + +currentposition(SessionID, _Env, _Input) -> + Size = db:size(), + R = binary_to_list( + jiffy:encode( + {[{result, <<"ok">>}, {position, Size}]})), + deliver(SessionID, R). + +fetchmissingentries(Index) -> + lists:reverse(fetchmissingentries(Index, [])). + +fetchmissingentries(Index, Acc) -> + case db:leafhash_for_index(Index) of + noentry -> + Acc; + Hash -> + case db:entry_for_leafhash(Hash) of + noentry -> + fetchmissingentries(Index + 1, [Hash | Acc]); + _ -> + fetchmissingentries(Index + 1, Acc) + end + end. + +missingentries(SessionID, _Env, _Input) -> + Size = db:size(), + Missing = fetchmissingentries(Size), + R = binary_to_list( + jiffy:encode( + {[{result, <<"ok">>}, {entries, Missing}]})), + deliver(SessionID, R). + +%% Private functions. +html(Text, Input) -> + io_lib:format( + "Content-Type: text/html\r\n\r\n" ++ + "<html><body><p>~n" ++ + "~s~n" ++ + "~p~n" ++ + "</body></html>~n", [Text, Input]). + +-spec deliver(any(), string()) -> ok | {error, _Reason}. +deliver(Session, Data) -> + mod_esi:deliver(Session, Data). |