Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 548 lines (486 sloc) 17.653 kb
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
1 -module(yaws_dav).
2 %%%-------------------------------------------------------------------
3 %%% Created : 15 May 2005 by Tobbet <tobbe@tornkvist.org>
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
4 %%% Modified: 21 Nov 2005 by <mbj@tail-f.com>
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
5 %%% Desc. : WebDav specifics.
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
6 %%% To use, add a line dav = true in the <server>.
7 %%% TODO: fix more fine-grained permissions
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
8 %%%-------------------------------------------------------------------
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
9 -export([propfind/1, delete/1, put/2, mkcol/1, move/1, copy/1]).
5ef2b8a *** empty log message ***
Tobbe Tornquist authored
10 -export([parse_xml/1, xml_expand/1, xml_expand/2]).
11
ed4466e Fixed include file references.
Tobbe Tornquist authored
12 -include("../include/yaws_dav.hrl").
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
13 -include("../include/yaws_api.hrl").
14 -include("../include/yaws.hrl").
15 -include("yaws_debug.hrl").
ed4466e Fixed include file references.
Tobbe Tornquist authored
16 -include_lib("xmerl/include/xmerl.hrl").
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
17 -include_lib("kernel/include/file.hrl").
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
18
19
20 -define(elog(X,Y), error_logger:info_msg("*elog ~p:~p: " X,
0be3c7e @klacke untabified all of yaws
authored
21 [?MODULE, ?LINE | Y])).
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
22
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
23 delete(A) ->
24 Path = davpath(A),
25 ?elog("DELETE Path=~p~n", [Path]),
26 case rmrf(Path) of
0be3c7e @klacke untabified all of yaws
authored
27 ok -> out200();
28 _ -> out403()
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
29 end.
30
31 put(SC, ARG) ->
32 H = ARG#arg.headers,
33 PPS = SC#sconf.partial_post_size,
455578a @vinoski major trailing whitespace cleanup
vinoski authored
34 CT =
9a74e5a @klacke Major general code cleanup, finally got rid of all the export_all statem...
authored
35 case yaws:to_lower(H#headers.content_type) of
0be3c7e @klacke untabified all of yaws
authored
36 "multipart/form-data"++_ -> multipart;
37 _ -> urlencoded
38 end,
9a74e5a @klacke Major general code cleanup, finally got rid of all the export_all statem...
authored
39 SSL = yaws:is_ssl(SC),
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
40 FName = davpath(ARG),
41 CliSock = ARG#arg.clisock,
42 TmpName = FName ++ ".tmp",
43 %% FIXME: first check if we can write to original file??
44 case file:open(TmpName, [raw,write]) of
0be3c7e @klacke untabified all of yaws
authored
45 {ok, Fd} ->
46 try
47 case H#headers.content_length of
48 undefined ->
49 Chunked = H#headers.transfer_encoding == "chunked",
50 case H#headers.connection of
51 "close" when Chunked == false->
52 store_client_data(Fd, CliSock, all, SSL);
53 _ when Chunked == true ->
54 store_chunked_client_data(Fd, CliSock, SSL)
55 end;
f44be6a @klacke all calls to old deprecated guard tests removed
authored
56 Len when is_integer(PPS) ->
0be3c7e @klacke untabified all of yaws
authored
57 Int_len = list_to_integer(Len),
455578a @vinoski major trailing whitespace cleanup
vinoski authored
58 if
0be3c7e @klacke untabified all of yaws
authored
59 Int_len == 0 ->
60 ok;
61 PPS < Int_len, CT == multipart ->
62 %% FIXME: handle this
e3f358e @vinoski treat src warnings as errors
vinoski authored
63 %% {partial,
64 store_client_data(Fd,CliSock, PPS, SSL); % };
0be3c7e @klacke untabified all of yaws
authored
65 true ->
66 store_client_data(Fd, CliSock, Int_len, SSL)
67 end;
68 Len when PPS == nolimit ->
69 Int_len = list_to_integer(Len),
70 if
71 Int_len == 0 ->
72 ok;
73 true ->
74 store_client_data(Fd, CliSock, Int_len, SSL)
75 end
76 end,
77 file:close(Fd),
78 case file:rename(TmpName, FName) of
79 ok ->
80 out200();
81 Error ->
82 throw(Error)
83 end
84 catch
85 _:_Err ->
86 ?Debug("PUT error ~p\n", [_Err, TmpName]),
87 file:close(Fd),
88 file:delete(TmpName),
89 out409()
90 end;
91 _Error ->
92 ?Debug("PUT error ~p ~p\n", [_Error, TmpName]),
93 out409()
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
94 end.
0be3c7e @klacke untabified all of yaws
authored
95
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
96 mkcol(A) ->
97 Path = davpath(A),
98 case file:make_dir(Path) of
0be3c7e @klacke untabified all of yaws
authored
99 ok ->
100 out201();
101 {error, Reason} ->
102 ?elog("failed to create dir: ~p , reason: ~p~n", [Path, Reason]),
103 out403()
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
104 end.
105
106 copy(A) ->
107 copy_move(A, fun do_copy/2).
108
109 move(A) ->
110 copy_move(A, fun do_move/2).
111
112 copy_move(A, OpF) ->
113 case lists:keysearch("Destination", 3, (A#arg.headers)#headers.other) of
0be3c7e @klacke untabified all of yaws
authored
114 {value, {http_header, _, _, _, Url}} ->
115 %% FIXME: check for weird paths
116 {Url1, _} = yaws_api:url_decode_q_split(Url),
117 Path = Url1 -- davroot(A),
118 From = davpath(A),
119 To = A#arg.docroot ++ "/" ++ Path,
120 ?elog("move from ~p to ~p (~p)\n", [From, To, Url]),
121 DoOverwrite = get_overwrite(A),
122 IsSame = is_same(From, To),
123 ToExsist = exists(To),
124 if IsSame == true ->
125 [{status, 403}];
126 DoOverwrite == false,
127 ToExsist == true ->
128 [{status, 412}];
129 true ->
130 if DoOverwrite == true ->
131 rmrf(To);
132 true ->
133 ok
134 end,
135 OpF(From, To)
136 end;
137 _ ->
138 [{status, 501}]
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
139 end.
140
141 do_move(From, To) ->
142 case file:rename(From, To) of
0be3c7e @klacke untabified all of yaws
authored
143 ok ->
144 out201();
145 _ ->
146 case file:copy(From, To) of
d07115c @klacke Several cleanups due to dialyzer, also moved the control file into users...
authored
147 {ok,_} ->
0be3c7e @klacke untabified all of yaws
authored
148 ok = file:delete(From),
149 out201();
d07115c @klacke Several cleanups due to dialyzer, also moved the control file into users...
authored
150 {error, Reason} ->
0be3c7e @klacke untabified all of yaws
authored
151 ?elog("move from ~p to ~p failed: ~p\n",
d07115c @klacke Several cleanups due to dialyzer, also moved the control file into users...
authored
152 [From, To, Reason]),
0be3c7e @klacke untabified all of yaws
authored
153 out409()
154 end
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
155 end.
156
157 do_copy(From, To) ->
158 case file:copy(From, To) of
0be3c7e @klacke untabified all of yaws
authored
159 {ok, _} ->
160 out201();
161 Error ->
162 ?elog("move from ~p to ~p failed: ~p\n",
163 [From, To, Error]),
164 out409()
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
165 end.
166
167 propfind(A) ->
168 %% Depth:
169 %% If '0', then no members should be returned.
170 %% If '1', then members one level down should be included in the reply.
171 %% If 'infinity', then all members, recursively, should be included.
172 case depth(A) of
0be3c7e @klacke untabified all of yaws
authored
173 0 ->
174 ?elog("propfind: Depth=0~n", []),
175 Response = depth_zero(A),
176 MultiStatus = [{multistatus, [{'xmlns',"DAV:"}], Response}],
177 B = yaws_dav:xml_expand(MultiStatus),
178 out207(B);
179 1 ->
180 Entries = get_entries(A),
181 ?elog("propfind: Depth=1 , length(Entries)=~p~n",
182 [length(Entries)]),
183 Url = davurl(A),
184 F = fun(Finfo) -> response_entry(Finfo, Url) end,
185 Responses = lists:map(F, Entries),
186 MultiStatus = [{multistatus, [{'xmlns',"DAV:"}], Responses}],
187 B = yaws_dav:xml_expand(MultiStatus),
188 out207(B)
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
189 end.
190
191
192 date_string({{Y,M,D}, {Hr,Min,Sec}}) ->
193 lists:concat([D, " ", month(M), " ", Y, " ", Hr, ":", Min, ":", Sec]).
194
195 get_entries(A) ->
196 Path = davpath(A),
197 case file:read_file_info(Path) of
0be3c7e @klacke untabified all of yaws
authored
198 {ok, Dir} when Dir#file_info.type == directory ->
199 {ok, L} = file:list_dir(Path),
200 [{Name, element(2, file:read_file_info(Path ++ "/" ++ Name))} ||
201 Name <- L];
202 {ok, Else} ->
203 [{get_name(Path),Else}]
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
204 end.
205
206 %%% FIXME should get a proper file_info entry here
207 %%
208 response_entry({Name, F}, Url) when F#file_info.type == directory -> % Dir
209 {response, [],
210 [{href, [], [Url ++ Name]},
455578a @vinoski major trailing whitespace cleanup
vinoski authored
211 {propstat, [],
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
212 [{prop, [],
0be3c7e @klacke untabified all of yaws
authored
213 [{name, [], [Name]},
455578a @vinoski major trailing whitespace cleanup
vinoski authored
214 {creationdate, [], [date_string(F#file_info.ctime)]},
0be3c7e @klacke untabified all of yaws
authored
215 {getlastmodified, [], [date_string(F#file_info.mtime)]},
216 {getcontentlength, [], [integer_to_list(F#file_info.size)]},
455578a @vinoski major trailing whitespace cleanup
vinoski authored
217 {resourcetype, [],
0be3c7e @klacke untabified all of yaws
authored
218 [{collection, [], []}]}
219 %%{ishidden, [], [bool2lnum(F#file.is_hidden)]}]},
220 ]},
221 {status, [], % Status 1
222 ["HTTP/1.1 200 OK"]}]}]};
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
223 %%
224 response_entry({Name, F}, Url) when F#file_info.type == regular -> % File
225 {response, [],
226 [{href, [], [Url ++ Name]},
455578a @vinoski major trailing whitespace cleanup
vinoski authored
227 {propstat, [],
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
228 [{prop, [],
0be3c7e @klacke untabified all of yaws
authored
229 [{name, [], [Name]},
455578a @vinoski major trailing whitespace cleanup
vinoski authored
230 {creationdate, [], [date_string(F#file_info.ctime)]},
0be3c7e @klacke untabified all of yaws
authored
231 {getlastmodified, [], [date_string(F#file_info.mtime)]},
232 {getcontentlength, [], [integer_to_list(F#file_info.size)]},
233 {resourcetype, [], []}
234 %%{ishidden, [], [bool2lnum(F#file.is_hidden)]}]},
235 ]},
236 {status, [], % Status 1
237 ["HTTP/1.1 200 OK"]}]}]};
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
238 %%
239 response_entry(F, _Url) ->
240 ?elog("ignoring file: ~p~n", [F]),
241 [].
242
243
244 get_name("/") -> "/";
245 get_name("") -> "/";
246 get_name(L) ->
247 [Rname|_] = string:tokens(lists:reverse(L), "/"),
248 lists:reverse(Rname).
249
250 file_name("/") -> ".";
251 file_name("") -> ".";
252 file_name(L) ->
253 [Rname|_] = string:tokens(lists:reverse(L), "/"),
254 lists:reverse(Rname).
255
256 get_overwrite(A) ->
257 case lists:keysearch("Overwrite", 3, (A#arg.headers)#headers.other) of
0be3c7e @klacke untabified all of yaws
authored
258 {value, {http_header, _, _, _, "T"}} -> true;
259 _ -> false
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
260 end.
261
262 exists(Path) ->
263 case file:read_file_info(Path) of
0be3c7e @klacke untabified all of yaws
authored
264 {ok, _} -> true;
265 _ -> false
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
266 end.
0be3c7e @klacke untabified all of yaws
authored
267
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
268 %% FIXME: how to do this in a portable way? on unix we could check inode...
269 is_same(A, B) ->
270 A == B.
271
272
273 depth_zero(A) ->
274 Path = davpath(A),
275 Url = davurl(A),
276 Name = file_name(Path),
277 {ok, F} = file:read_file_info(Path), % FIXME
278 ?elog("server_path=~p~n", [A#arg.server_path]),
279 [{response, [],
280 [{href, [], [Url]},
455578a @vinoski major trailing whitespace cleanup
vinoski authored
281 {propstat, [],
0be3c7e @klacke untabified all of yaws
authored
282 [{prop, [],
283 [{name, [], [Name]},
455578a @vinoski major trailing whitespace cleanup
vinoski authored
284 {creationdate, [], [date_string(F#file_info.ctime)]},
0be3c7e @klacke untabified all of yaws
authored
285 {getlastmodified, [], [date_string(F#file_info.mtime)]},
286 {getcontentlength, [], [integer_to_list(F#file_info.size)]},
455578a @vinoski major trailing whitespace cleanup
vinoski authored
287 {resourcetype, [],
0be3c7e @klacke untabified all of yaws
authored
288 is_collection(F)}
289 %%{ishidden, [], [bool2lnum(F#file.is_hidden)]}]},
290 ]},
455578a @vinoski major trailing whitespace cleanup
vinoski authored
291 {status, [],
0be3c7e @klacke untabified all of yaws
authored
292 ["HTTP/1.1 200 OK"]}]}]}].
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
293
294 is_collection(F) when F#file_info.type == directory ->
0be3c7e @klacke untabified all of yaws
authored
295 [{collection, [], []}];
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
296 is_collection(_) ->
297 [].
298
299 davpath(A) ->
300 A#arg.docroot ++ A#arg.server_path.
301
302 davurl(A) ->
303 davroot(A) ++ A#arg.server_path ++ "/".
304
305 davroot(A) ->
306 Method = case A#arg.clisock of
5b34d48 @vinoski wrap SSL sockets in tuple
vinoski authored
307 {ssl ,_} -> "https";
0be3c7e @klacke untabified all of yaws
authored
308 _ -> "http"
309 end,
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
310 Host = (A#arg.headers)#headers.host,
311 Method ++ "://" ++ Host.
312
313 depth(A) ->
314 %%
315 %% Look for: {http_header, _Num, 'Depth', _, Depth}
316 %%
317 Hs = (A#arg.headers)#headers.other,
318 case lists:keysearch("Depth", 3, Hs) of
0be3c7e @klacke untabified all of yaws
authored
319 {value, {_,_,"Depth",_,Depth}} ->
320 to_depth(Depth);
321 _ ->
322 0
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
323 end.
324
325 to_depth("infinity") -> infinity;
326 to_depth(L) ->
327 case catch list_to_integer(L) of
f44be6a @klacke all calls to old deprecated guard tests removed
authored
328 I when is_integer(I) -> I;
0be3c7e @klacke untabified all of yaws
authored
329 _ -> 0
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
330 end.
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
331
332 xml_expand(L) ->
5ef2b8a *** empty log message ***
Tobbe Tornquist authored
333 xml_expand(L, "utf-8").
334
335 xml_expand(L, Cset) ->
336 Prolog = ["<?xml version=\"1.0\" encoding=\""++Cset++"\" ?>"],
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
337 xmerl:export_simple(L,xmerl_xml,[{prolog,Prolog}]).
338
339
340 parse_xml([]) -> [];
f44be6a @klacke all calls to old deprecated guard tests removed
authored
341 parse_xml(L) when is_list(L) ->
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
342 case catch xmerl_scan:string(L, [{namespace_conformant, true}]) of
f44be6a @klacke all calls to old deprecated guard tests removed
authored
343 {X,_} when is_record(X, xmlElement) ->
0be3c7e @klacke untabified all of yaws
authored
344 parse_dav(X);
345 _Z ->
346 ?elog("to_xml: error ~p~n", [_Z]),
347 {error, "xml scanner failed"}
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
348 end.
349
350 -define(CONTENT(X), X#xmlElement.content).
351
352 -define(IS_PROPFIND(X), #xmlElement{expanded_name = {'DAV:',propfind}} = X).
353 -define(IS_PROP(X), #xmlElement{expanded_name = {'DAV:',prop}} = X).
354 -define(IS_NAME(X), #xmlElement{expanded_name = {'DAV:',name}} = X).
355 -define(IS_PARENTNAME(X), #xmlElement{expanded_name = {'DAV:',parentname}} = X).
356 -define(IS_HREF(X), #xmlElement{expanded_name = {'DAV:',href}} = X).
357 -define(IS_ISHIDDEN(X), #xmlElement{expanded_name = {'DAV:',ishidden}} = X).
358 -define(IS_ISCOLLECTION(X), #xmlElement{expanded_name = {'DAV:',iscollection}} = X).
7f03335 *** empty log message ***
Tobbe Tornquist authored
359 -define(IS_ISREADONLY(X), #xmlElement{expanded_name = {'DAV:',isreadonly}} = X).
360 -define(IS_GETCONTENTTYPE(X), #xmlElement{expanded_name = {'DAV:',getcontenttype}} = X).
361 -define(IS_CONTENTCLASS(X), #xmlElement{expanded_name = {'DAV:',contentclass}} = X).
362 -define(IS_GETCONTENTLANGUAGE(X), #xmlElement{expanded_name = {'DAV:',getcontentlanguage}} = X).
363 -define(IS_CREATIONDATE(X), #xmlElement{expanded_name = {'DAV:',creationdate}} = X).
364 -define(IS_LASTACCESSED(X), #xmlElement{expanded_name = {'DAV:',lastaccessed}} = X).
365 -define(IS_GETLASTMODIFIED(X), #xmlElement{expanded_name = {'DAV:',getlastmodified}} = X).
366 -define(IS_GETCONTENTLENGTH(X), #xmlElement{expanded_name = {'DAV:',getcontentlength}} = X).
367 -define(IS_RESOURCETYPE(X), #xmlElement{expanded_name = {'DAV:',resourcetype}} = X).
368 -define(IS_ISSTRUCTUREDDOCUMENT(X), #xmlElement{expanded_name = {'DAV:',isstructureddocument}} = X).
369 -define(IS_DEFAULTDOCUMENT(X), #xmlElement{expanded_name = {'DAV:',defaultdocument}} = X).
370 -define(IS_DISPLAYNAME(X), #xmlElement{expanded_name = {'DAV:',displayname}} = X).
371 -define(IS_ISROOT(X), #xmlElement{expanded_name = {'DAV:',isroot}} = X).
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
372
373
374 parse_dav(?IS_PROPFIND(X)) ->
375 parse_propfind(?CONTENT(X), #propfind{});
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
376 parse_dav(_X) ->
377 %%?elog("parse_dav: GOT ~p~n", [_X]),
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
378 {error, "parse_dav"}. % FIXME , webdav (tobbe)
379
380
381 parse_propfind([?IS_PROP(H)|T], R) ->
382 Prop = parse_prop(?CONTENT(H)),
383 parse_propfind(T, R#propfind{prop = Prop});
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
384 parse_propfind([_H|T], R) ->
385 %%?elog("parse_propfind: ~p~n",[_H]),
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
386 parse_propfind(T, R);
387 parse_propfind([], R) ->
388 R.
389
390 parse_prop(L) ->
391 parse_prop(L, []).
392
393 parse_prop([?IS_NAME(_H)|T], L) ->
394 parse_prop(T, [name | L]);
395 parse_prop([?IS_PARENTNAME(_H)|T], L) ->
396 parse_prop(T, [parentname | L]);
397 parse_prop([?IS_HREF(_H)|T], L) ->
398 parse_prop(T, [href | L]);
399 parse_prop([?IS_ISHIDDEN(_H)|T], L) ->
400 parse_prop(T, [ishidden | L]);
401 parse_prop([?IS_ISCOLLECTION(_H)|T], L) ->
402 parse_prop(T, [iscollection | L]);
7f03335 *** empty log message ***
Tobbe Tornquist authored
403 parse_prop([?IS_ISREADONLY(_H)|T], L) ->
404 parse_prop(T, [isreadonly | L]);
405 parse_prop([?IS_GETCONTENTTYPE(_H)|T], L) ->
406 parse_prop(T, [getcontenttype | L]);
407 parse_prop([?IS_CONTENTCLASS(_H)|T], L) ->
408 parse_prop(T, [contentclass | L]);
409 parse_prop([?IS_GETCONTENTLANGUAGE(_H)|T], L) ->
410 parse_prop(T, [getcontentlanguage | L]);
411 parse_prop([?IS_CREATIONDATE(_H)|T], L) ->
412 parse_prop(T, [creationdate | L]);
413 parse_prop([?IS_LASTACCESSED(_H)|T], L) ->
414 parse_prop(T, [lastaccessed | L]);
415 parse_prop([?IS_GETLASTMODIFIED(_H)|T], L) ->
416 parse_prop(T, [getlastmodified | L]);
417 parse_prop([?IS_GETCONTENTLENGTH(_H)|T], L) ->
418 parse_prop(T, [getcontentlength | L]);
419 parse_prop([?IS_RESOURCETYPE(_H)|T], L) ->
420 parse_prop(T, [resourcetype | L]);
421 parse_prop([?IS_ISSTRUCTUREDDOCUMENT(_H)|T], L) ->
422 parse_prop(T, [isstructureddocument | L]);
423 parse_prop([?IS_DEFAULTDOCUMENT(_H)|T], L) ->
424 parse_prop(T, [defaultdocument | L]);
425 parse_prop([?IS_DISPLAYNAME(_H)|T], L) ->
426 parse_prop(T, [displayname | L]);
427 parse_prop([?IS_ISROOT(_H)|T], L) ->
428 parse_prop(T, [isroot | L]);
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
429 parse_prop([H|T], L) ->
7f03335 *** empty log message ***
Tobbe Tornquist authored
430 ?elog("parse_propfind: NYI ~p~n",[H]), % FIXME , webdav
16299b3 Adding the beginning of WebDav support. The PROPFIND method has been add...
Tobbe Tornquist authored
431 parse_prop(T, L);
432 parse_prop([], L) ->
433 lists:reverse(L). % preserve order!
434
435
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
436 month(1) -> "Jan";
437 month(2) -> "Feb";
438 month(3) -> "Mar";
439 month(4) -> "Apr";
440 month(5) -> "May";
441 month(6) -> "Jun";
442 month(7) -> "Jul";
443 month(8) -> "Aug";
444 month(9) -> "Sep";
445 month(10) -> "Oct";
446 month(11) -> "Nov";
447 month(12) -> "Dec".
448
449 out207(L) ->
450 outXXX(207, L).
451
452 outXXX(XXX, L) ->
453 [{status, XXX},
454 {header, {content_type, "text/xml; charset=\"utf-8\""}},
455 {html, L}].
0be3c7e @klacke untabified all of yaws
authored
456
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
457 out200() ->
458 [{status, 200}].
459
460 out201() ->
461 [{status, 201}].
462
463 out403() ->
464 [{status, 403}].
465
466 out409() ->
467 [{status, 409}].
468
469
470 rmrf(Path) ->
471 case file:read_file_info(Path) of
0be3c7e @klacke untabified all of yaws
authored
472 {ok, F} when F#file_info.type == directory ->
473 case file:list_dir(Path) of
474 {ok, Fs} ->
475 case rmrf(Path, Fs) of
476 ok ->
477 file:del_dir(Path);
478 _Err ->
479 ok
480 end;
481 Err ->
482 Err
483 end;
484 {ok, _} ->
485 file:delete(Path);
486 Err ->
487 Err
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
488 end.
489
490 rmrf(_Dir, []) ->
491 ok;
492 rmrf(Dir, [H|T]) ->
493 F = filename:join(Dir, H),
494 case rmrf(F) of
0be3c7e @klacke untabified all of yaws
authored
495 ok ->
496 rmrf(Dir, T);
497 Err ->
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
498 Err
499 end.
500
501
502 store_client_data(Fd, CliSock, all, SSlBool) ->
503 store_client_data_all(Fd, CliSock, SSlBool);
504
505 store_client_data(Fd, CliSock, Len, SSlBool) ->
506 store_client_data_len(Fd, CliSock, Len, SSlBool).
507
508
509 %% not nice to support this for ssl sockets
510 store_chunked_client_data(Fd, CliSock, SSL) ->
511 yaws:setopts(CliSock, [binary, {packet, line}], SSL),
ca1c8b1 @karlsson Fixed a number of compiler warnings and html validation errors
karlsson authored
512 N = yaws:get_chunk_num(CliSock, SSL),
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
513 yaws:setopts(CliSock, [binary, {packet, raw}], SSL),
514 if
0be3c7e @klacke untabified all of yaws
authored
515 N == 0 ->
516 _Tmp=yaws:do_recv(CliSock, 2, SSL);%% flush last crnl
517 true ->
ca1c8b1 @karlsson Fixed a number of compiler warnings and html validation errors
karlsson authored
518 B = yaws:get_chunk(CliSock, N, 0,SSL),
9a74e5a @klacke Major general code cleanup, finally got rid of all the export_all statem...
authored
519 yaws:eat_crnl(CliSock,SSL),
0be3c7e @klacke untabified all of yaws
authored
520 ok = file:write(Fd, B),
521 store_chunked_client_data(Fd, CliSock, SSL)
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
522 end.
523
524 store_client_data_len(_Fd, _CliSock, 0, _SSlBool) ->
525 ok;
526 store_client_data_len(Fd, CliSock, Len, SSlBool) ->
527 case yaws:cli_recv(CliSock, Len, SSlBool) of
0be3c7e @klacke untabified all of yaws
authored
528 {ok, B} ->
529 ok = file:write(Fd, B),
530 store_client_data_len(Fd, CliSock, Len-size(B), SSlBool);
531 _Other ->
532 ?Debug("store_client_data_len: ~p~n", [_Other]),
533 exit(normal)
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
534 end.
535
536 store_client_data_all(Fd, CliSock, SSlBool) ->
537 case yaws:cli_recv(CliSock, 4000, SSlBool) of
0be3c7e @klacke untabified all of yaws
authored
538 {ok, B} ->
539 ok = file:write(Fd, B),
540 store_client_data_all(Fd, CliSock, SSlBool);
541 eof ->
542 ok;
543 _Other ->
544 ?Debug("store_client_data_all: ~p~n", [_Other]),
545 exit(normal)
868ce8a @mbj4668 reworked the DAV support a bit - don't use an appmod, instead yaws has b...
mbj4668 authored
546 end.
547
Something went wrong with that request. Please try again.