Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

126 lines (92 sloc) 2.925 kb
<html>
<h2> File upload </h2>
<p>This page shows how to upload a file to the webserver, nothing of course
actually gets written to disk, but the upload code is
<a href="code.yaws?file=/upload.yaws">here in file upload.yaws</a>
</p>
<erl>
-record(upload, {
fd,
filename,
last}).
-define(DIR, "/tmp/YawsTestUploads/").
out(A) when A#arg.state == undefined ->
State = #upload{},
multipart(A, State);
out(A) ->
multipart(A, A#arg.state).
err() ->
{ehtml,
{p, [], "error"}}.
multipart(A, State) ->
Parse = yaws_api:parse_multipart_post(A),
case Parse of
{cont, Cont, Res} ->
case addFileChunk(A, Res, State) of
{done, Result} ->
Result;
{cont, NewState} ->
{get_more, Cont, NewState}
end;
{result, Res} ->
case addFileChunk(A, Res, State#upload{last=true}) of
{done, Result} ->
Result;
{cont, _} ->
err()
end;
{error, _Reason} ->
err()
end.
addFileChunk(A, [{part_body, Data}|Res], State) ->
addFileChunk(A, [{body, Data}|Res], State);
addFileChunk(_A, [], State) when State#upload.last==true,
State#upload.filename /= undefined,
State#upload.fd /= undefined ->
file:close(State#upload.fd),
%%file:delete([?DIR,State#upload.filename]),
Res = {ehtml,
{p,[], "File upload done"}},
{done, Res};
addFileChunk(A, [], State) when State#upload.last==true ->
{done, err()};
addFileChunk(_A, [], State) ->
{cont, State};
addFileChunk(A, [{head, {_Name, Opts}}|Res], State ) ->
case lists:keysearch("filename", 1, Opts) of
{value, {_, Fname0}} ->
Fname = yaws_api:sanitize_file_name(basename(Fname0)),
%% we must not put the file in the
%% docroot, it may execute uploade code if the
%% file is a .yaws file !!!!!
file:make_dir(?DIR),
case file:open([?DIR, Fname] ,[write]) of
{ok, Fd} ->
S2 = State#upload{filename = Fname,
fd = Fd},
addFileChunk(A, Res, S2);
Err ->
{done, err()}
end;
false ->
addFileChunk(A,Res,State)
end;
addFileChunk(A, [{body, Data}|Res], State)
when State#upload.filename /= undefined ->
case file:write(State#upload.fd, Data) of
ok ->
addFileChunk(A, Res, State);
Err ->
{done, err()}
end.
basename(FilePath) ->
case string:rchr(FilePath, $\\) of
0 ->
%% probably not a DOS name
filename:basename(FilePath);
N ->
%% probably a DOS name, remove everything after last \
basename(string:substr(FilePath, N+1))
end.
</erl>
</html>
Jump to Line
Something went wrong with that request. Please try again.