diff --git a/mod_http_upload/README.txt b/mod_http_upload/README.txt index 9a842a2..8cc9160 100644 --- a/mod_http_upload/README.txt +++ b/mod_http_upload/README.txt @@ -66,6 +66,13 @@ The configurable mod_http_upload options are: This option limits the acceptable file size. Either a number of bytes (larger than zero) or 'infinity' must be specified. +- jid_in_url (default: 'sha1') + + When this option is set to 'node', the node identifier of the user's JID + (i.e., the user name) is included in the GET and PUT URLs generated by + mod_http_upload. Otherwise, a SHA-1 hash of the user's bare JID is + included instead. + - docroot (default: 'undefined') Uploaded files are stored below the directory specified (as an absolute diff --git a/mod_http_upload/src/mod_http_upload.erl b/mod_http_upload/src/mod_http_upload.erl index b9bcf72..e704dbf 100644 --- a/mod_http_upload/src/mod_http_upload.erl +++ b/mod_http_upload/src/mod_http_upload.erl @@ -75,6 +75,7 @@ name :: binary(), access :: atom(), max_size :: pos_integer() | infinity, + jid_in_url :: sha1 | node, docroot :: binary(), put_url :: binary(), get_url :: binary(), @@ -142,6 +143,10 @@ mod_opt_type(max_size) -> fun (I) when is_integer(I), I > 0 -> I; (infinity) -> infinity end; +mod_opt_type(jid_in_url) -> + fun(sha1) -> sha1; + (node) -> node + end; mod_opt_type(docroot) -> fun iolist_to_binary/1; mod_opt_type(put_url) -> @@ -157,7 +162,8 @@ mod_opt_type(service_url) -> (<<"https://", _/binary>> = URL) -> URL end; mod_opt_type(_) -> - [host, name, access, max_size, docroot, put_url, get_url, service_url]. + [host, name, access, max_size, jid_in_url, docroot, + put_url, get_url, service_url]. %%-------------------------------------------------------------------- %% gen_server callbacks. @@ -176,6 +182,11 @@ init({ServerHost, Opts}) -> fun (I) when is_integer(I), I > 0 -> I; (infinity) -> infinity end, 104857600), + JIDinURL = gen_mod:get_opt(jid_in_url, Opts, + fun(sha1) -> sha1; + (node) -> node + end, + sha1), DocRoot = gen_mod:get_opt(docroot, Opts, fun iolist_to_binary/1, undefined), PutURL = gen_mod:get_opt(put_url, Opts, @@ -210,7 +221,9 @@ init({ServerHost, Opts}) -> end, ejabberd_router:register_route(Host), {ok, #state{server_host = ServerHost, host = Host, name = Name, - access = Access, max_size = MaxSize, docroot = DocRoot, + access = Access, max_size = MaxSize, + jid_in_url = JIDinURL, + docroot = DocRoot, put_url = str:strip(PutURL, right, $/), get_url = str:strip(GetURL, right, $/), service_url = ServiceURL}}. @@ -440,14 +453,15 @@ create_slot(#state{service_url = undefined, max_size = MaxSize}, ?INFO_MSG("Rejecting file ~s from ~s (too large: ~B bytes)", [File, User, Size]), {error, ?ERRT_NOT_ACCEPTABLE(Lang, Text)}; -create_slot(#state{service_url = undefined}, User, File, _Size, _ContentType, - _Lang) -> - UserHash = p1_sha:sha(User), +create_slot(#state{service_url = undefined, + jid_in_url = JIDinURL}, + User, File, _Size, _ContentType, _Lang) -> + UserStr = make_user_string(User, JIDinURL), RandStr = make_rand_string(40), SaneFile = re:replace(File, <<"[^a-zA-Z0-9_.-]">>, <<$_>>, [global, {return, binary}]), ?INFO_MSG("Got HTTP upload slot for ~s (file: ~s)", [User, File]), - {ok, [UserHash, RandStr, SaneFile]}; + {ok, [UserStr, RandStr, SaneFile]}; create_slot(#state{service_url = ServiceURL}, User, File, Size, ContentType, _Lang) -> Options = [{body_format, binary}, {full_result, false}], @@ -520,6 +534,14 @@ slot_el(PutURL, GetURL) -> #xmlel{name = <<"get">>, children = [{xmlcdata, GetURL}]}]}. +-spec make_user_string(binary(), sha1 | node) -> binary(). + +make_user_string(User, sha1) -> + p1_sha:sha(User); +make_user_string(User, node) -> + [Node, _Domain] = binary:split(User, <<$@>>), + re:replace(Node, <<"[^a-zA-Z0-9_.-]">>, <<$_>>, [global, {return, binary}]). + -spec make_rand_string(non_neg_integer()) -> binary(). make_rand_string(Length) -> @@ -630,8 +652,14 @@ remove_user(User, Server) -> undefined -> ok; DocRoot -> - UserHash = p1_sha:sha(LUser), - UserDir = str:join([DocRoot, UserHash], <<$/>>), + JIDinURL = gen_mod:get_module_opt(LServer, ?MODULE, jid_in_url, + fun(sha1) -> sha1; + (node) -> node + end, + sha1), + UserStr = make_user_string(<>, + JIDinURL), + UserDir = str:join([DocRoot, UserStr], <<$/>>), case del_tree(UserDir) of ok -> ?INFO_MSG("Removed HTTP upload directory of ~s@~s",