Packages
nova
0.9.5
0.15.1
0.14.3
0.14.1
0.13.7
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.24
0.9.23
0.9.22
0.9.21
0.9.20
0.9.19
0.9.18
0.9.17
0.9.16
0.9.15
0.9.11
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.4.4
0.4.3
0.4.2
0.4.1
0.2.2
0.1.0
0.0.1
0.0.0
Nova is a web application framework
Current section
Files
Jump to
Current section
Files
src/plugins/nova_request_plugin.erl
-module(nova_request_plugin).
-behaviour(nova_plugin).
-export([
pre_request/2,
post_request/2,
plugin_info/0
]).
%%--------------------------------------------------------------------
%% @doc
%% Pre-request callback
%% @end
%%--------------------------------------------------------------------
-spec pre_request(Req :: cowboy_req:req(), Options :: map()) ->
{ok, Req0 :: cowboy_req:req()}.
pre_request(Req, Options) ->
Options0 = nova_plugin_utilities:parse_options(Options),
%% Read the body and put it into the Req object
Req0 = read_body(Req),
{ok, _Req1} = modulate_state(Req0, Options0).
%%--------------------------------------------------------------------
%% @doc
%% Post-request callback
%% @end
%%--------------------------------------------------------------------
-spec post_request(Req :: cowboy_req:req(), Options :: map()) ->
{ok, Req0 :: cowboy_req:req()}.
post_request(Req, _Options) ->
{ok, Req}.
%%--------------------------------------------------------------------
%% @doc
%% nova_plugin callback. Returns information about the plugin.
%% @end
%%--------------------------------------------------------------------
-spec plugin_info() -> {Title :: binary(),
Version :: binary(),
Author :: binary(),
Description :: binary(),
Options :: [{Key :: atom(), OptionDescription :: binary()}]}.
plugin_info() ->
{<<"Nova body plugin">>,
<<"0.0.1">>,
<<"Nova team <info@novaframework.org">>,
<<"This plugin modulates the body of a request.">>,
[
{parse_bindings, <<"Used to parse bindings and put them in state under `bindings` key">>},
{decode_json_body, <<"Decodes the body as JSON and puts it under `json`">>},
{parse_qs, <<"Used to parse qs and put hem in state under `qs` key">>}
]}.
%%%%%%%%%%%%%%%%%%%%%%
%% Private functions
%%%%%%%%%%%%%%%%%%%%%%
modulate_state(Req, []) ->
{ok, Req};
modulate_state(Req = #{headers := #{<<"content-type">> := <<"application/json", _/binary>>}, body := Body}, [decode_json_body|Tl]) ->
%% Decode the data
JsonLib = nova:get_env(json_lib, thoas),
case erlang:apply(JsonLib, decode, [Body]) of
{ok, JSON} ->
modulate_state(Req#{json => JSON}, Tl);
Error ->
Req400 = cowboy_req:reply(400, Req),
logger:warning(#{status_code => 400,
msg => "Failed to decode json.",
error => Error}),
{stop, Req400}
end;
modulate_state(#{headers := #{<<"content-type">> := <<"application/x-www-form-urlencoded", _/binary>>}, body := Body} = Req,
[read_urlencoded_body|Tl]) ->
Data = cow_qs:parse_qs(Body),
%% First read in the body
Params = maps:from_list(Data),
modulate_state(Req#{params => Params}, Tl);
modulate_state(Req, [parse_qs|T1]) ->
Qs = cowboy_req:parse_qs(Req),
MapQs = maps:from_list(Qs),
modulate_state(Req#{parsed_qs => MapQs}, T1);
modulate_state(State, [_|Tl]) ->
modulate_state(State, Tl).
read_body(Req) ->
{ok, Data, Req0} =
case cowboy_req:has_body(Req) of
true ->
cowboy_req:read_body(Req);
_ ->
{ok, <<>>, Req}
end,
Req0#{body => Data}.