@@ -9,7 +9,8 @@ elli_static_test_() ->
99 ? _test (no_file ()),
1010 ? _test (not_found ()),
1111 ? _test (safe_traversal ()),
12- ? _test (unsafe_traversal ())]}.
12+ ? _test (unsafe_traversal ()),
13+ ? _test (invalid_path_separator ())]}.
1314
1415
1516readme () ->
@@ -31,13 +32,18 @@ not_found() ->
3132 ? assertMatch ({{" HTTP/1.1" ,404 ," Not Found" }, _Headers , " Not Found" }, Response ).
3233
3334safe_traversal () ->
34- {ok , Response } = httpc :request (" http://localhost:3000/elli_static/"
35- " ../elli_static/README.md" ),
3635 {ok , File } = file :read_file (" README.md" ),
3736 Expected = binary_to_list (File ),
37+
38+ {ok , Response } = httpc :request (" http://localhost:3000/elli_static/"
39+ " ../elli_static/README.md" ),
3840 ? assertEqual ([integer_to_list (iolist_size (Expected ))],
3941 proplists :get_all_values (" content-length" , element (2 , Response ))),
40- ? assertMatch ({_Status , _Headers , Expected }, Response ).
42+ ? assertMatch ({_Status , _Headers , Expected }, Response ),
43+
44+
45+ % % `Response' should match the same request above
46+ {ok , Response } = httpc :request (" http://localhost:3000/elli_static/./README.md" ).
4147
4248unsafe_traversal () ->
4349 % % compute the relative path to /etc/passwd
@@ -48,6 +54,12 @@ unsafe_traversal() ->
4854 {ok , Response } = httpc :request (" http://localhost:3000/elli_static/" ++ Path ),
4955 ? assertMatch ({{" HTTP/1.1" ,404 ," Not Found" }, _Headers , " Not Found" }, Response ).
5056
57+ invalid_path_separator () ->
58+ % % https://www.ietf.org/rfc/rfc2396.txt defines a path separator to be a
59+ % % single slash
60+ {ok , Response } = httpc :request (" http://localhost:3000////elli_static/README.md" ),
61+ ? assertMatch ({{" HTTP/1.1" ,404 ," Not Found" }, _Headers , " Not Found" }, Response ).
62+
5163setup () ->
5264 {ok , Dir } = file :get_cwd (),
5365 Args = [{<<" /elli_static" >>, {dir , Dir }}],
0 commit comments