n2o_proto.erl 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. -module(n2o_proto).
  2. -description('N2O Protocol WebSocket endpoint handler').
  3. -author('Maxim Sokhatsky').
  4. -include_lib("n4u/include/wf.hrl").
  5. -compile([export_all, nowarn_export_all]).
  6. formatter(O)-> case lists:keyfind(formatter,1,O) of {formatter,F} -> F; X -> X end.
  7. upack(D) -> binary_to_term(D,[safe]).
  8. protocols() -> wf:config(n2o,protocols,[ n2o_heart,
  9. n2o_nitrogen,
  10. n2o_file,
  11. n2o_client,
  12. n2o_http ]).
  13. terminate(_,#cx{module=Module}) -> catch Module:event(terminate).
  14. init(_Transport, Req, _Opts, _) ->
  15. wf:actions([]),
  16. Ctx = (wf:init_context(Req))#cx{formatter=formatter(_Opts)},
  17. NewCtx = wf:fold(init,Ctx#cx.handlers,Ctx),
  18. wf:context(NewCtx),
  19. wf:reg(broadcast,{wf:peer(Req)}),
  20. {Origin, _} = cowboy_req:header(<<"origin">>, Req, <<"*">>),
  21. ConfigOrigin = wf:to_binary(wf:config(n2o,origin,Origin)),
  22. wf:info(?MODULE,"Origin: ~p",[ConfigOrigin]),
  23. Req1 = wf:header(<<"Access-Control-Allow-Origin">>, ConfigOrigin, NewCtx#cx.req),
  24. {ok, Req1, NewCtx}.
  25. % N2O top level protocol NOP REPLY PUSH
  26. info(M,R,S) -> filter(M,R,S,protocols(),[]).
  27. stream({text,_}=M,R,S) -> filter(M,R,S,protocols(),[]);
  28. stream({binary,<<>>},R,S) -> nop(R,S);
  29. stream({binary,D},R,S) -> filter(upack(D),R,S,protocols(),[]);
  30. stream(_,R,S) -> nop(R,S).
  31. filter(M,R,S,Protos,Acc) -> case application:get_env(n2o,filter,{?MODULE,push}) of
  32. undefined -> push(M,R,S,Protos,Acc);
  33. {Mod,Fun} -> Mod:Fun(M,R,S,Protos,Acc) end.
  34. nop(R,S) -> {reply,<<>>,R,S}.
  35. reply(M,R,S) -> {reply,M,R,S}.
  36. push(_,R,S,[],_) -> nop(R,S);
  37. push(M,R,S,[H|T],Acc) ->
  38. case H:info(M,R,S) of
  39. {unknown,_,_,_} -> push(M,R,S,T,Acc);
  40. {reply,M1,R1,S1} -> reply(M1,R1,S1);
  41. A -> push(M,R,S,T,[A|Acc]) end.