diff options
Diffstat (limited to 'src/mod_http_fileserver.erl')
-rw-r--r-- | src/mod_http_fileserver.erl | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/src/mod_http_fileserver.erl b/src/mod_http_fileserver.erl index c1c5b6461..f34936724 100644 --- a/src/mod_http_fileserver.erl +++ b/src/mod_http_fileserver.erl @@ -66,6 +66,8 @@ {-1, 403, [], <<"Forbidden">>}). -define(HTTP_ERR_REQUEST_AUTH, {-1, 401, ?REQUEST_AUTH_HEADERS, <<"Unauthorized">>}). +-define(HTTP_ERR_HOST_UNKNOWN, + {-1, 410, [], <<"Host unknown">>}). -define(DEFAULT_CONTENT_TYPE, <<"application/octet-stream">>). @@ -178,10 +180,15 @@ check_docroot_defined(DocRoot, Host) -> end. check_docroot_exists(DocRoot) -> - case file:read_file_info(DocRoot) of - {error, Reason} -> - throw({error_access_docroot, DocRoot, Reason}); - {ok, FI} -> FI + case filelib:ensure_dir(filename:join(DocRoot, "foo")) of + ok -> + case file:read_file_info(DocRoot) of + {error, Reason} -> + throw({error_access_docroot, DocRoot, Reason}); + {ok, FI} -> FI + end; + {error, Reason} -> + throw({error_access_docroot, DocRoot, Reason}) end. check_docroot_is_dir(DRInfo, DocRoot) -> @@ -297,18 +304,22 @@ code_change(_OldVsn, State, _Extra) -> %% Returns the page to be sent back to the client and/or HTTP status code. process(LocalPath, #request{host = Host, auth = Auth, headers = RHeaders} = Request) -> ?DEBUG("Requested ~p", [LocalPath]), - try gen_server:call(get_proc_name(Host), {serve, LocalPath, Auth, RHeaders}) of - {FileSize, Code, Headers, Contents} -> - add_to_log(FileSize, Code, Request), - {Code, Headers, Contents} - catch - 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) + try + VHost = ejabberd_router:host_of_route(Host), + {FileSize, Code, Headers, Contents} = + gen_server:call(get_proc_name(VHost), + {serve, LocalPath, Auth, RHeaders}), + add_to_log(FileSize, Code, Request#request{host = VHost}), + {Code, Headers, Contents} + catch _:{Why, _} when Why == noproc; Why == invalid_domain; Why == unregistered_route -> + ?DEBUG("Received an HTTP request with Host: ~s, " + "but couldn't find the related " + "ejabberd virtual host", [Host]), + {FileSize1, Code1, Headers1, Contents1} = ?HTTP_ERR_HOST_UNKNOWN, + add_to_log(FileSize1, Code1, Request#request{host = ?MYNAME}), + {Code1, Headers1, Contents1} end. - serve(LocalPath, Auth, DocRoot, DirectoryIndices, CustomHeaders, DefaultContentType, ContentTypes, UserAccess, IfModifiedSince) -> CanProceed = case {UserAccess, Auth} of @@ -425,7 +436,7 @@ add_to_log(File, FileSize, Code, Request) -> IP = ip_to_string(element(1, Request#request.ip)), Path = join(Request#request.path, "/"), Query = case stringify_query(Request#request.q) of - [] -> + <<"">> -> ""; String -> [$? | String] @@ -445,11 +456,13 @@ add_to_log(File, FileSize, Code, Request) -> FileSize, Referer, UserAgent]). stringify_query(Q) -> - join( - lists:map(fun(E) -> - lists:concat([binary_to_list(element(1, E)), "=", binary_to_list(element(2, E))]) - end, Q), - "&"). + stringify_query(Q, []). +stringify_query([], Res) -> + join(lists:reverse(Res), "&"); +stringify_query([{nokey, _B} | Q], Res) -> + stringify_query(Q, Res); +stringify_query([{A, B} | Q], Res) -> + stringify_query(Q, [join([A,B], "=") | Res]). find_header(Header, Headers, Default) -> case lists:keysearch(Header, 1, Headers) of |