From ba30ac8ce85f15f7af12d531e56981565ebca8ce Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Mon, 4 Jun 2018 22:18:56 +0200 Subject: [PATCH] Return detailed error if HTTP upload is too large If the file size specified in an HTTP upload slot request exceeds the the configured maximum size, include the limit with the stanza error. --- rebar.config | 2 +- src/mod_http_upload.erl | 24 ++++++++++++++++-------- test/upload_tests.erl | 9 ++++++--- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/rebar.config b/rebar.config index a9dccaac1..b35d67602 100644 --- a/rebar.config +++ b/rebar.config @@ -25,7 +25,7 @@ {fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.22"}}}, {stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.11"}}}, {fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.30"}}}, - {xmpp, ".*", {git, "https://github.com/processone/xmpp", "6e3feb7"}}, + {xmpp, ".*", {git, "https://github.com/processone/xmpp", "e26a39a"}}, {fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.14"}}}, {jiffy, ".*", {git, "https://github.com/davisp/jiffy", {tag, "0.14.8"}}}, {p1_oauth2, ".*", {git, "https://github.com/processone/p1_oauth2", {tag, "0.6.3"}}}, diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index 34138240e..1ece69f62 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -531,7 +531,8 @@ process_slot_request(#iq{lang = Lang, from = From} = IQ, case acl:match_rule(ServerHost, Access, From) of allow -> ContentType = yield_content_type(CType), - case create_slot(State, From, File, Size, ContentType, Lang) of + case create_slot(State, From, File, Size, ContentType, XMLNS, + Lang) of {ok, Slot} -> {ok, Timer} = timer:send_after(?SLOT_TIMEOUT, {slot_timed_out, @@ -552,21 +553,28 @@ process_slot_request(#iq{lang = Lang, from = From} = IQ, xmpp:make_error(IQ, xmpp:err_forbidden(Txt, Lang)) end. --spec create_slot(state(), jid(), binary(), pos_integer(), binary(), binary()) +-spec create_slot(state(), jid(), binary(), pos_integer(), binary(), binary(), + binary()) -> {ok, slot()} | {ok, binary(), binary()} | {error, xmlel()}. create_slot(#state{service_url = undefined, max_size = MaxSize}, - JID, File, Size, _ContentType, Lang) when MaxSize /= infinity, - Size > MaxSize -> + JID, File, Size, _ContentType, XMLNS, Lang) + when MaxSize /= infinity, + Size > MaxSize -> Text = {<<"File larger than ~w bytes">>, [MaxSize]}, ?INFO_MSG("Rejecting file ~s from ~s (too large: ~B bytes)", [File, jid:encode(JID), Size]), - {error, xmpp:err_not_acceptable(Text, Lang)}; + Error = xmpp:err_not_acceptable(Text, Lang), + Els = xmpp:get_els(Error), + Els1 = [#upload_file_too_large{'max-file-size' = MaxSize, + xmlns = XMLNS} | Els], + Error1 = xmpp:set_els(Error, Els1), + {error, Error1}; create_slot(#state{service_url = undefined, jid_in_url = JIDinURL, secret_length = SecretLength, server_host = ServerHost, docroot = DocRoot}, - JID, File, Size, _ContentType, Lang) -> + JID, File, Size, _ContentType, _XMLNS, Lang) -> UserStr = make_user_string(JID, JIDinURL), UserDir = <>, case ejabberd_hooks:run_fold(http_upload_slot_request, ServerHost, allow, @@ -583,8 +591,8 @@ create_slot(#state{service_url = undefined, {error, Error} end; create_slot(#state{service_url = ServiceURL}, - #jid{luser = U, lserver = S} = JID, File, Size, ContentType, - Lang) -> + #jid{luser = U, lserver = S} = JID, + File, Size, ContentType, _XMLNS, Lang) -> Options = [{body_format, binary}, {full_result, false}], HttpOptions = [{timeout, ?SERVICE_REQUEST_TIMEOUT}], SizeStr = integer_to_binary(Size), diff --git a/test/upload_tests.erl b/test/upload_tests.erl index aa847e4bd..fa6b04553 100644 --- a/test/upload_tests.erl +++ b/test/upload_tests.erl @@ -188,11 +188,14 @@ max_size_exceed(Config, NS) -> 'content-type' = <>, xmlns = NS}]}) end, - check_size_error(IQErr). + check_size_error(IQErr, Size, NS). -check_size_error(IQErr) -> +check_size_error(IQErr, Size, NS) -> Err = xmpp:get_error(IQErr), - #stanza_error{reason = 'not-acceptable'} = Err. + FileTooLarge = xmpp:get_subtag(Err, #upload_file_too_large{xmlns = NS}), + #stanza_error{reason = 'not-acceptable'} = Err, + #upload_file_too_large{'max-file-size' = MaxSize} = FileTooLarge, + Size > MaxSize. namespaces() -> [?NS_HTTP_UPLOAD_0, ?NS_HTTP_UPLOAD, ?NS_HTTP_UPLOAD_OLD].