@@ -9,7 +9,8 @@ elli_static_test_() ->
9
9
? _test (no_file ()),
10
10
? _test (not_found ()),
11
11
? _test (safe_traversal ()),
12
- ? _test (unsafe_traversal ())]}.
12
+ ? _test (unsafe_traversal ()),
13
+ ? _test (invalid_path_separator ())]}.
13
14
14
15
15
16
readme () ->
@@ -31,13 +32,18 @@ not_found() ->
31
32
? assertMatch ({{" HTTP/1.1" ,404 ," Not Found" }, _Headers , " Not Found" }, Response ).
32
33
33
34
safe_traversal () ->
34
- {ok , Response } = httpc :request (" http://localhost:3000/elli_static/"
35
- " ../elli_static/README.md" ),
36
35
{ok , File } = file :read_file (" README.md" ),
37
36
Expected = binary_to_list (File ),
37
+
38
+ {ok , Response } = httpc :request (" http://localhost:3000/elli_static/"
39
+ " ../elli_static/README.md" ),
38
40
? assertEqual ([integer_to_list (iolist_size (Expected ))],
39
41
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" ).
41
47
42
48
unsafe_traversal () ->
43
49
% % compute the relative path to /etc/passwd
@@ -48,6 +54,12 @@ unsafe_traversal() ->
48
54
{ok , Response } = httpc :request (" http://localhost:3000/elli_static/" ++ Path ),
49
55
? assertMatch ({{" HTTP/1.1" ,404 ," Not Found" }, _Headers , " Not Found" }, Response ).
50
56
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
+
51
63
setup () ->
52
64
{ok , Dir } = file :get_cwd (),
53
65
Args = [{<<" /elli_static" >>, {dir , Dir }}],
0 commit comments