diff options
-rw-r--r-- | src/mod_http_upload.erl | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index 09fd66d3e..8ed47f69d 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -31,9 +31,6 @@ -define(SERVICE_REQUEST_TIMEOUT, 5000). % 5 seconds. -define(CALL_TIMEOUT, 60000). % 1 minute. -define(SLOT_TIMEOUT, timer:hours(5)). --define(URL_ENC(URL), binary_to_list(misc:url_encode(URL))). --define(ADDR_TO_STR(IP), ejabberd_config:may_hide_data(misc:ip_to_list(IP))). --define(STR_TO_INT(Str, B), binary_to_integer(iolist_to_binary(Str), B)). -define(DEFAULT_CONTENT_TYPE, <<"application/octet-stream">>). -define(CONTENT_TYPES, [{<<".avi">>, <<"video/avi">>}, @@ -170,11 +167,11 @@ mod_opt_type(jid_in_url) -> end; mod_opt_type(file_mode) -> fun(undefined) -> undefined; - (Mode) -> ?STR_TO_INT(Mode, 8) + (Mode) -> binary_to_integer(iolist_to_binary(Mode), 8) end; mod_opt_type(dir_mode) -> fun(undefined) -> undefined; - (Mode) -> ?STR_TO_INT(Mode, 8) + (Mode) -> binary_to_integer(iolist_to_binary(Mode), 8) end; mod_opt_type(docroot) -> fun iolist_to_binary/1; @@ -375,7 +372,7 @@ process(LocalPath, #request{method = Method, host = Host, ip = IP}) Method == 'GET' orelse Method == 'HEAD' -> ?DEBUG("Rejecting ~s request from ~s for ~s: Too few path components", - [Method, ?ADDR_TO_STR(IP), Host]), + [Method, encode_addr(IP), Host]), http_response(404); process(_LocalPath, #request{method = 'PUT', host = Host, ip = IP, length = Length} = Request) -> @@ -383,7 +380,7 @@ process(_LocalPath, #request{method = 'PUT', host = Host, ip = IP, case catch gen_server:call(Proc, {use_slot, Slot, Length}, ?CALL_TIMEOUT) of {ok, Path, FileMode, DirMode, GetPrefix, Thumbnail, CustomHeaders} -> ?DEBUG("Storing file from ~s for ~s: ~s", - [?ADDR_TO_STR(IP), Host, Path]), + [encode_addr(IP), Host, Path]), case store_file(Path, Request, FileMode, DirMode, GetPrefix, Slot, Thumbnail) of ok -> @@ -392,24 +389,24 @@ process(_LocalPath, #request{method = 'PUT', host = Host, ip = IP, http_response(201, Headers ++ CustomHeaders, OutData); {error, closed} -> ?DEBUG("Cannot store file ~s from ~s for ~s: connection closed", - [Path, ?ADDR_TO_STR(IP), Host]), + [Path, encode_addr(IP), Host]), http_response(404); {error, Error} -> ?ERROR_MSG("Cannot store file ~s from ~s for ~s: ~s", - [Path, ?ADDR_TO_STR(IP), Host, format_error(Error)]), + [Path, encode_addr(IP), Host, format_error(Error)]), http_response(500) end; {error, size_mismatch} -> ?INFO_MSG("Rejecting file ~s from ~s for ~s: Unexpected size (~B)", - [lists:last(Slot), ?ADDR_TO_STR(IP), Host, Length]), + [lists:last(Slot), encode_addr(IP), Host, Length]), http_response(413); {error, invalid_slot} -> ?INFO_MSG("Rejecting file ~s from ~s for ~s: Invalid slot", - [lists:last(Slot), ?ADDR_TO_STR(IP), Host]), + [lists:last(Slot), encode_addr(IP), Host]), http_response(403); Error -> ?ERROR_MSG("Cannot handle PUT request from ~s for ~s: ~p", - [?ADDR_TO_STR(IP), Host, Error]), + [encode_addr(IP), Host, Error]), http_response(500) end; process(_LocalPath, #request{method = Method, host = Host, ip = IP} = Request) @@ -422,7 +419,7 @@ process(_LocalPath, #request{method = Method, host = Host, ip = IP} = Request) case file:open(Path, [read]) of {ok, Fd} -> file:close(Fd), - ?INFO_MSG("Serving ~s to ~s", [Path, ?ADDR_TO_STR(IP)]), + ?INFO_MSG("Serving ~s to ~s", [Path, encode_addr(IP)]), ContentType = guess_content_type(FileName), Headers1 = case ContentType of <<"image/", _SubType/binary>> -> []; @@ -437,30 +434,30 @@ process(_LocalPath, #request{method = Method, host = Host, ip = IP} = Request) http_response(200, Headers3, {file, Path}); {error, eacces} -> ?INFO_MSG("Cannot serve ~s to ~s: Permission denied", - [Path, ?ADDR_TO_STR(IP)]), + [Path, encode_addr(IP)]), http_response(403); {error, enoent} -> ?INFO_MSG("Cannot serve ~s to ~s: No such file", - [Path, ?ADDR_TO_STR(IP)]), + [Path, encode_addr(IP)]), http_response(404); {error, eisdir} -> ?INFO_MSG("Cannot serve ~s to ~s: Is a directory", - [Path, ?ADDR_TO_STR(IP)]), + [Path, encode_addr(IP)]), http_response(404); {error, Error} -> ?INFO_MSG("Cannot serve ~s to ~s: ~s", - [Path, ?ADDR_TO_STR(IP), format_error(Error)]), + [Path, encode_addr(IP), format_error(Error)]), http_response(500) end; Error -> ?ERROR_MSG("Cannot handle ~s request from ~s for ~s: ~p", - [Method, ?ADDR_TO_STR(IP), Host, Error]), + [Method, encode_addr(IP), Host, Error]), http_response(500) end; process(_LocalPath, #request{method = 'OPTIONS', host = Host, ip = IP} = Request) -> ?DEBUG("Responding to OPTIONS request from ~s for ~s", - [?ADDR_TO_STR(IP), Host]), + [encode_addr(IP), Host]), {Proc, _Slot} = parse_http_request(Request), case catch gen_server:call(Proc, get_conf, ?CALL_TIMEOUT) of {ok, _DocRoot, CustomHeaders} -> @@ -468,12 +465,12 @@ process(_LocalPath, #request{method = 'OPTIONS', host = Host, http_response(200, [AllowHeader | CustomHeaders]); Error -> ?ERROR_MSG("Cannot handle OPTIONS request from ~s for ~s: ~p", - [?ADDR_TO_STR(IP), Host, Error]), + [encode_addr(IP), Host, Error]), http_response(500) end; process(_LocalPath, #request{method = Method, host = Host, ip = IP}) -> ?DEBUG("Rejecting ~s request from ~s for ~s", - [Method, ?ADDR_TO_STR(IP), Host]), + [Method, encode_addr(IP), Host]), http_response(405, [{<<"Allow">>, <<"OPTIONS, HEAD, GET, PUT">>}]). %%-------------------------------------------------------------------- @@ -600,12 +597,14 @@ create_slot(#state{service_url = ServiceURL}, Options = [{body_format, binary}, {full_result, false}], HttpOptions = [{timeout, ?SERVICE_REQUEST_TIMEOUT}], SizeStr = integer_to_binary(Size), - GetRequest = binary_to_list(ServiceURL) ++ - "?jid=" ++ ?URL_ENC(jid:encode({U, S, <<"">>})) ++ - "&name=" ++ ?URL_ENC(File) ++ - "&size=" ++ ?URL_ENC(SizeStr) ++ - "&content_type=" ++ ?URL_ENC(ContentType), - case httpc:request(get, {GetRequest, []}, HttpOptions, Options) of + JidStr = jid:encode({U, S, <<"">>}), + GetRequest = <<ServiceURL/binary, + "?jid=", (misc:url_encode(JidStr))/binary, + "&name=", (misc:url_encode(File))/binary, + "&size=", (misc:url_encode(SizeStr))/binary, + "&content_type=", (misc:url_encode(ContentType))/binary>>, + case httpc:request(get, {binary_to_list(GetRequest), []}, + HttpOptions, Options) of {ok, {Code, Body}} when Code >= 200, Code =< 299 -> case binary:split(Body, <<$\n>>, [global, trim]) of [<<"http", _/binary>> = PutURL, @@ -703,6 +702,11 @@ replace_special_chars(S) -> yield_content_type(<<"">>) -> ?DEFAULT_CONTENT_TYPE; yield_content_type(Type) -> Type. +-spec encode_addr(inet:ip_address() | {inet:ip_address(), inet:port_number()} | + undefined) -> binary(). +encode_addr(IP) -> + ejabberd_config:may_hide_data(misc:ip_to_list(IP)). + -spec iq_disco_info(binary(), binary(), binary(), [xdata()]) -> disco_info(). iq_disco_info(Host, Lang, Name, AddInfo) -> Form = case gen_mod:get_module_opt(Host, ?MODULE, max_size) of |