perkeep/clients/go/camwebdav/response.go

139 lines
2.7 KiB
Go

package main
import (
"bytes"
"template"
"fmt"
"http"
"time"
"url"
)
type xmler interface {
XML(b *bytes.Buffer)
}
// See: http://www.webdav.org/specs/rfc4918.html
// 14.7 href XML Element
type href url.URL
func (h *href) XML(b *bytes.Buffer) {
b.WriteString("<href>" + template.HTMLEscapeString((*url.URL)(h).String()) + "</href>")
}
// 14.16 multistatus XML Element
type multistatus []*response
func (m multistatus) XML(b *bytes.Buffer) {
b.WriteString("<multistatus xmlns='DAV:'>")
for _, r := range m {
r.XML(b)
}
b.WriteString("</multistatus>")
}
// 14.24 response XML Element
type response struct {
href *href
body xmler // hrefsstatus OR propstats
}
func (r *response) XML(b *bytes.Buffer) {
b.WriteString("<response>")
r.href.XML(b)
r.body.XML(b)
b.WriteString("</response>")
}
// part of 14.24 response XML element
type hrefsstatus struct {
hrefs []*href
status status
}
func (hs *hrefsstatus) XML(b *bytes.Buffer) {
for _, h := range hs.hrefs {
h.XML(b)
}
hs.status.XML(b)
}
// part of 14.24 response element
type propstats []propstat
func (p propstats) XML(b *bytes.Buffer) {
b.WriteString("<propstat>")
for _, prop := range p {
prop.XML(b)
}
b.WriteString("</propstat>")
}
// 14.22 propstat XML Element
type propstat struct {
props []xmler
status status
}
func (p *propstat) XML(b *bytes.Buffer) {
b.WriteString("<prop>")
for _, prop := range p.props {
prop.XML(b)
}
b.WriteString("</prop>")
p.status.XML(b)
}
// 14.28 status XML element
type status int
func (s status) XML(b *bytes.Buffer) {
b.WriteString(fmt.Sprintf("<status>HTTP/1.1 %d %s</status>", s, template.HTMLEscapeString(http.StatusText(int(s)))))
}
// 15.1 creationdate Property
type creationdate uint64 // seconds from unix epoch
func (c creationdate) XML(b *bytes.Buffer) {
b.WriteString("<creationdate>")
b.WriteString(epochToXMLTime(int64(c)))
b.WriteString("</creationdate>")
}
// 15.4 getcontentlength Property
type getcontentlength uint64
func (l getcontentlength) XML(b *bytes.Buffer) {
b.WriteString("<getcontentlength>")
b.WriteString(fmt.Sprint(l))
b.WriteString("</getcontentlength>")
}
// 15.7 getlastmodified Property
type getlastmodified uint64 // seconds from unix epoch
func (g getlastmodified) XML(b *bytes.Buffer) {
b.WriteString("<getlastmodified>")
b.WriteString(epochToXMLTime(int64(g)))
b.WriteString("</getlastmodified>")
}
// 15.9 resourcetype Property
type resourcetype bool // true if collection (directory), false otherwise
func (r resourcetype) XML(b *bytes.Buffer) {
b.WriteString("<resourcetype>")
if r {
b.WriteString("<collection/>")
}
b.WriteString("</resourcetype>")
}
// helpers
func epochToXMLTime(sec int64) string {
return template.HTMLEscapeString(time.SecondsToUTC(sec).Format(time.RFC3339))
}