Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 126 lines (92 sloc) 2.925 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
<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>
Something went wrong with that request. Please try again.