]> review.fuel-infra Code Review - packages/trusty/rabbitmq-server.git/blob
948826839cb204f7cd285d1e01d7f7d6dbba7c37
[packages/trusty/rabbitmq-server.git] /
1 %% @author Bryan Fink <bryan@basho.com>
2 %% @author Andy Gross <andy@basho.com>
3 %% @author Justin Sheehy <justin@basho.com>
4 %% @copyright 2008-2009 Basho Technologies, Inc.
5
6 -module(webmachine_demo_fs_resource).
7 -export([init/1]).
8 -export([allowed_methods/2,
9          resource_exists/2,
10          last_modified/2,
11          content_types_provided/2,
12          content_types_accepted/2,
13          delete_resource/2,
14          post_is_create/2,
15          create_path/2,
16          provide_content/2,
17          accept_content/2,
18          generate_etag/2]).
19
20 -record(context, {root,response_body=undefined,metadata=[]}).
21
22 -include_lib("kernel/include/file.hrl").
23 -include_lib("webmachine/include/webmachine.hrl").
24
25 init(ConfigProps) ->
26     {root, Root} = proplists:lookup(root, ConfigProps),
27     {ok, #context{root=Root}}.
28     
29 allowed_methods(ReqData, Context) ->
30     {['HEAD', 'GET', 'PUT', 'DELETE', 'POST'], ReqData, Context}.
31
32 file_path(_Context, []) ->
33     false;
34 file_path(Context, Name) ->
35     RelName = case hd(Name) of
36         "/" -> tl(Name);
37         _ -> Name
38     end,
39     filename:join([Context#context.root, RelName]).
40
41 file_exists(Context, Name) ->
42     NamePath = file_path(Context, Name),
43     case filelib:is_regular(NamePath) of 
44         true ->
45             {true, NamePath};
46         false ->
47             false
48     end.
49
50 resource_exists(ReqData, Context) ->
51     Path = wrq:disp_path(ReqData),
52     case file_exists(Context, Path) of 
53         {true, _} ->
54             {true, ReqData, Context};
55         _ ->
56             case Path of
57                 "p" -> {true, ReqData, Context};
58                 _ -> {false, ReqData, Context}
59             end
60     end.
61
62 maybe_fetch_object(Context, Path) ->
63     % if returns {true, NewContext} then NewContext has response_body
64     case Context#context.response_body of
65         undefined ->
66             case file_exists(Context, Path) of 
67                 {true, FullPath} ->
68                     {ok, Value} = file:read_file(FullPath),
69                     {true, Context#context{response_body=Value}};
70                 false ->
71                     {false, Context}
72             end;
73         _Body ->
74             {true, Context}
75     end.
76
77 content_types_provided(ReqData, Context) ->
78     CT = webmachine_util:guess_mime(wrq:disp_path(ReqData)),
79     {[{CT, provide_content}], ReqData,
80      Context#context{metadata=[{'content-type', CT}|Context#context.metadata]}}.
81
82 content_types_accepted(ReqData, Context) ->
83     CT = case wrq:get_req_header("content-type", ReqData) of
84              undefined -> "application/octet-stream";
85              X -> X
86          end,
87     {MT, _Params} = webmachine_util:media_type_to_detail(CT),
88     {[{MT, accept_content}], ReqData,
89      Context#context{metadata=[{'content-type', MT}|Context#context.metadata]}}.
90
91 accept_content(ReqData, Context) ->
92     Path = wrq:disp_path(ReqData),
93     FP = file_path(Context, Path),
94     ok = filelib:ensure_dir(FP),
95     ReqData1 = case file_exists(Context, Path) of 
96         {true, _} ->
97             ReqData;
98         _ ->
99             LOC = "http://" ++
100                    wrq:get_req_header("host", ReqData) ++
101                    "/fs/" ++ Path,
102             wrq:set_resp_header("Location", LOC, ReqData)
103     end,
104     Value = wrq:req_body(ReqData1),
105     case file:write_file(FP, Value) of
106         ok ->
107             {true, wrq:set_resp_body(Value, ReqData1), Context};
108         Err ->
109             {{error, Err}, ReqData1, Context}
110     end.    
111
112 post_is_create(ReqData, Context) ->
113     {true, ReqData, Context}.
114
115 create_path(ReqData, Context) ->
116     case wrq:get_req_header("slug", ReqData) of
117         undefined -> {undefined, ReqData, Context};
118         Slug ->
119             case file_exists(Context, Slug) of
120                 {true, _} -> {undefined, ReqData, Context};
121                 _ -> {Slug, ReqData, Context}
122             end
123     end.
124
125 delete_resource(ReqData, Context) ->
126     case file:delete(file_path(
127                        Context, wrq:disp_path(ReqData))) of
128         ok -> {true, ReqData, Context};
129         _ -> {false, ReqData, Context}
130     end.
131
132 provide_content(ReqData, Context) ->
133     case maybe_fetch_object(Context, wrq:disp_path(ReqData)) of 
134         {true, NewContext} ->
135             Body = NewContext#context.response_body,
136             {Body, ReqData, Context};
137         {false, NewContext} ->
138             {error, ReqData, NewContext}
139     end.
140
141 last_modified(ReqData, Context) ->
142     {true, FullPath} = file_exists(Context,
143                                    wrq:disp_path(ReqData)),
144     LMod = filelib:last_modified(FullPath),
145     {LMod, ReqData, Context#context{metadata=[{'last-modified',
146                     httpd_util:rfc1123_date(LMod)}|Context#context.metadata]}}.
147
148 hash_body(Body) -> mochihex:to_hex(binary_to_list(crypto:sha(Body))).
149
150 generate_etag(ReqData, Context) ->
151     case maybe_fetch_object(Context, wrq:disp_path(ReqData)) of
152         {true, BodyContext} ->
153             ETag = hash_body(BodyContext#context.response_body),
154             {ETag, ReqData,
155              BodyContext#context{metadata=[{etag,ETag}|
156                                            BodyContext#context.metadata]}};
157         _ ->
158             {undefined, ReqData, Context}
159     end.