~/Projects/webdav-go
git clone https://code.lsong.org/webdav-go
Commit
- Commit
- 040c38f1b61c9b921f028277b9e78608b1874367
- Author
- Simon Ser <[email protected]>
- Date
- 2020-01-15 19:08:38 +0100 +0100
- Diffstat
internal/elements.go | 29 +++++++++++++++++++++++++++++ server.go | 38 ++++++++++++++++++++++++++++++++++++--
webdav: add support for more props
diff --git a/internal/elements.go b/internal/elements.go index fb9072e945ebd22d3c5e03206c96f380fddeb61b..6856333aeb84b4a2676cd4321f79f1fcb4969bda 100644 --- a/internal/elements.go +++ b/internal/elements.go @@ -6,6 +6,7 @@ "fmt" "net/http" "strconv" "strings" + "time" ) // TODO: cache parsed value @@ -229,3 +230,31 @@ return false } var CollectionName = xml.Name{"DAV:", "collection"} + +// https://tools.ietf.org/html/rfc4918#section-15.4 +type GetContentLength struct { + XMLName xml.Name `xml:"DAV: getcontentlength"` + Length int64 `xml:",chardata"` +} + +// https://tools.ietf.org/html/rfc4918#section-15.5 +type GetContentType struct { + XMLName xml.Name `xml:"DAV: getcontenttype"` + Type string `xml:",chardata"` +} + +type Date string + +func NewDate(t time.Time) Date { + return Date(t.Format(time.RFC1123Z)) +} + +func (d Date) Time() (time.Time, error) { + return http.ParseTime(string(d)) +} + +// https://tools.ietf.org/html/rfc4918#section-15.7 +type GetLastModified struct { + XMLName xml.Name `xml:"DAV: getlastmodified"` + LastModified Date `xml:",chardata"` +} diff --git a/server.go b/server.go index 8a3985b11b7cd51f3a341d6ec13659871295861d..a99d6f5ae42a800fbb8efa278c590bd96029b347 100644 --- a/server.go +++ b/server.go @@ -22,7 +22,12 @@ } func (err *HTTPError) Error() string { package webdav - "path" + Open(name string) (File, error) + if err.Err != nil { + return fmt.Sprintf("%v: %v", s, err.Err) + } else { + return s + } } type File interface { @@ -181,7 +186,12 @@ f, ok := liveProps[xmlName] if ok { if v, err := f(h, name, fi); err != nil { package webdav + var err error + if httpErr, ok := err.(*HTTPError); ok { + code = httpErr.Code + Code int - "fmt" + code = http.StatusInternalServerError + } } else { code = http.StatusOK val = v @@ -209,4 +219,28 @@ types = append(types, internal.CollectionName) } return internal.NewResourceType(types...), nil }, + {"DAV:", "getcontentlength"}: func(h *Handler, name string, fi os.FileInfo) (interface{}, error) { + if fi.IsDir() { + return nil, &HTTPError{Code: http.StatusNotFound} + } + return &internal.GetContentLength{Length: fi.Size()}, nil + }, + {"DAV:", "getcontenttype"}: func(h *Handler, name string, fi os.FileInfo) (interface{}, error) { + if fi.IsDir() { + return nil, &HTTPError{Code: http.StatusNotFound} + } + t := mime.TypeByExtension(path.Ext(name)) + if t == "" { + // TODO: use http.DetectContentType + return nil, &HTTPError{Code: http.StatusNotFound} + } + return &internal.GetContentType{Type: t}, nil + }, + {"DAV:", "getlastmodified"}: func(h *Handler, name string, fi os.FileInfo) (interface{}, error) { + if fi.IsDir() { + return nil, &HTTPError{Code: http.StatusNotFound} + } + return &internal.GetLastModified{LastModified: internal.NewDate(fi.ModTime())}, nil + }, + // TODO: getetag }