0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00

Simplify the code that calls REST callbacks

This commit is contained in:
Loïc Hoguin 2018-11-05 11:44:24 +01:00
parent 805a156785
commit 9d2b1a8892
No known key found for this signature in database
GPG key ID: 8A9DF795F6FED764

View file

@ -297,12 +297,11 @@ known_methods(Req, State=#state{method=Method}) ->
next(Req, State, fun uri_too_long/2); next(Req, State, fun uri_too_long/2);
no_call -> no_call ->
next(Req, State, 501); next(Req, State, 501);
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{List, Req2, HandlerState} -> {List, Req2, State2} ->
State2 = State#state{handler_state=HandlerState},
case lists:member(Method, List) of case lists:member(Method, List) of
true -> next(Req2, State2, fun uri_too_long/2); true -> next(Req2, State2, fun uri_too_long/2);
false -> next(Req2, State2, 501) false -> next(Req2, State2, 501)
@ -324,12 +323,11 @@ allowed_methods(Req, State=#state{method=Method}) ->
no_call -> no_call ->
method_not_allowed(Req, State, method_not_allowed(Req, State,
[<<"HEAD">>, <<"GET">>, <<"OPTIONS">>]); [<<"HEAD">>, <<"GET">>, <<"OPTIONS">>]);
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{List, Req2, HandlerState} -> {List, Req2, State2} ->
State2 = State#state{handler_state=HandlerState},
case lists:member(Method, List) of case lists:member(Method, List) of
true when Method =:= <<"OPTIONS">> -> true when Method =:= <<"OPTIONS">> ->
next(Req2, State2#state{allowed_methods=List}, next(Req2, State2#state{allowed_methods=List},
@ -357,16 +355,16 @@ is_authorized(Req, State) ->
case call(Req, State, is_authorized) of case call(Req, State, is_authorized) of
no_call -> no_call ->
forbidden(Req, State); forbidden(Req, State);
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{true, Req2, HandlerState} -> {true, Req2, State2} ->
forbidden(Req2, State#state{handler_state=HandlerState}); forbidden(Req2, State2);
{{false, AuthHead}, Req2, HandlerState} -> {{false, AuthHead}, Req2, State2} ->
Req3 = cowboy_req:set_resp_header( Req3 = cowboy_req:set_resp_header(
<<"www-authenticate">>, AuthHead, Req2), <<"www-authenticate">>, AuthHead, Req2),
respond(Req3, State#state{handler_state=HandlerState}, 401) respond(Req3, State2, 401)
end. end.
forbidden(Req, State) -> forbidden(Req, State) ->
@ -376,13 +374,13 @@ rate_limited(Req, State) ->
case call(Req, State, rate_limited) of case call(Req, State, rate_limited) of
no_call -> no_call ->
valid_content_headers(Req, State); valid_content_headers(Req, State);
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{false, Req2, HandlerState} -> {false, Req2, State2} ->
valid_content_headers(Req2, State#state{handler_state=HandlerState}); valid_content_headers(Req2, State2);
{{true, RetryAfter0}, Req2, HandlerState} -> {{true, RetryAfter0}, Req2, State2} ->
RetryAfter = if RetryAfter = if
is_integer(RetryAfter0), RetryAfter0 >= 0 -> is_integer(RetryAfter0), RetryAfter0 >= 0 ->
integer_to_binary(RetryAfter0); integer_to_binary(RetryAfter0);
@ -390,7 +388,7 @@ rate_limited(Req, State) ->
cowboy_clock:rfc1123(RetryAfter0) cowboy_clock:rfc1123(RetryAfter0)
end, end,
Req3 = cowboy_req:set_resp_header(<<"retry-after">>, RetryAfter, Req2), Req3 = cowboy_req:set_resp_header(<<"retry-after">>, RetryAfter, Req2),
respond(Req3, State#state{handler_state=HandlerState}, 429) respond(Req3, State2, 429)
end. end.
valid_content_headers(Req, State) -> valid_content_headers(Req, State) ->
@ -412,12 +410,12 @@ options(Req, State=#state{allowed_methods=Methods, method= <<"OPTIONS">>}) ->
= << << ", ", M/binary >> || M <- Methods >>, = << << ", ", M/binary >> || M <- Methods >>,
Req2 = cowboy_req:set_resp_header(<<"allow">>, Allow, Req), Req2 = cowboy_req:set_resp_header(<<"allow">>, Allow, Req),
respond(Req2, State, 200); respond(Req2, State, 200);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {stop, Req2, State2} ->
switch_handler(Switch, Req2, HandlerState); terminate(Req2, State2);
{stop, Req2, HandlerState} -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
terminate(Req2, State#state{handler_state=HandlerState}); switch_handler(Switch, Req2, State2);
{ok, Req2, HandlerState} -> {ok, Req2, State2} ->
respond(Req2, State#state{handler_state=HandlerState}, 200) respond(Req2, State2, 200)
end; end;
options(Req, State) -> options(Req, State) ->
content_types_provided(Req, State). content_types_provided(Req, State).
@ -453,26 +451,25 @@ content_types_provided(Req, State) ->
catch _:_ -> catch _:_ ->
respond(Req, State2, 400) respond(Req, State2, 400)
end; end;
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{[], Req2, HandlerState} -> {[], Req2, State2} ->
not_acceptable(Req2, State#state{handler_state=HandlerState}); not_acceptable(Req2, State2);
{CTP, Req2, HandlerState} -> {CTP, Req2, State2} ->
CTP2 = [normalize_content_types(P) || P <- CTP], CTP2 = [normalize_content_types(P) || P <- CTP],
State2 = State#state{ State3 = State2#state{content_types_p=CTP2},
handler_state=HandlerState, content_types_p=CTP2},
try cowboy_req:parse_header(<<"accept">>, Req2) of try cowboy_req:parse_header(<<"accept">>, Req2) of
undefined -> undefined ->
{PMT, _Fun} = HeadCTP = hd(CTP2), {PMT, _Fun} = HeadCTP = hd(CTP2),
languages_provided( languages_provided(
Req2#{media_type => PMT}, Req2#{media_type => PMT},
State2#state{content_type_a=HeadCTP}); State3#state{content_type_a=HeadCTP});
Accept -> Accept ->
choose_media_type(Req2, State2, prioritize_accept(Accept)) choose_media_type(Req2, State3, prioritize_accept(Accept))
catch _:_ -> catch _:_ ->
respond(Req2, State2, 400) respond(Req2, State3, 400)
end end
end. end.
@ -545,18 +542,18 @@ match_media_type_params(Req, State, Accept,
no_call -> no_call ->
languages_provided(Req#{media_type => {TP, STP, Params_A0}}, languages_provided(Req#{media_type => {TP, STP, Params_A0}},
State#state{content_type_a=Provided}); State#state{content_type_a=Provided});
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{CP, Req2, HandlerState} -> {CP, Req2, State2} ->
State2 = State#state{handler_state=HandlerState, charsets_p=CP}, State3 = State2#state{charsets_p=CP},
case lists:member(Charset, CP) of case lists:member(Charset, CP) of
false -> false ->
match_media_type(Req2, State2, Accept, Tail, MediaType); match_media_type(Req2, State3, Accept, Tail, MediaType);
true -> true ->
languages_provided(Req2#{media_type => {TP, STP, Params_A}}, languages_provided(Req2#{media_type => {TP, STP, Params_A}},
State2#state{content_type_a=Provided, State3#state{content_type_a=Provided,
charset_a=Charset}) charset_a=Charset})
end end
end; end;
@ -596,20 +593,20 @@ languages_provided(Req, State) ->
case call(Req, State, languages_provided) of case call(Req, State, languages_provided) of
no_call -> no_call ->
charsets_provided(Req, State); charsets_provided(Req, State);
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{[], Req2, HandlerState} -> {[], Req2, State2} ->
not_acceptable(Req2, State#state{handler_state=HandlerState}); not_acceptable(Req2, State2);
{LP, Req2, HandlerState} -> {LP, Req2, State2} ->
State2 = State#state{handler_state=HandlerState, languages_p=LP}, State3 = State2#state{languages_p=LP},
case cowboy_req:parse_header(<<"accept-language">>, Req2) of case cowboy_req:parse_header(<<"accept-language">>, Req2) of
undefined -> undefined ->
set_language(Req2, State2#state{language_a=hd(LP)}); set_language(Req2, State3#state{language_a=hd(LP)});
AcceptLanguage -> AcceptLanguage ->
AcceptLanguage2 = prioritize_languages(AcceptLanguage), AcceptLanguage2 = prioritize_languages(AcceptLanguage),
choose_language(Req2, State2, AcceptLanguage2) choose_language(Req2, State3, AcceptLanguage2)
end end
end. end.
@ -678,12 +675,12 @@ charsets_provided(Req, State) ->
case call(Req, State, charsets_provided) of case call(Req, State, charsets_provided) of
no_call -> no_call ->
set_content_type(Req, State); set_content_type(Req, State);
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{CP, Req2, HandlerState} -> {CP, Req2, State2} ->
charsets_provided(Req2, State#state{handler_state=HandlerState, charsets_p=CP}) charsets_provided(Req2, State2#state{charsets_p=CP})
end. end.
prioritize_charsets(AcceptCharsets) -> prioritize_charsets(AcceptCharsets) ->
@ -784,9 +781,8 @@ variances(Req, State, Variances) ->
case unsafe_call(Req, State, variances) of case unsafe_call(Req, State, variances) of
no_call -> no_call ->
{Variances, Req, State}; {Variances, Req, State};
{HandlerVariances, Req2, HandlerState} -> {HandlerVariances, Req2, State2} ->
{Variances ++ HandlerVariances, Req2, {Variances ++ HandlerVariances, Req2, State2}
State#state{handler_state=HandlerState}}
end. end.
resource_exists(Req, State) -> resource_exists(Req, State) ->
@ -942,16 +938,16 @@ is_put_to_missing_resource(Req, State) ->
%% with Location the full new URI of the resource. %% with Location the full new URI of the resource.
moved_permanently(Req, State, OnFalse) -> moved_permanently(Req, State, OnFalse) ->
case call(Req, State, moved_permanently) of case call(Req, State, moved_permanently) of
{{true, Location}, Req2, HandlerState} -> {{true, Location}, Req2, State2} ->
Req3 = cowboy_req:set_resp_header( Req3 = cowboy_req:set_resp_header(
<<"location">>, Location, Req2), <<"location">>, Location, Req2),
respond(Req3, State#state{handler_state=HandlerState}, 301); respond(Req3, State2, 301);
{false, Req2, HandlerState} -> {false, Req2, State2} ->
OnFalse(Req2, State#state{handler_state=HandlerState}); OnFalse(Req2, State2);
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
no_call -> no_call ->
OnFalse(Req, State) OnFalse(Req, State)
end. end.
@ -965,16 +961,16 @@ previously_existed(Req, State) ->
%% with Location the full new URI of the resource. %% with Location the full new URI of the resource.
moved_temporarily(Req, State) -> moved_temporarily(Req, State) ->
case call(Req, State, moved_temporarily) of case call(Req, State, moved_temporarily) of
{{true, Location}, Req2, HandlerState} -> {{true, Location}, Req2, State2} ->
Req3 = cowboy_req:set_resp_header( Req3 = cowboy_req:set_resp_header(
<<"location">>, Location, Req2), <<"location">>, Location, Req2),
respond(Req3, State#state{handler_state=HandlerState}, 307); respond(Req3, State2, 307);
{false, Req2, HandlerState} -> {false, Req2, State2} ->
is_post_to_missing_resource(Req2, State#state{handler_state=HandlerState}, 410); is_post_to_missing_resource(Req2, State2, 410);
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
no_call -> no_call ->
is_post_to_missing_resource(Req, State, 410) is_post_to_missing_resource(Req, State, 410)
end. end.
@ -1023,13 +1019,12 @@ accept_resource(Req, State) ->
case call(Req, State, content_types_accepted) of case call(Req, State, content_types_accepted) of
no_call -> no_call ->
respond(Req, State, 415); respond(Req, State, 415);
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{CTA, Req2, HandlerState} -> {CTA, Req2, State2} ->
CTA2 = [normalize_content_types(P) || P <- CTA], CTA2 = [normalize_content_types(P) || P <- CTA],
State2 = State#state{handler_state=HandlerState},
try cowboy_req:parse_header(<<"content-type">>, Req2) of try cowboy_req:parse_header(<<"content-type">>, Req2) of
ContentType -> ContentType ->
choose_content_type(Req2, State2, ContentType, CTA2) choose_content_type(Req2, State2, ContentType, CTA2)
@ -1060,21 +1055,17 @@ choose_content_type(Req, State, ContentType, [_Any|Tail]) ->
process_content_type(Req, State=#state{method=Method, exists=Exists}, Fun) -> process_content_type(Req, State=#state{method=Method, exists=Exists}, Fun) ->
try case call(Req, State, Fun) of try case call(Req, State, Fun) of
{stop, Req2, HandlerState2} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState2}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{true, Req2, HandlerState2} when Exists -> {true, Req2, State2} when Exists ->
State2 = State#state{handler_state=HandlerState2},
next(Req2, State2, fun has_resp_body/2); next(Req2, State2, fun has_resp_body/2);
{true, Req2, HandlerState2} -> {true, Req2, State2} ->
State2 = State#state{handler_state=HandlerState2},
next(Req2, State2, fun maybe_created/2); next(Req2, State2, fun maybe_created/2);
{false, Req2, HandlerState2} -> {false, Req2, State2} ->
State2 = State#state{handler_state=HandlerState2},
respond(Req2, State2, 400); respond(Req2, State2, 400);
{{true, ResURL}, Req2, HandlerState2} when Method =:= <<"POST">> -> {{true, ResURL}, Req2, State2} when Method =:= <<"POST">> ->
State2 = State#state{handler_state=HandlerState2},
Req3 = cowboy_req:set_resp_header( Req3 = cowboy_req:set_resp_header(
<<"location">>, ResURL, Req2), <<"location">>, ResURL, Req2),
if if
@ -1143,12 +1134,11 @@ set_resp_body_expires(Req, State) ->
%% it to the response. %% it to the response.
set_resp_body(Req, State=#state{handler=Handler, content_type_a={_, Callback}}) -> set_resp_body(Req, State=#state{handler=Handler, content_type_a={_, Callback}}) ->
try case call(Req, State, Callback) of try case call(Req, State, Callback) of
{stop, Req2, HandlerState2} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState2}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{Body, Req2, HandlerState2} -> {Body, Req2, State2} ->
State2 = State#state{handler_state=HandlerState2},
Req3 = cowboy_req:set_resp_body(Body, Req2), Req3 = cowboy_req:set_resp_body(Body, Req2),
multiple_choices(Req3, State2) multiple_choices(Req3, State2)
end catch Class:{case_clause, no_call} -> end catch Class:{case_clause, no_call} ->
@ -1200,11 +1190,11 @@ generate_etag(Req, State=#state{etag=undefined}) ->
case unsafe_call(Req, State, generate_etag) of case unsafe_call(Req, State, generate_etag) of
no_call -> no_call ->
{undefined, Req, State#state{etag=no_call}}; {undefined, Req, State#state{etag=no_call}};
{Etag, Req2, HandlerState} when is_binary(Etag) -> {Etag, Req2, State2} when is_binary(Etag) ->
Etag2 = cow_http_hd:parse_etag(Etag), Etag2 = cow_http_hd:parse_etag(Etag),
{Etag2, Req2, State#state{handler_state=HandlerState, etag=Etag2}}; {Etag2, Req2, State2#state{etag=Etag2}};
{Etag, Req2, HandlerState} -> {Etag, Req2, State2} ->
{Etag, Req2, State#state{handler_state=HandlerState, etag=Etag}} {Etag, Req2, State2#state{etag=Etag}}
end; end;
generate_etag(Req, State=#state{etag=Etag}) -> generate_etag(Req, State=#state{etag=Etag}) ->
{Etag, Req, State}. {Etag, Req, State}.
@ -1215,9 +1205,8 @@ last_modified(Req, State=#state{last_modified=undefined}) ->
case unsafe_call(Req, State, last_modified) of case unsafe_call(Req, State, last_modified) of
no_call -> no_call ->
{undefined, Req, State#state{last_modified=no_call}}; {undefined, Req, State#state{last_modified=no_call}};
{LastModified, Req2, HandlerState} -> {LastModified, Req2, State2} ->
{LastModified, Req2, State#state{handler_state=HandlerState, {LastModified, Req2, State2#state{last_modified=LastModified}}
last_modified=LastModified}}
end; end;
last_modified(Req, State=#state{last_modified=LastModified}) -> last_modified(Req, State=#state{last_modified=LastModified}) ->
{LastModified, Req, State}. {LastModified, Req, State}.
@ -1228,9 +1217,8 @@ expires(Req, State=#state{expires=undefined}) ->
case unsafe_call(Req, State, expires) of case unsafe_call(Req, State, expires) of
no_call -> no_call ->
{undefined, Req, State#state{expires=no_call}}; {undefined, Req, State#state{expires=no_call}};
{Expires, Req2, HandlerState} -> {Expires, Req2, State2} ->
{Expires, Req2, State#state{handler_state=HandlerState, {Expires, Req2, State2#state{expires=Expires}}
expires=Expires}}
end; end;
expires(Req, State=#state{expires=Expires}) -> expires(Req, State=#state{expires=Expires}) ->
{Expires, Req, State}. {Expires, Req, State}.
@ -1241,34 +1229,44 @@ expect(Req, State, Callback, Expected, OnTrue, OnFalse) ->
case call(Req, State, Callback) of case call(Req, State, Callback) of
no_call -> no_call ->
next(Req, State, OnTrue); next(Req, State, OnTrue);
{stop, Req2, HandlerState} -> {stop, Req2, State2} ->
terminate(Req2, State#state{handler_state=HandlerState}); terminate(Req2, State2);
{Switch, Req2, HandlerState} when element(1, Switch) =:= switch_handler -> {Switch, Req2, State2} when element(1, Switch) =:= switch_handler ->
switch_handler(Switch, Req2, HandlerState); switch_handler(Switch, Req2, State2);
{Expected, Req2, HandlerState} -> {Expected, Req2, State2} ->
next(Req2, State#state{handler_state=HandlerState}, OnTrue); next(Req2, State2, OnTrue);
{_Unexpected, Req2, HandlerState} -> {_Unexpected, Req2, State2} ->
next(Req2, State#state{handler_state=HandlerState}, OnFalse) next(Req2, State2, OnFalse)
end. end.
call(Req, State=#state{handler=Handler, handler_state=HandlerState}, call(Req0, State=#state{handler=Handler,
Callback) -> handler_state=HandlerState0}, Callback) ->
case erlang:function_exported(Handler, Callback, 2) of case erlang:function_exported(Handler, Callback, 2) of
true -> true ->
try try Handler:Callback(Req0, HandlerState0) of
Handler:Callback(Req, HandlerState) no_call ->
no_call;
{Result, Req, HandlerState} ->
{Result, Req, State#state{handler_state=HandlerState}}
catch Class:Reason -> catch Class:Reason ->
error_terminate(Req, State, Class, Reason) error_terminate(Req0, State, Class, Reason)
end; end;
false -> false ->
no_call no_call
end. end.
unsafe_call(Req, #state{handler=Handler, handler_state=HandlerState}, unsafe_call(Req0, State=#state{handler=Handler,
Callback) -> handler_state=HandlerState0}, Callback) ->
case erlang:function_exported(Handler, Callback, 2) of case erlang:function_exported(Handler, Callback, 2) of
true -> Handler:Callback(Req, HandlerState); false ->
false -> no_call no_call;
true ->
case Handler:Callback(Req0, HandlerState0) of
no_call ->
no_call;
{Result, Req, HandlerState} ->
{Result, Req, State#state{handler_state=HandlerState}}
end
end. end.
next(Req, State, Next) when is_function(Next) -> next(Req, State, Next) when is_function(Next) ->
@ -1279,9 +1277,9 @@ next(Req, State, StatusCode) when is_integer(StatusCode) ->
respond(Req, State, StatusCode) -> respond(Req, State, StatusCode) ->
terminate(cowboy_req:reply(StatusCode, Req), State). terminate(cowboy_req:reply(StatusCode, Req), State).
switch_handler({switch_handler, Mod}, Req, HandlerState) -> switch_handler({switch_handler, Mod}, Req, #state{handler_state=HandlerState}) ->
{Mod, Req, HandlerState}; {Mod, Req, HandlerState};
switch_handler({switch_handler, Mod, Opts}, Req, HandlerState) -> switch_handler({switch_handler, Mod, Opts}, Req, #state{handler_state=HandlerState}) ->
{Mod, Req, HandlerState, Opts}. {Mod, Req, HandlerState, Opts}.
-spec error_terminate(cowboy_req:req(), #state{}, atom(), any()) -> no_return(). -spec error_terminate(cowboy_req:req(), #state{}, atom(), any()) -> no_return().