/deps/webmachine/demo/src/demo_fs_resource.erl
https://code.google.com/p/zotonic/ · Erlang · 157 lines · 133 code · 19 blank · 5 comment · 0 complexity · ca4eba93dec0d8b24fe74653885b1621 MD5 · raw file
- %% @author Bryan Fink <bryan@basho.com>
- %% @author Andy Gross <andy@basho.com>
- %% @author Justin Sheehy <justin@basho.com>
- %% @copyright 2008-2009 Basho Technologies, Inc.
- -module(demo_fs_resource).
- -export([init/1]).
- -export([allowed_methods/2,
- resource_exists/2,
- last_modified/2,
- content_types_provided/2,
- content_types_accepted/2,
- delete_resource/2,
- post_is_create/2,
- create_path/2,
- provide_content/2,
- accept_content/2,
- generate_etag/2]).
- -record(context, {root,response_body=undefined,metadata=[]}).
- -include_lib("kernel/include/file.hrl").
- -include_lib("webmachine/include/webmachine.hrl").
- init(ConfigProps) ->
- {root, Root} = proplists:lookup(root, ConfigProps),
- {ok, #context{root=Root}}.
-
- allowed_methods(ReqData, Context) ->
- {['HEAD', 'GET', 'PUT', 'DELETE', 'POST'], ReqData, Context}.
- file_path(Context, Name) ->
- RelName = case hd(Name) of
- "/" -> tl(Name);
- _ -> Name
- end,
- filename:join([Context#context.root, RelName]).
- file_exists(Context, Name) ->
- NamePath = file_path(Context, Name),
- case filelib:is_regular(NamePath) of
- true ->
- {true, NamePath};
- false ->
- false
- end.
- resource_exists(ReqData, Context) ->
- Path = wrq:disp_path(ReqData),
- case file_exists(Context, Path) of
- {true, _} ->
- {true, ReqData, Context};
- _ ->
- case Path of
- "p" -> {true, ReqData, Context};
- _ -> {false, ReqData, Context}
- end
- end.
- maybe_fetch_object(Context, Path) ->
- % if returns {true, NewContext} then NewContext has response_body
- case Context#context.response_body of
- undefined ->
- case file_exists(Context, Path) of
- {true, FullPath} ->
- {ok, Value} = file:read_file(FullPath),
- {true, Context#context{response_body=Value}};
- false ->
- {false, Context}
- end;
- _Body ->
- {true, Context}
- end.
- content_types_provided(ReqData, Context) ->
- CT = webmachine_util:guess_mime(wrq:disp_path(ReqData)),
- {[{CT, provide_content}], ReqData,
- Context#context{metadata=[{'content-type', CT}|Context#context.metadata]}}.
- content_types_accepted(ReqData, Context) ->
- CT = case wrq:get_req_header_lc("content-type", ReqData) of
- undefined -> "application/octet-stream";
- X -> X
- end,
- {MT, _Params} = webmachine_util:media_type_to_detail(CT),
- {[{MT, accept_content}], ReqData,
- Context#context{metadata=[{'content-type', MT}|Context#context.metadata]}}.
- accept_content(ReqData, Context) ->
- Path = wrq:disp_path(ReqData),
- FP = file_path(Context, Path),
- ok = filelib:ensure_dir(filename:dirname(FP)),
- ReqData1 = case file_exists(Context, Path) of
- {true, _} ->
- ReqData;
- _ ->
- LOC = "http://" ++
- wrq:get_req_header_lc("host", ReqData) ++
- "/fs/" ++ Path,
- wrq:set_resp_header("Location", LOC, ReqData)
- end,
- Value = wrq:req_body(ReqData1),
- case file:write_file(FP, Value) of
- ok ->
- {true, wrq:set_resp_body(Value, ReqData1), Context};
- Err ->
- {{error, Err}, ReqData1, Context}
- end.
- post_is_create(ReqData, Context) ->
- {true, ReqData, Context}.
- create_path(ReqData, Context) ->
- case wrq:get_req_header_lc("slug", ReqData) of
- undefined -> {undefined, ReqData, Context};
- Slug ->
- case file_exists(Context, Slug) of
- {true, _} -> {undefined, ReqData, Context};
- _ -> {Slug, ReqData, Context}
- end
- end.
- delete_resource(ReqData, Context) ->
- case file:delete(file_path(
- Context, wrq:disp_path(ReqData))) of
- ok -> {true, ReqData, Context};
- _ -> {false, ReqData, Context}
- end.
- provide_content(ReqData, Context) ->
- case maybe_fetch_object(Context, wrq:disp_path(ReqData)) of
- {true, NewContext} ->
- Body = NewContext#context.response_body,
- {Body, ReqData, Context};
- {false, NewContext} ->
- {error, ReqData, NewContext}
- end.
- last_modified(ReqData, Context) ->
- {true, FullPath} = file_exists(Context,
- wrq:disp_path(ReqData)),
- LMod = filelib:last_modified(FullPath),
- {LMod, ReqData, Context#context{metadata=[{'last-modified',
- httpd_util:rfc1123_date(LMod)}|Context#context.metadata]}}.
- hash_body(Body) -> mochihex:to_hex(binary_to_list(crypto:sha(Body))).
- generate_etag(ReqData, Context) ->
- case maybe_fetch_object(Context, wrq:disp_path(ReqData)) of
- {true, BodyContext} ->
- ETag = hash_body(BodyContext#context.response_body),
- {ETag, ReqData,
- BodyContext#context{metadata=[{etag,ETag}|
- BodyContext#context.metadata]}};
- _ ->
- {undefined, ReqData, Context}
- end.