diff options
Diffstat (limited to 'src/cowboy_rest.erl')
-rw-r--r-- | src/cowboy_rest.erl | 57 |
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. |