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
|
# File 'lib/async/caldav/handlers/propfind.rb', line 13
def call(path:, storage:, user:, headers: {}, body: nil, **)
depth = ['depth'] || '1'
propname = body&.include?('propname')
col_path = path.ensure_trailing_slash
collection = storage.get_collection(col_path.to_s)
item_data = storage.get_item(path.to_s)
if !collection && !item_data && path.depth > 2
return [404, { 'content-type' => 'text/plain' }, ['Not Found']]
end
responses = []
if collection
col = Protocol::Caldav::Collection.new(
path: col_path,
type: collection[:type],
displayname: collection[:displayname],
description: collection[:description],
color: collection[:color],
props: collection[:props]
)
responses << (propname ? col.to_propname_xml : col.to_propfind_xml)
if depth != '0'
storage.list_collections(col_path.to_s).each do |child_path, child_data|
child_p = Protocol::Caldav::Path.new(child_path, storage_class: storage)
child_col = Protocol::Caldav::Collection.new(
path: child_p,
type: child_data[:type],
displayname: child_data[:displayname],
description: child_data[:description],
color: child_data[:color],
props: child_data[:props]
)
responses << (propname ? child_col.to_propname_xml : child_col.to_propfind_xml)
end
storage.list_items(col_path.to_s).each do |item_path, data|
item_p = Protocol::Caldav::Path.new(item_path, storage_class: storage)
item = Protocol::Caldav::Item.new(
path: item_p,
body: data[:body],
content_type: data[:content_type],
etag: data[:etag]
)
responses << (propname ? item.to_propname_xml : item.to_propfind_xml)
end
end
elsif item_data
item = Protocol::Caldav::Item.new(
path: path,
body: item_data[:body],
content_type: item_data[:content_type],
etag: item_data[:etag]
)
responses << (propname ? item.to_propname_xml : item.to_propfind_xml)
else
responses << build_discovery_xml(path, user)
if depth != '0'
storage.list_collections(col_path.to_s).each do |child_path, child_data|
child_p = Protocol::Caldav::Path.new(child_path, storage_class: storage)
child_col = Protocol::Caldav::Collection.new(
path: child_p,
type: child_data[:type],
displayname: child_data[:displayname],
description: child_data[:description],
color: child_data[:color],
props: child_data[:props]
)
responses << (propname ? child_col.to_propname_xml : child_col.to_propfind_xml)
end
end
end
xml = Protocol::Caldav::Multistatus.new(responses).to_xml
[207, Protocol::Caldav::Constants::DAV_HEADERS, [xml]]
end
|