Browse Source

Silence expected errors from the static_handler test suite

Loïc Hoguin 6 years ago
parent
commit
84aea5d24d
2 changed files with 29 additions and 9 deletions
  1. 5 2
      src/cowboy_static.erl
  2. 24 7
      test/static_handler_SUITE.erl

+ 5 - 2
src/cowboy_static.erl

@@ -120,7 +120,7 @@ init_dir(Req, Path, HowToAccess, Extra) when is_list(Path) ->
 init_dir(Req, Path, HowToAccess, Extra) ->
 init_dir(Req, Path, HowToAccess, Extra) ->
 	Dir = fullpath(filename:absname(Path)),
 	Dir = fullpath(filename:absname(Path)),
 	PathInfo = cowboy_req:path_info(Req),
 	PathInfo = cowboy_req:path_info(Req),
-	Filepath = filename:join([Dir|[escape_reserved(P, <<>>) || P <- PathInfo]]),
+	Filepath = filename:join([Dir|escape_reserved(PathInfo)]),
 	Len = byte_size(Dir),
 	Len = byte_size(Dir),
 	case fullpath(Filepath) of
 	case fullpath(Filepath) of
 		<< Dir:Len/binary, $/, _/binary >> ->
 		<< Dir:Len/binary, $/, _/binary >> ->
@@ -131,6 +131,9 @@ init_dir(Req, Path, HowToAccess, Extra) ->
 			{cowboy_rest, Req, error}
 			{cowboy_rest, Req, error}
 	end.
 	end.
 
 
+escape_reserved([]) -> [];
+escape_reserved([P|Tail]) -> [escape_reserved(P, <<>>)|escape_reserved(Tail)].
+
 %% We escape the slash found in path segments because
 %% We escape the slash found in path segments because
 %% a segment corresponds to a directory entry, and
 %% a segment corresponds to a directory entry, and
 %% therefore those slashes are expected to be part of
 %% therefore those slashes are expected to be part of
@@ -315,7 +318,7 @@ forbidden(Req, State) ->
 -spec content_types_provided(Req, State)
 -spec content_types_provided(Req, State)
 	-> {[{binary(), get_file}], Req, State}
 	-> {[{binary(), get_file}], Req, State}
 	when State::state().
 	when State::state().
-content_types_provided(Req, State={Path, _, Extra}) ->
+content_types_provided(Req, State={Path, _, Extra}) when is_list(Extra) ->
 	case lists:keyfind(mimetypes, 1, Extra) of
 	case lists:keyfind(mimetypes, 1, Extra) of
 		false ->
 		false ->
 			{[{cow_mimetypes:web(Path), get_file}], Req, State};
 			{[{cow_mimetypes:web(Path), get_file}], Req, State};

+ 24 - 7
test/static_handler_SUITE.erl

@@ -54,10 +54,6 @@ groups() ->
 	].
 	].
 
 
 init_per_suite(Config) ->
 init_per_suite(Config) ->
-	%% @todo When we can chain stream handlers, write one
-	%% to hide these expected errors.
-	ct:print("This test suite will produce error reports. "
-		"The path for these expected errors begins with '/bad' or '/char'."),
 	%% Two static folders are created: one in ct_helper's private directory,
 	%% Two static folders are created: one in ct_helper's private directory,
 	%% and one in the test run private directory.
 	%% and one in the test run private directory.
 	PrivDir = code:priv_dir(ct_helper) ++ "/static",
 	PrivDir = code:priv_dir(ct_helper) ++ "/static",
@@ -81,8 +77,6 @@ init_per_suite(Config) ->
 	[{static_dir, StaticDir}, {char_dir, CharDir}, {chars, Chars}|Config].
 	[{static_dir, StaticDir}, {char_dir, CharDir}, {chars, Chars}|Config].
 
 
 end_per_suite(Config) ->
 end_per_suite(Config) ->
-	ct:print("This test suite produced error reports. "
-		"The path for these expected errors begins with '/bad' or '/char'."),
 	%% Special directory.
 	%% Special directory.
 	CharDir = config(char_dir, Config),
 	CharDir = config(char_dir, Config),
 	_ = [file:delete(CharDir ++ [$/, C]) || C <- lists:seq(0, 127)],
 	_ = [file:delete(CharDir ++ [$/, C]) || C <- lists:seq(0, 127)],
@@ -103,16 +97,23 @@ init_per_group(priv_dir, Config) ->
 init_per_group(Name=http_no_sendfile, Config) ->
 init_per_group(Name=http_no_sendfile, Config) ->
 	cowboy_test:init_http(Name, #{
 	cowboy_test:init_http(Name, #{
 		env => #{dispatch => init_dispatch(Config)},
 		env => #{dispatch => init_dispatch(Config)},
+		middlewares => [?MODULE, cowboy_router, cowboy_handler],
 		sendfile => false
 		sendfile => false
 	}, [{flavor, vanilla}|Config]);
 	}, [{flavor, vanilla}|Config]);
 init_per_group(Name=h2c_no_sendfile, Config) ->
 init_per_group(Name=h2c_no_sendfile, Config) ->
 	Config1 = cowboy_test:init_http(Name, #{
 	Config1 = cowboy_test:init_http(Name, #{
 		env => #{dispatch => init_dispatch(Config)},
 		env => #{dispatch => init_dispatch(Config)},
+		middlewares => [?MODULE, cowboy_router, cowboy_handler],
 		sendfile => false
 		sendfile => false
 	}, [{flavor, vanilla}|Config]),
 	}, [{flavor, vanilla}|Config]),
 	lists:keyreplace(protocol, 1, Config1, {protocol, http2});
 	lists:keyreplace(protocol, 1, Config1, {protocol, http2});
 init_per_group(Name, Config) ->
 init_per_group(Name, Config) ->
-	cowboy_test:init_common_groups(Name, Config, ?MODULE).
+	Config1 = cowboy_test:init_common_groups(Name, Config, ?MODULE),
+	Opts = ranch:get_protocol_options(Name),
+	ok = ranch:set_protocol_options(Name, Opts#{
+		middlewares => [?MODULE, cowboy_router, cowboy_handler]
+	}),
+	Config1.
 
 
 end_per_group(Name, _) ->
 end_per_group(Name, _) ->
 	cowboy:stop_listener(Name).
 	cowboy:stop_listener(Name).
@@ -182,6 +183,22 @@ init_dispatch(Config) ->
 		{"/bad/ez_priv_dir/[...]", cowboy_static, {priv_dir, static_files_app, "cgi-bin"}}
 		{"/bad/ez_priv_dir/[...]", cowboy_static, {priv_dir, static_files_app, "cgi-bin"}}
 	]}]).
 	]}]).
 
 
+%% Middleware interface to silence expected errors.
+
+execute(Req=#{path := Path}, Env) ->
+	case Path of
+		<<"/bad/priv_dir/app/", _/bits>> -> ct_helper:ignore(cowboy_static, priv_path, 2);
+		<<"/bad/priv_file/app">> -> ct_helper:ignore(cowboy_static, priv_path, 2);
+		<<"/bad/priv_dir/route">> -> ct_helper:ignore(cowboy_static, escape_reserved, 1);
+		<<"/bad/dir/route">> -> ct_helper:ignore(cowboy_static, escape_reserved, 1);
+		<<"/bad">> -> ct_helper:ignore(cowboy_static, init_opts, 2);
+		<<"/bad/options">> -> ct_helper:ignore(cowboy_static, content_types_provided, 2);
+		<<"/bad/options/mime">> -> ct_helper:ignore(cowboy_rest, set_content_type, 2);
+		<<"/bad/options/etag">> -> ct_helper:ignore(cowboy_static, generate_etag, 2);
+		_ -> ok
+	end,
+	{ok, Req, Env}.
+
 %% Internal functions.
 %% Internal functions.
 
 
 -spec do_charset_crash(_) -> no_return().
 -spec do_charset_crash(_) -> no_return().