Let client retry HTTP upload on file size mismatch
Let the main mod_http_upload process look at the size of an HTTP upload rather than performing this check in the ejabberd_http handler. This way, the upload slot won't be invalidated if the size of the uploaded file doesn't match the size requested for the slot. The PUT request is still rejected, but the client now has a chance to retry the upload.
This commit is contained in:
parent
bcf07fd032
commit
f7f40cf9a6
|
@ -321,22 +321,24 @@ init({ServerHost, Opts}) ->
|
|||
-> {reply, {ok, pos_integer(), binary(),
|
||||
pos_integer() | undefined,
|
||||
pos_integer() | undefined}, state()} |
|
||||
{reply, {error, binary()}, state()} | {noreply, state()}.
|
||||
{reply, {error, atom()}, state()} | {noreply, state()}.
|
||||
|
||||
handle_call({use_slot, Slot}, _From, #state{file_mode = FileMode,
|
||||
dir_mode = DirMode,
|
||||
get_url = GetPrefix,
|
||||
thumbnail = Thumbnail,
|
||||
docroot = DocRoot} = State) ->
|
||||
handle_call({use_slot, Slot, Size}, _From, #state{file_mode = FileMode,
|
||||
dir_mode = DirMode,
|
||||
get_url = GetPrefix,
|
||||
thumbnail = Thumbnail,
|
||||
docroot = DocRoot} = State) ->
|
||||
case get_slot(Slot, State) of
|
||||
{ok, {Size, Timer}} ->
|
||||
timer:cancel(Timer),
|
||||
NewState = del_slot(Slot, State),
|
||||
Path = str:join([DocRoot | Slot], <<$/>>),
|
||||
{reply, {ok, Size, Path, FileMode, DirMode, GetPrefix, Thumbnail},
|
||||
{reply, {ok, Path, FileMode, DirMode, GetPrefix, Thumbnail},
|
||||
NewState};
|
||||
{ok, {_WrongSize, _Timer}} ->
|
||||
{reply, {error, size_mismatch}, State};
|
||||
error ->
|
||||
{reply, {error, <<"Invalid slot">>}, State}
|
||||
{reply, {error, invalid_slot}, State}
|
||||
end;
|
||||
handle_call(get_docroot, _From, #state{docroot = DocRoot} = State) ->
|
||||
{reply, {ok, DocRoot}, State};
|
||||
|
@ -406,9 +408,8 @@ process(LocalPath, #request{method = Method, host = Host, ip = IP})
|
|||
process(_LocalPath, #request{method = 'PUT', host = Host, ip = IP,
|
||||
data = Data} = Request) ->
|
||||
{Proc, Slot} = parse_http_request(Request),
|
||||
case catch gen_server:call(Proc, {use_slot, Slot}) of
|
||||
{ok, Size, Path, FileMode, DirMode, GetPrefix, Thumbnail}
|
||||
when byte_size(Data) == Size ->
|
||||
case catch gen_server:call(Proc, {use_slot, Slot, byte_size(Data)}) of
|
||||
{ok, Path, FileMode, DirMode, GetPrefix, Thumbnail} ->
|
||||
?DEBUG("Storing file from ~s for ~s: ~s",
|
||||
[?ADDR_TO_STR(IP), Host, Path]),
|
||||
case store_file(Path, Data, FileMode, DirMode,
|
||||
|
@ -422,13 +423,13 @@ process(_LocalPath, #request{method = 'PUT', host = Host, ip = IP,
|
|||
[Path, ?ADDR_TO_STR(IP), Host, ?FORMAT(Error)]),
|
||||
http_response(Host, 500)
|
||||
end;
|
||||
{ok, Size, Path, _FileMode, _DirMode, _GetPrefix, _Thumbnail} ->
|
||||
?INFO_MSG("Rejecting file ~s from ~s for ~s: Size is ~B, not ~B",
|
||||
[Path, ?ADDR_TO_STR(IP), Host, byte_size(Data), Size]),
|
||||
{error, size_mismatch} ->
|
||||
?INFO_MSG("Rejecting file from ~s for ~s: Unexpected size (~B)",
|
||||
[?ADDR_TO_STR(IP), Host, byte_size(Data)]),
|
||||
http_response(Host, 413);
|
||||
{error, Error} ->
|
||||
?INFO_MSG("Rejecting file from ~s for ~s: ~p",
|
||||
[?ADDR_TO_STR(IP), Host, Error]),
|
||||
{error, invalid_slot} ->
|
||||
?INFO_MSG("Rejecting file from ~s for ~s: Invalid slot",
|
||||
[?ADDR_TO_STR(IP), Host]),
|
||||
http_response(Host, 403);
|
||||
Error ->
|
||||
?ERROR_MSG("Cannot handle PUT request from ~s for ~s: ~p",
|
||||
|
|
Loading…
Reference in New Issue