-module(fileupload_resource).
-export([init/1, to_html/2, allowed_methods/2, process_post/2]).
-define(STORE_PATH, "/tmp/fileupload_demo").
-include_lib("webmachine/include/webmachine.hrl").
init([]) -> {ok, no_state}.
allowed_methods(ReqData, C) -> {['GET', 'POST'], ReqData, C}.
process_post(ReqData, C) ->
ContentType = wrq:get_req_header("content-type", ReqData),
Boundary = string:substr(ContentType, string:str(ContentType, "boundary=")
+ length("boundary=")),
{FileName, FileSize, Content} = get_streamed_body(
webmachine_multipart:stream_parts(
wrq:stream_req_body(ReqData, 1024),
Boundary), [],[]),
StorePath = filename:join([?STORE_PATH,"/", FileName]),
filelib:ensure_dir(StorePath),
file:write_file(StorePath, Content),
NewRD = wrq:append_to_response_body(
io_lib:format(
"<html><head><title>Upload Complete</title></head>"
"<body><h1>Upload Complete</h1>"
"<p>Received file ~s (~.2fK)</p></body></html>",
[filename:basename(StorePath), FileSize]), ReqData),
{true, NewRD, C}.
to_html(ReqData, C) ->
{"<html><head><title>Webmachine File Upload Example</title></head>"
"<body><h1>Webmachine File Upload Example</h1>"
"<form action='/' method='POST' enctype='multipart/form-data'>"
"Upload File: <input type='file' name='filedata'/>"
"<input type='submit' value='Upload'></form></body></html>",
ReqData, C}.
get_streamed_body(done_parts, FileName, Acc) ->
Bin = iolist_to_binary(lists:reverse(Acc)),
{FileName, size(Bin)/1024.0, Bin};
get_streamed_body({{"filedata", {Params, _Hdrs}, Content}, Next}, Props, Acc) ->
FileName = binary_to_list(proplists:get_value(<<"filename">>, Params)),
get_streamed_body(Next(),[FileName|Props],[Content|Acc]).