aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_rest.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/cowboy_rest.erl')
-rw-r--r--src/cowboy_rest.erl57
1 files changed, 39 insertions, 18 deletions
diff --git a/src/cowboy_rest.erl b/src/cowboy_rest.erl
index 1c0554a..c6b53bd 100644
--- a/src/cowboy_rest.erl
+++ b/src/cowboy_rest.erl
@@ -40,7 +40,7 @@
language_a :: undefined | binary(),
%% Charset.
- charsets_p = [] :: [{binary(), atom()}],
+ charsets_p = [] :: [{binary(), integer()}],
charset_a :: undefined | binary(),
%% Cached resource calls.
@@ -73,10 +73,10 @@ upgrade(_ListenerPid, Handler, Opts, Req) ->
catch Class:Reason ->
PLReq = cowboy_req:to_list(Req),
error_logger:error_msg(
- "** Handler ~p terminating in rest_init/2~n"
+ "** Cowboy handler ~p terminating in ~p/~p~n"
" for the reason ~p:~p~n** Options were ~p~n"
"** Request was ~p~n** Stacktrace: ~p~n~n",
- [Handler, Class, Reason, Opts, PLReq, erlang:get_stacktrace()]),
+ [Handler, rest_init, 2, Class, Reason, Opts, PLReq, erlang:get_stacktrace()]),
{ok, _Req2} = cowboy_req:reply(500, Req),
close
end.
@@ -195,8 +195,9 @@ options(Req, State) ->
%%
%% Note that it is also possible to return a binary content type that will
%% then be parsed by Cowboy. However note that while this may make your
-%% resources a little more readable, this is a lot less efficient. An example
-%% of such a return value would be:
+%% resources a little more readable, this is a lot less efficient.
+%%
+%% An example of such return value would be:
%% {<<"text/html">>, to_html}
content_types_provided(Req, State) ->
case call(Req, State, content_types_provided) of
@@ -210,14 +211,15 @@ content_types_provided(Req, State) ->
CTP2 = [normalize_content_types(P) || P <- CTP],
State2 = State#state{
handler_state=HandlerState, content_types_p=CTP2},
- {ok, Accept, Req3} = cowboy_req:parse_header(<<"accept">>, Req2),
- case Accept of
- undefined ->
+ case cowboy_req:parse_header(<<"accept">>, Req2) of
+ {error, badarg} ->
+ respond(Req2, State2, 400);
+ {ok, undefined, Req3} ->
{PMT, _Fun} = HeadCTP = hd(CTP2),
languages_provided(
cowboy_req:set_meta(media_type, PMT, Req3),
State2#state{content_type_a=HeadCTP});
- Accept ->
+ {ok, Accept, Req3} ->
Accept2 = prioritize_accept(Accept),
choose_media_type(Req3, State2, Accept2)
end
@@ -725,9 +727,19 @@ put_resource(Req, State, OnTrue) ->
%% list of content types, otherwise it'll shadow the ones following.
choose_content_type(Req, State, _OnTrue, _ContentType, []) ->
respond(Req, State, 415);
-choose_content_type(Req, State, OnTrue, ContentType, [{Accepted, Fun}|_Tail])
+choose_content_type(Req,
+ State=#state{handler=Handler, handler_state=HandlerState},
+ OnTrue, ContentType, [{Accepted, Fun}|_Tail])
when Accepted =:= '*' orelse Accepted =:= ContentType ->
case call(Req, State, Fun) of
+ no_call ->
+ error_logger:error_msg(
+ "** Cowboy handler ~p terminating; "
+ "function ~p/~p was not exported~n"
+ "** Request was ~p~n** State was ~p~n~n",
+ [Handler, Fun, 2, cowboy_req:to_list(Req), HandlerState]),
+ {ok, _} = cowboy_req:reply(500, Req),
+ close;
{halt, Req2, HandlerState} ->
terminate(Req2, State#state{handler_state=HandlerState});
{true, Req2, HandlerState} ->
@@ -758,19 +770,28 @@ has_resp_body(Req, State) ->
%% Set the response headers and call the callback found using
%% content_types_provided/2 to obtain the request body and add
%% it to the response.
-set_resp_body(Req, State=#state{content_type_a={_Type, Fun}}) ->
+set_resp_body(Req, State=#state{handler=Handler, handler_state=HandlerState,
+ content_type_a={_Type, Fun}}) ->
{Req2, State2} = set_resp_etag(Req, State),
{LastModified, Req3, State3} = last_modified(Req2, State2),
- case LastModified of
+ Req4 = case LastModified of
LastModified when is_atom(LastModified) ->
- Req4 = Req3;
+ Req3;
LastModified ->
- LastModifiedStr = httpd_util:rfc1123_date(LastModified),
- Req4 = cowboy_req:set_resp_header(
- <<"last-modified">>, LastModifiedStr, Req3)
+ LastModifiedBin = cowboy_clock:rfc1123(LastModified),
+ cowboy_req:set_resp_header(
+ <<"last-modified">>, LastModifiedBin, Req3)
end,
{Req5, State4} = set_resp_expires(Req4, State3),
case call(Req5, State4, Fun) of
+ no_call ->
+ error_logger:error_msg(
+ "** Cowboy handler ~p terminating; "
+ "function ~p/~p was not exported~n"
+ "** Request was ~p~n** State was ~p~n~n",
+ [Handler, Fun, 2, cowboy_req:to_list(Req5), HandlerState]),
+ {ok, _} = cowboy_req:reply(500, Req5),
+ close;
{halt, Req6, HandlerState} ->
terminate(Req6, State4#state{handler_state=HandlerState});
{Body, Req6, HandlerState} ->
@@ -810,9 +831,9 @@ set_resp_expires(Req, State) ->
Expires when is_atom(Expires) ->
{Req2, State2};
Expires ->
- ExpiresStr = httpd_util:rfc1123_date(Expires),
+ ExpiresBin = cowboy_clock:rfc1123(Expires),
Req3 = cowboy_req:set_resp_header(
- <<"expires">>, ExpiresStr, Req2),
+ <<"expires">>, ExpiresBin, Req2),
{Req3, State2}
end.