Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBadlop <badlop@process-one.net>2013-06-25 12:37:03 +0400
committerBadlop <badlop@process-one.net>2013-06-25 12:37:03 +0400
commit45db79b9a7160357eebb43192b93be83bf1f3ea5 (patch)
treea008e8228944abfa3659847b003060185d1728f5
parent870edd13e560453d2e93c98fdc8ba98b8b319a3f (diff)
Normalize HTTP path (thanks to Justin Kirby)
-rw-r--r--src/web/ejabberd_http.erl15
-rw-r--r--src/web/mod_http_fileserver.erl3
2 files changed, 15 insertions, 3 deletions
diff --git a/src/web/ejabberd_http.erl b/src/web/ejabberd_http.erl
index 612a544bd..d5abc516c 100644
--- a/src/web/ejabberd_http.erl
+++ b/src/web/ejabberd_http.erl
@@ -372,7 +372,7 @@ process_request(#state{request_method = Method,
{'EXIT', _} ->
make_bad_request(State);
{NPath, Query} ->
- LPath = [path_decode(NPE) || NPE <- string:tokens(NPath, "/")],
+ LPath = normalize_path([NPE || NPE <- string:tokens(path_decode(NPath), "/")]),
LQuery = case (catch parse_urlencoded(Query)) of
{'EXIT', _Reason} ->
[];
@@ -449,7 +449,7 @@ process_request(#state{request_method = Method,
{'EXIT', _} ->
make_bad_request(State);
{NPath, _Query} ->
- LPath = [path_decode(NPE) || NPE <- string:tokens(NPath, "/")],
+ LPath = normalize_path([NPE || NPE <- string:tokens(path_decode(NPath), "/")]),
LQuery = case (catch parse_urlencoded(Data)) of
{'EXIT', _Reason} ->
[];
@@ -1125,3 +1125,14 @@ drop_spaces(YS=[X|XS]) ->
false ->
YS
end.
+
+normalize_path(Path) ->
+ normalize_path(Path, []).
+
+normalize_path([], Norm) -> lists:reverse(Norm);
+normalize_path([".."|Path], Norm) ->
+ normalize_path(Path, Norm);
+normalize_path([_Parent, ".."|Path], Norm) ->
+ normalize_path(Path, Norm);
+normalize_path([Part | Path], Norm) ->
+ normalize_path(Path, [Part|Norm]).
diff --git a/src/web/mod_http_fileserver.erl b/src/web/mod_http_fileserver.erl
index 71a627208..292a460a5 100644
--- a/src/web/mod_http_fileserver.erl
+++ b/src/web/mod_http_fileserver.erl
@@ -303,7 +303,7 @@ process(LocalPath, Request) ->
add_to_log(FileSize, Code, Request),
{Code, Headers, Contents}
catch
- exit:{noproc, _} ->
+ exit:{noproc, _} ->
?ERROR_MSG("Received an HTTP request with Host ~p, but couldn't find the related "
"ejabberd virtual host", [Request#request.host]),
ejabberd_web:error(not_found)
@@ -313,6 +313,7 @@ serve(LocalPath, DocRoot, DirectoryIndices, CustomHeaders, DefaultContentType, C
FileName = filename:join(filename:split(DocRoot) ++ LocalPath),
case file:read_file_info(FileName) of
{error, enoent} -> ?HTTP_ERR_FILE_NOT_FOUND;
+ {error, enotdir} -> ?HTTP_ERR_FILE_NOT_FOUND;
{error, eacces} -> ?HTTP_ERR_FORBIDDEN;
{ok, #file_info{type = directory}} -> serve_index(FileName,
DirectoryIndices,