Skip to content

Commit

Permalink
Merge pull request #33 from rustkas/fix_doc
Browse files Browse the repository at this point in the history
General improvements
  • Loading branch information
mmzeeman committed May 6, 2022
2 parents 072e1c5 + f221a45 commit ed1aed8
Show file tree
Hide file tree
Showing 15 changed files with 1,089 additions and 192 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.eunit
doc/
deps
*.o
*.beam
Expand All @@ -14,3 +13,6 @@ _build
_checkout
compile_commands.json
rebar3
doc/*
!doc/style.css
!doc/overview.edoc
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ xref: $(REBAR)
clean:
$(REBAR) clean

##
## Doc targets
##
docs: $(REBAR)
$(REBAR) edoc

edoc_private: $(REBAR)
$(REBAR) as edoc_private edoc

$(REBAR):
$(ERL) -noshell -s inets -s ssl \
-eval '{ok, saved_to_file} = httpc:request(get, {"$(REBAR_URL)", []}, [], [{stream, "$(REBAR)"}])' \
Expand Down
5 changes: 5 additions & 0 deletions doc/overview.edoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@author Marc Worrell <marc@worrell.nl>
@title cowmachine
@doc Webmachine for <a href="http://zotonic.com/">Zotonic</a> and <a href="https://ninenines.eu/">Cowboy</a>.
@copyright Apache-2.0
@reference This is an adaptation of <a href="https://github.com/webmachine/webmachine">webmachine</a> for the Cowboy web server.
75 changes: 75 additions & 0 deletions doc/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* standard EDoc style sheet */
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
margin-left: .25in;
margin-right: .2in;
margin-top: 0.2in;
margin-bottom: 0.2in;
color: #000000;
background-color: #ffffff;
}
h1,h2 {
margin-left: -0.2in;
}
div.navbar {
background-color: #add8e6;
padding: 0.2em;
}
h2.indextitle {
padding: 0.4em;
background-color: #add8e6;
}
h3.function,h3.typedecl {
background-color: #add8e6;
padding-left: 1em;
}
div.spec {
margin-left: 2em;

background-color: #eeeeee;
}
a.module {
text-decoration:none
}
a.module:hover {
background-color: #eeeeee;
}
ul.definitions {
list-style-type: none;
}
ul.index {
list-style-type: none;
background-color: #eeeeee;
}

/*
* Minor style tweaks
*/
ul {
list-style-type: square;
}
table {
border-collapse: collapse;
}
td {
padding: 3px;
vertical-align: middle;
}

/*
Tune styles
*/

table[summary="navigation bar"] {
background-image: url('http://zotonic.com/lib/images/logo.png');
background-repeat: no-repeat;
background-position: center;
}

code, p>tt, a>tt {
font-size: 1.2em;
}

p {
line-height: 1.5;
}
26 changes: 21 additions & 5 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,28 @@
]},

{xref_ignores, [
]},

{dialyzer, [
]}
]},
{edoc_private, [
{edoc_opts, [
{private, true}
]}
]},
{check, [
{dialyzer, [
{warnings, [
no_return
]}
]}
]}
]},

{erl_opts, [
debug_info
]}
]
}
]}.


{edoc_opts, [
{preprocess, true}, {stylesheet, "style.css"}
]}.
75 changes: 67 additions & 8 deletions src/cowmachine.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
%% @copyright 2016-2022 Marc Worrell
%%
%% @doc Cowmachine: webmachine middleware for Cowboy/Zotonic
%% @end

%% Copyright 2016-2022 Marc Worrell
%%
Expand Down Expand Up @@ -34,11 +35,15 @@
-include("cowmachine_state.hrl").
-include("cowmachine_log.hrl").

%% @private
-export_type([cmstate/0]).

%% @doc Cowboy middleware, route the new request. Continue with the cowmachine,
%% requests a redirect or return a 400 on an unknown host.
-spec execute(Req, Env) -> {ok, Req, Env} | {stop, Req}
-spec execute(Req, Env) -> Result
when Req :: cowboy_req:req(),
Env :: cowboy_middleware:env().
Env :: cowboy_middleware:env(),
Result :: {ok, Req, Env} | {stop, Req}.
execute(Req, #{ cowmachine_controller := _Controller } = Env) ->
ContextEnv = maps:get(cowmachine_context, Env, undefined),
Context = cowmachine_req:init_context(Req, Env, ContextEnv),
Expand All @@ -47,10 +52,13 @@ execute(Req, #{ cowmachine_controller := _Controller } = Env) ->

%% @doc Handle a request, executes the cowmachine http states. Can be used by middleware
%% functions to add some additional initialization of controllers or context.
-spec request(Context, Options::map()) -> {ok, Req, Env} | {stop, Req}

-spec request(Context, Options) -> Result
when Context :: cowmachine_req:context(),
Req :: cowboy_req:req(),
Env :: cowboy_middleware:env().
Options :: map(),
Req :: cowboy_req:req(),
Env :: cowboy_middleware:env(),
Result :: {ok, Req, Env} | {stop, Req}.
request(Context, Options) ->
Req = cowmachine_req:req(Context),
Env = cowmachine_req:env(Context),
Expand All @@ -62,14 +70,23 @@ request(Context, Options) ->
Other
end.

-spec request_1(Controller, Req, Env, Options, Context) -> Result when
Controller :: atom(),
Req :: cowboy_req:req(),
Env :: cowboy_middleware:env(),
Options :: map(),
Context :: cowmachine_req:context(),
Result :: {upgrade, UpgradeFun, State, Context} | cowboy_middleware:env() | any(),
UpgradeFun :: atom(),
State :: cmstate().
request_1(Controller, Req, Env, Options, Context) ->
State = #cmstate{
controller = Controller,
cache = #{},
options = Options
},
Site = maps:get(site, Env, undefined),
try
ReqResult = try
EnvInit = cowmachine_req:init_env(Req, Env),
Context1 = cowmachine_req:set_env(EnvInit, Context),
case cowmachine_decision_core:handle_request(State, Context1) of
Expand Down Expand Up @@ -116,9 +133,21 @@ request_1(Controller, Req, Env, Options, Context) ->
class => Class, reason => Reason,
stack => Stacktrace}, Req),
handle_stop_request(500, Site, {throw, {Reason, Stacktrace}}, Req, Env, State, Context)
end.
end,
ReqResult.


% @todo add the error controller as an application env, if not defined then just terminate with the corresponding error code.

-spec handle_stop_request(ResponseCode, Site, Reason, Req, Env, State, Context) -> Result when
ResponseCode :: integer(),
Site :: atom() | undefined,
Reason :: any(),
Req :: cowboy_req:req(),
Env :: cowboy_middleware:env(),
State :: cmstate(),
Context :: cowmachine_req:context(),
Result :: {ok, Req, Env} | {stop, Req}.
handle_stop_request(ResponseCode, _Site, Reason, Req, Env, State, Context) ->
State1 = State#cmstate{
controller = controller_http_error
Expand Down Expand Up @@ -154,13 +183,19 @@ handle_stop_request(ResponseCode, _Site, Reason, Req, Env, State, Context) ->
%%
%% Logging
%%

-spec log(Report) -> Result when
Report :: map(),
Result :: any().
log(#{ level := Level } = Report) ->
log_report(Level, Report#{
in => cowmachine,
node => node()
}).

-spec log(Report, Req) -> Result when
Report :: map(),
Req :: map(),
Result :: any().
log(#{ level := Level } = Report, Req) when is_map(Req) ->
Report1 = lists:foldl(fun({Key, Fun}, Acc) ->
case Fun(Req) of
Expand All @@ -175,6 +210,10 @@ log(#{ level := Level } = Report, Req) when is_map(Req) ->
node => node()
}).

-spec log_report(LogLevel, Report) -> Result when
LogLevel :: debug | info | notice | warning | error,
Report :: map(),
Result :: any().
log_report(debug, Report) when is_map(Report) ->
?LOG_DEBUG(Report);
log_report(info, Report) when is_map(Report) ->
Expand All @@ -186,16 +225,36 @@ log_report(warning, Report) when is_map(Report) ->
log_report(error, Report) when is_map(Report) ->
?LOG_ERROR(Report).

-spec src(IpInfo) -> Result when
IpInfo :: #{ peer := {IP, Port} } | any(),
Port :: integer(),
IP :: tuple(),
Result :: {ok, map()} | undefined.
src(#{ peer := {IP, Port} }) -> {ok, ip_info(IP, Port)};
src(_) -> undefined.

-spec dst(DstInfo) -> Result when
DstInfo :: #{ sock := {IP, Port} } | #{ port := Port } | any(),
IP :: tuple(),
Port :: integer(),
Result :: {ok, #{IPType => string(), port => Port}} | {ok, #{ port => Port }} | undefined,
IPType :: ip4 | ip6.
dst(#{ sock := {IP, Port} } ) -> {ok, ip_info(IP, Port)};
dst(#{ port := Port }) -> {ok, #{ port => Port }};
dst(_) -> undefined.

-spec path(PathInfo) -> Result when
PathInfo :: #{ path := Path } | any(),
Path :: any(),
Result :: {ok, Path} | undefined.
path(#{ path := Path }) -> {ok, Path};
path(_) -> undefined.

-spec ip_info(IP, Port) -> Result when
IP :: tuple(),
Port :: integer(),
IPType :: ip4 | ip6,
Result :: #{IPType => string(), port => Port}.
ip_info(IP, Port) ->
IPType = case tuple_size(IP) of 4 -> ip4; 8 -> ip6 end,
#{IPType => inet_parse:ntoa(IP), port => Port}.

0 comments on commit ed1aed8

Please sign in to comment.