@@ -154,8 +154,10 @@ fn handle_propfind(
154154"# ,
155155 ) ;
156156
157+ let compact_children = depth == DavDepth :: One && target_path. is_dir ( ) ;
157158 for resource in resources {
158- append_multistatus_response ( & mut body, base_dir, & resource, & mode) ?;
159+ let compact = compact_children && resource != target_path;
160+ append_multistatus_response ( & mut body, base_dir, & resource, & mode, compact) ?;
159161 }
160162 body. push_str ( "</D:multistatus>\n " ) ;
161163
@@ -1726,6 +1728,7 @@ fn append_multistatus_response(
17261728 base_dir : & Path ,
17271729 resource : & Path ,
17281730 mode : & PropfindMode ,
1731+ compact : bool ,
17291732) -> Result < ( ) , AppError > {
17301733 let metadata = std:: fs:: metadata ( resource) ?;
17311734 let is_dir = metadata. is_dir ( ) ;
@@ -1743,27 +1746,40 @@ fn append_multistatus_response(
17431746 xml. push_str ( " <D:href>" ) ;
17441747 xml. push_str ( & xml_escape ( & href) ) ;
17451748 xml. push_str ( "</D:href>\n " ) ;
1746- let live_props = build_live_props ( resource, is_dir, & displayname, & metadata) ;
1749+ let include_lock_props = !compact;
1750+ let live_props = build_live_props (
1751+ resource,
1752+ is_dir,
1753+ & displayname,
1754+ & metadata,
1755+ include_lock_props,
1756+ ) ;
17471757 match mode {
17481758 PropfindMode :: AllProp => {
1749- let mut merged = live_props. clone ( ) ;
1750- let dead = dead_props_for_path ( resource) ;
1751- for ( name, value) in dead {
1752- if !merged. iter ( ) . any ( |( live_name, _) | live_name == & name) {
1753- merged. push ( ( name, Some ( xml_escape ( & value) ) ) ) ;
1759+ if compact {
1760+ append_propstat ( xml, & live_props, "HTTP/1.1 200 OK" ) ;
1761+ } else {
1762+ let mut merged = live_props. clone ( ) ;
1763+ let dead = dead_props_for_path ( resource) ;
1764+ for ( name, value) in dead {
1765+ if !merged. iter ( ) . any ( |( live_name, _) | live_name == & name) {
1766+ merged. push ( ( name, Some ( xml_escape ( & value) ) ) ) ;
1767+ }
17541768 }
1769+ append_propstat ( xml, & merged, "HTTP/1.1 200 OK" ) ;
17551770 }
1756- append_propstat ( xml, & merged, "HTTP/1.1 200 OK" ) ;
17571771 }
17581772 PropfindMode :: PropName => {
17591773 let mut names: Vec < ( PropName , Option < String > ) > = live_props
17601774 . iter ( )
17611775 . map ( |( name, _) | ( name. clone ( ) , None ) )
17621776 . collect ( ) ;
1763- let dead = dead_props_for_path ( resource) ;
1764- for dead_name in dead. keys ( ) {
1765- if !names. iter ( ) . any ( |( name, _) | name == dead_name) {
1766- names. push ( ( dead_name. clone ( ) , None ) ) ;
1777+ if !compact {
1778+ let dead = dead_props_for_path ( resource) ;
1779+ for dead_name in dead. keys ( ) {
1780+ if !names. iter ( ) . any ( |( name, _) | name == dead_name) {
1781+ names. push ( ( dead_name. clone ( ) , None ) ) ;
1782+ }
17671783 }
17681784 }
17691785 append_propstat ( xml, & names, "HTTP/1.1 200 OK" ) ;
@@ -1850,6 +1866,7 @@ fn build_live_props(
18501866 is_dir : bool ,
18511867 displayname : & str ,
18521868 metadata : & std:: fs:: Metadata ,
1869+ include_lock_props : bool ,
18531870) -> Vec < ( PropName , Option < String > ) > {
18541871 let mut props = Vec :: new ( ) ;
18551872 props. push ( ( dav_prop_name ( "displayname" ) , Some ( xml_escape ( displayname) ) ) ) ;
@@ -1891,23 +1908,25 @@ fn build_live_props(
18911908 dav_prop_name ( "getetag" ) ,
18921909 Some ( etag_for_resource ( resource, metadata) ) ,
18931910 ) ) ;
1894- props. push ( (
1895- dav_prop_name ( "supportedlock" ) ,
1896- Some ( "<D:lockentry><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry>" . to_string ( ) ) ,
1897- ) ) ;
1898- if let Some ( lock) = current_lock_for_path ( resource) {
1911+ if include_lock_props {
18991912 props. push ( (
1900- dav_prop_name ( "lockdiscovery" ) ,
1901- Some ( format ! (
1902- "<D:activelock><D:locktype><D:write/></D:locktype><D:lockscope><D:exclusive/></D:lockscope><D:depth>{}</D:depth><D:timeout>Second-{}</D:timeout><D:lockroot><D:href>{}</D:href></D:lockroot><D:locktoken><D:href>{}</D:href></D:locktoken></D:activelock>" ,
1903- if lock. depth_infinity { "Infinity" } else { "0" } ,
1904- lock. timeout_secs,
1905- xml_escape( & lock. lockroot_href) ,
1906- xml_escape( & lock. token)
1907- ) ) ,
1913+ dav_prop_name ( "supportedlock" ) ,
1914+ Some ( "<D:lockentry><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype></D:lockentry>" . to_string ( ) ) ,
19081915 ) ) ;
1909- } else {
1910- props. push ( ( dav_prop_name ( "lockdiscovery" ) , Some ( String :: new ( ) ) ) ) ;
1916+ if let Some ( lock) = current_lock_for_path ( resource) {
1917+ props. push ( (
1918+ dav_prop_name ( "lockdiscovery" ) ,
1919+ Some ( format ! (
1920+ "<D:activelock><D:locktype><D:write/></D:locktype><D:lockscope><D:exclusive/></D:lockscope><D:depth>{}</D:depth><D:timeout>Second-{}</D:timeout><D:lockroot><D:href>{}</D:href></D:lockroot><D:locktoken><D:href>{}</D:href></D:locktoken></D:activelock>" ,
1921+ if lock. depth_infinity { "Infinity" } else { "0" } ,
1922+ lock. timeout_secs,
1923+ xml_escape( & lock. lockroot_href) ,
1924+ xml_escape( & lock. token)
1925+ ) ) ,
1926+ ) ) ;
1927+ } else {
1928+ props. push ( ( dav_prop_name ( "lockdiscovery" ) , Some ( String :: new ( ) ) ) ) ;
1929+ }
19111930 }
19121931
19131932 props
0 commit comments