summaryrefslogtreecommitdiff
path: root/src/frontend.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend.erl')
-rw-r--r--src/frontend.erl102
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).