// Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package dav import ( "bytes" "context" "encoding/xml" ) // Proppatch describes a property update instruction as defined in RFC 4918. // See http://www.webdav.org/specs/rfc4918.html#METHOD_PROPPATCH type Proppatch struct { // Remove specifies whether this patch removes properties. If it does not // remove them, it sets them. Remove bool // Props contains the properties to be set or removed. Props []Property } // Propstat describes a XML propstat element as defined in RFC 4918. // See http://www.webdav.org/specs/rfc4918.html#ELEMENT_propstat type Propstat struct { // Props contains the properties for which Status applies. Props []Property // Status defines the HTTP status code of the properties in Prop. // Allowed values include, but are not limited to the WebDAV status // code extensions for HTTP/1.1. // http://www.webdav.org/specs/rfc4918.html#status.code.extensions.to.http11 Status int // XMLError contains the XML representation of the optional error element. // XML content within this field must not rely on any predefined // namespace declarations or prefixes. If empty, the XML error element // is omitted. XMLError string // ResponseDescription contains the contents of the optional // responsedescription field. If empty, the XML element is omitted. ResponseDescription string } // DeadPropsHolder holds the dead properties of a resource. // // Dead properties are those properties that are explicitly defined. In // comparison, live properties, such as DAV:getcontentlength, are implicitly // defined by the underlying resource, and cannot be explicitly overridden or // removed. See the Terminology section of // http://www.webdav.org/specs/rfc4918.html#rfc.section.3 // // There is a whitelist of the names of live properties. This package handles // all live properties, and will only pass non-whitelisted names to the Patch // method of DeadPropsHolder implementations. type DeadPropsHolder interface { // DeadProps returns a copy of the dead properties held. DeadProps() (map[xml.Name]Property, error) // Patch patches the dead properties held. // // Patching is atomic; either all or no patches succeed. It returns (nil, // non-nil) if an internal server error occurred, otherwise the Propstats // collectively contain one Property for each proposed patch Property. If // all patches succeed, Patch returns a slice of length one and a Propstat // element with a 200 OK HTTP status code. If none succeed, for reasons // other than an internal server error, no Propstat has status 200 OK. // // For more details on when various HTTP status codes apply, see // http://www.webdav.org/specs/rfc4918.html#PROPPATCH-status Patch([]Proppatch) ([]Propstat, error) } func EscapeXML(s string) string { for i := 0; i < len(s); i++ { // As an optimization, if s contains only ASCII letters, digits or a // few special characters, the escaped value is s itself and we don't // need to allocate a buffer and convert between string and []byte. switch c := s[i]; { case c == ' ' || c == '_' || ('+' <= c && c <= '9') || // Digits as well as + , - . and / ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'): continue } // Otherwise, go through the full escaping process. var buf bytes.Buffer xml.EscapeText(&buf, []byte(s)) return buf.String() } return s } // ContentTyper is an optional interface for the os.FileInfo // objects returned by the FileSystem. // // If this interface is defined then it will be used to read the // content type from the object. // // If this interface is not defined the file will be opened and the // content type will be guessed from the initial contents of the file. type ContentTyper interface { // ContentType returns the content type for the file. // // If this returns error ErrNotImplemented then the error will // be ignored and the base implementation will be used // instead. ContentType(ctx context.Context) (string, error) }