Patch title: Release 85 bulk changes
Abstract:
File: /pliant/protocol/http/webdav.pli
Key:
    Removed line
    Added line
   
module "/pliant/language/unsafe.pli"
module "/pliant/language/stream.pli"
module "/pliant/util/encoding/date.pli"


function webdav_list url_path files in out
  arg Str url_path ; arg Array:FileInfo files ; arg List:Str in ; arg_w List:Str out
  var List:Str props :=  var List:Str empty_list ; var List:Str prop_ns :=  var List:Str empty_list
  var (Dictionary Str Str) namespaces := var (Dictionary Str Str) empty_dict
  var CBool prop := false ; var CBool unknown := false
  var Pointer:Str c :> in first
  while exists:c
    var Str all := c
    while (all parse "<" any:(var Str tag) ">" any:(var Str remain))
      if (tag parse any:(var Str base) _ any:(var Str options))
        tag := base
      else
        options := ""
      if (tag parse any:(var Str base) "/")
        tag := base
      if (tag parse any ":" any:(var Str base))
        tag := base
      if tag="/prop"
        prop := false
      var Str ns := options option "xmlns=" Str
      if not exists:(namespaces first ns)
        namespaces insert ns "ns"+(string namespaces:size)
      if prop
        props += tag ; prop_ns += ns
        if tag<>"resourcetype" and tag<>"getlastmodified" and tag<>"getcontentlength"
          unknown := true
      if tag="prop"
        prop := true
      all := remain
    c :> in next c
  out := var List:Str empty_list
  out += "<?xml version=[dq]1.0[dq] encoding=[dq]utf-8[dq]?>"
  if not (exists props:first)
    props += "resourcetype" ; prop_ns += ""
    props += "getlastmodified" ; prop_ns += ""
    props += "getcontentlength" ; prop_ns += ""
  var Str l := "<D:multistatus xmlns:D=[dq]DAV:[dq]"
  each pns namespaces
    l += " xmlns:"+pns+"=[dq]"+(shunt (namespaces key pns)<>"" (namespaces key pns) "DAV:")+"[dq]"
  l += ">"
  out += l
  for (var Int i) 0 files:size-1
    var CBool is_dir := files:i:is_directory or files:i:name="" and url_path:len>0 and (url_path url_path:len-1)="/"
    out += "<D:response>"
    out += "<D:href>"+(replace url_path+files:i:name "%" "%25")+"</D:href>"
    for (var Int lap) 0 (shunt unknown 1 0)
      out += "<D:propstat>"
      out += "<D:prop>"
      var Pointer:Str p :> props first ; var Pointer:Str pns :> prop_ns first
      while exists:p
        var Pointer:Str nsid :> namespaces first pns ; var Str tag := ""
        if p="resourcetype"
          tag := shunt is_dir "<D:resourcetype><D:collection/></D:resourcetype>" "<D:resourcetype/>"
        eif p="getlastmodified"
          if not is_dir
            tag := "<D:getlastmodified>"+(rfc1123_date files:i:datetime)+"</D:getlastmodified>"
        eif p="getcontentlength"
          if not is_dir
            tag := "<D:getcontentlength>"+(string files:i:size)+"</D:getcontentlength>"
        if tag<>""
          if lap=0
            out += tag
        else
          if lap=1 and exists:nsid
            out += "<"+nsid+":"+p+"/>"
        p :> props next p ; pns :> prop_ns next pns
      out += "</D:prop>"
      out += "<D:status>HTTP/1.1 "+(shunt lap=0 "200 OK" "404 Not Found")+"</D:status>"
      out += "</D:propstat>"
    out += "</D:response>"
  out += "</D:multistatus>"

export webdav_list