%%% 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" ++ "

~n" ++ "~s~n" ++ "~p~n" ++ "~n", [Text, Input]). -spec deliver(any(), string()) -> ok | {error, _Reason}. deliver(Session, Data) -> mod_esi:deliver(Session, Data).