Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #78 from johannesh/invalid_return

Elli should return 500 for handlers returning bogus responses
  • Loading branch information...
commit 46277379d9d2a52ad3282cb9806f6e72f2157dad 2 parents 7365dce + 838032b
@knutin authored
View
3  include/elli.hrl
@@ -29,7 +29,8 @@
chunk_complete | request_complete |
request_throw | request_error | request_exit |
request_closed | request_parse_error |
- client_closed | client_timeout.
+ client_closed | client_timeout |
+ invalid_return.
-record(req, {
method :: http_method(),
View
8 src/elli_example_callback.erl
@@ -163,6 +163,9 @@ handle('GET', [<<"403">>], _Req) ->
%% authentication/authorization
throw({403, [], <<"Forbidden">>});
+handle('GET', [<<"invalid_return">>], _Req) ->
+ {invalid_return};
+
handle(_, _, _Req) ->
{404, [], <<"Not Found">>}.
@@ -216,6 +219,11 @@ handle_event(request_throw, [_Request, _Exception, _Stacktrace], _) -> ok;
handle_event(request_error, [_Request, _Exception, _Stacktrace], _) -> ok;
handle_event(request_exit, [_Request, _Exception, _Stacktrace], _) -> ok;
+%% invalid_return is sent if the user callback code returns a term not
+%% understood by elli, see elli_http:execute_callback/1.
+%% After triggering this event, a generated response is sent to the user.
+handle_event(invalid_return, [_Request, _ReturnValue], _) -> ok;
+
%% chunk_complete fires when a chunked response is completely
%% sent. It's identical to the request_complete event, except instead
View
2  src/elli_handler.erl
@@ -3,4 +3,4 @@
-callback handle(Req :: #req{}, callback_args()) ->
ignore | {response_code(), [tuple()], binary()} | {ok, [tuple()], binary()}.
--callback handle_event(Event :: elli_event(), Args :: [tuple()], Config :: [tuple()]) -> ok.
+-callback handle_event(Event :: elli_event(), Args :: [term()], Config :: [tuple()]) -> ok.
View
5 src/elli_http.erl
@@ -220,7 +220,10 @@ execute_callback(#req{callback = {Mod, Args}} = Req) ->
{HttpCode, Headers, {file, Filename, Range}} ->
{file, HttpCode, Headers, Filename, Range};
{HttpCode, Headers, Body} -> {response, HttpCode, Headers, Body};
- {HttpCode, Body} -> {response, HttpCode, [], Body}
+ {HttpCode, Body} -> {response, HttpCode, [], Body};
+ Unexpected ->
+ handle_event(Mod, invalid_return, [Req, Unexpected], Args),
+ {response, 500, [], <<"Internal server error">>}
catch
throw:{ResponseCode, Headers, Body} when is_integer(ResponseCode) ->
{response, ResponseCode, Headers, Body};
View
16 test/elli_tests.erl
@@ -13,6 +13,7 @@ elli_test_() ->
?_test(hello_world()),
?_test(not_found()),
?_test(crash()),
+ ?_test(invalid_return()),
?_test(no_compress()),
?_test(exception_flow()),
?_test(accept_content_type()),
@@ -79,6 +80,13 @@ crash() ->
{"content-length", "21"}], headers(Response)),
?assertEqual("Internal server error", body(Response)).
+invalid_return() ->
+ % Elli should return 500 for handlers returning bogus responses.
+ {ok, Response} = httpc:request("http://localhost:3001/invalid_return"),
+ ?assertEqual(500, status(Response)),
+ ?assertEqual([{"connection", "Keep-Alive"},
+ {"content-length", "21"}], headers(Response)),
+ ?assertEqual("Internal server error", body(Response)).
no_compress() ->
{ok, Response} = httpc:request(get, {"http://localhost:3001/compressed",
@@ -408,10 +416,10 @@ get_range_test_() ->
OffsetReq = #req{headers = [{<<"Range">>,<<"bytes=200-">>}]},
UndefReq = #req{headers = []},
BadReq = #req{headers = [{<<"Range">>,<<"bytes=--99,hallo-world">>}]},
-
+
ByteRangeSet = [{bytes, 0, 99}, {bytes, 500, 999}, {suffix, 800}],
- [?_assertEqual(ByteRangeSet, elli_request:get_range(Req)),
+ [?_assertEqual(ByteRangeSet, elli_request:get_range(Req)),
?_assertEqual([{offset, 200}], elli_request:get_range(OffsetReq)),
?_assertEqual([], elli_request:get_range(UndefReq)),
?_assertEqual(parse_error, elli_request:get_range(BadReq))].
@@ -426,8 +434,8 @@ normalize_range_test_() ->
Normal = {200, 400},
Set = [{bytes, 0, 999}],
EmptySet = [],
- Invalid1 = {bytes, 400, 200},
- Invalid2 = {bytes, 1200, 2000},
+ Invalid1 = {bytes, 400, 200},
+ Invalid2 = {bytes, 1200, 2000},
Invalid3 = {offset, -10},
Invalid4 = {offset, 2000},
Invalid5 = parse_error,
Please sign in to comment.
Something went wrong with that request. Please try again.