%%% Copyright (c) 2014, NORDUnet A/S. %%% See LICENSE for licensing information. %%% @doc Storage node API -module(storage). %% API (URL) -export([sendentry/3, entrycommitted/3, fetchnewentries/3]). newentries_path() -> {ok, Value} = application:get_env(plop, newentries_path), Value. 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), ok = index:addlast(newentries_path(), TreeLeafHash), binary_to_list( jiffy:encode( {[{result, <<"ok">>}]})) end), deliver(SessionID, R). entrycommitted(SessionID, _Env, Input) -> R = (catch case (catch jiffy:decode(Input)) of {error, E} -> html("entrycommitted: bad input:", E); {PropList} -> EntryHash = base64:decode(proplists:get_value(<<"entryhash">>, PropList)), LeafHash = base64:decode(proplists:get_value(<<"treeleafhash">>, PropList)), ok = db:add_entryhash(LeafHash, EntryHash), binary_to_list( jiffy:encode( {[{result, <<"ok">>}]})) end), deliver(SessionID, R). fetchnewhashes(Index) -> lists:reverse(fetchnewhashes(Index, [])). fetchnewhashes(Index, Acc) -> case index:get(newentries_path(), Index) of noentry -> Acc; Entry -> fetchnewhashes(Index + 1, [Entry | Acc]) end. fetchnewentries(SessionID, _Env, _Input) -> NewHashes = fetchnewhashes(0), Entries = lists:map(fun(LeafHash) -> {[{hash, base64:encode(LeafHash)}, {entry, base64:encode(db:entry_for_leafhash(LeafHash))}]} end, NewHashes), R = (catch binary_to_list( jiffy:encode( {[{result, <<"ok">>}, {entries, Entries}]}))), 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).