Documentation
¶
Overview ¶
Package internal provides low-level helpers for WebDAV clients and servers.
Index ¶
- Constants
- Variables
- func DecodeXMLRequest(r *http.Request, v interface{}) error
- func DiscoverContextURL(ctx context.Context, service, domain string) (string, error)
- func FormatOverwrite(overwrite bool) string
- func IsNotFound(err error) bool
- func IsRequestBodyEmpty(r *http.Request) bool
- func ParseOverwrite(s string) (bool, error)
- func ServeError(w http.ResponseWriter, err error)
- func ServeMultiStatus(w http.ResponseWriter, ms *MultiStatus) error
- func ServeXML(w http.ResponseWriter) *xml.Encoder
- type ACE
- type ACL
- type AlternateURISet
- type Backend
- type Client
- func (c *Client) Do(req *http.Request) (*http.Response, error)
- func (c *Client) DoMultiStatus(req *http.Request) (*MultiStatus, error)
- func (c *Client) NewRequest(method string, path string, body io.Reader) (*http.Request, error)
- func (c *Client) NewXMLRequest(method string, path string, v interface{}) (*http.Request, error)
- func (c *Client) Options(ctx context.Context, path string) (classes map[string]bool, methods map[string]bool, err error)
- func (c *Client) PropFind(ctx context.Context, path string, depth Depth, propfind *PropFind) (*MultiStatus, error)
- func (c *Client) PropFindFlat(ctx context.Context, path string, propfind *PropFind) (*Response, error)
- func (c *Client) ResolveHref(p string) *url.URL
- func (c *Client) SyncCollection(ctx context.Context, path, syncToken string, level Depth, limit *Limit, ...) (*MultiStatus, error)
- type CurrentUserPrincipal
- type CurrentUserPrivilegeSet
- type Deny
- type Depth
- type Description
- type DisplayName
- type ETag
- type Error
- type GetContentLength
- type GetContentType
- type GetETag
- type GetLastModified
- type Grant
- type Group
- type GroupMemberSet
- type GroupMembership
- type HTTPClient
- type HTTPError
- type Handler
- type Href
- type Include
- type Limit
- type Location
- type MultiStatus
- type Owner
- type Principal
- type PrincipalURL
- type Privilege
- type Prop
- type PropFind
- type PropFindFunc
- type PropStat
- type PropertyUpdate
- type RawXMLValue
- func (val *RawXMLValue) Decode(v interface{}) error
- func (val *RawXMLValue) MarshalXML(e *xml.Encoder, start xml.StartElement) error
- func (val *RawXMLValue) TokenReader() xml.TokenReader
- func (val *RawXMLValue) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
- func (val *RawXMLValue) XMLName() (name xml.Name, ok bool)
- type Remove
- type ResourceType
- type Response
- type Set
- type Status
- type SupportedPrivilege
- type SupportedPrivilegeSet
- type SyncCollectionQuery
- type Time
Constants ¶
const Namespace = "DAV:"
Variables ¶
var ( /* rfc3744#section-3.1 The read privilege controls methods that return information about the state of the resource, including the resource's properties. Affected methods include GET and PROPFIND. Any implementation-defined privilege that also controls access to GET and PROPFIND must be aggregated under DAV:read - if an ACL grants access to DAV:read, the client may expect that no other privilege needs to be granted to have access to GET and PROPFIND. Additionally, the read privilege MUST control the OPTIONS method. */ Read = xml.Name{"DAV:", "read"} /* rfc3744#section-3.2 The write privilege controls methods that lock a resource or modify the content, dead properties, or (in the case of a collection) membership of the resource, such as PUT and PROPPATCH. Note that state modification is also controlled via locking (see section 5.3 of [RFC2518]), so effective write access requires that both write privileges and write locking requirements are satisfied. Any implementation-defined privilege that also controls access to methods modifying content, dead properties or collection membership must be aggregated under DAV:write, e.g., if an ACL grants access to DAV:write, the client may expect that no other privilege needs to be granted to have access to PUT and PROPPATCH. */ Write = xml.Name{"DAV:", "write"} /* rfc3744#section-3.3 The DAV:write-properties privilege controls methods that modify the dead properties of the resource, such as PROPPATCH. Whether this privilege may be used to control access to any live properties is determined by the implementation. Any implementation-defined privilege that also controls access to methods modifying dead properties must be aggregated under DAV:write-properties - e.g., if an ACL grants access to DAV:write-properties, the client can safely expect that no other privilege needs to be granted to have access to PROPPATCH. */ WriteProperties = xml.Name{"DAV:", "write-properties"} /* rfc3744#section-3.4 The DAV:write-content privilege controls methods that modify the content of an existing resource, such as PUT. Any implementation- defined privilege that also controls access to content must be aggregated under DAV:write-content - e.g., if an ACL grants access to DAV:write-content, the client can safely expect that no other privilege needs to be granted to have access to PUT. Note that PUT - when applied to an unmapped URI - creates a new resource and therefore is controlled by the DAV:bind privilege on the parent collection. */ WriteContent = xml.Name{"DAV:", "write-content"} /* rfc3744#section-3.5 The DAV:unlock privilege controls the use of the UNLOCK method by a principal other than the lock owner (the principal that created a lock can always perform an UNLOCK). While the set of users who may lock a resource is most commonly the same set of users who may modify a resource, servers may allow various kinds of administrators to unlock resources locked by others. Any privilege controlling access by non-lock owners to UNLOCK MUST be aggregated under DAV:unlock. A lock owner can always remove a lock by issuing an UNLOCK with the correct lock token and authentication credentials. That is, even if a principal does not have DAV:unlock privilege, they can still remove locks they own. Principals other than the lock owner can remove a lock only if they have DAV:unlock privilege and they issue an UNLOCK with the correct lock token. Lock timeout is not affected by the DAV:unlock privilege. */ Unlock = xml.Name{"DAV:", "unlock"} /* rfc3744#section-3.6 The DAV:read-acl privilege controls the use of PROPFIND to retrieve the DAV:acl property of the resource. */ ReadACL = xml.Name{"DAV:", "read-acl"} /* rfc3744#section-3.7 The DAV:read-current-user-privilege-set privilege controls the use of PROPFIND to retrieve the DAV:current-user-privilege-set property of the resource. Clients are intended to use this property to visually indicate in their UI items that are dependent on the permissions of a resource, for example, by graying out resources that are not writable. This privilege is separate from DAV:read-acl because there is a need to allow most users access to the privileges permitted the current user (due to its use in creating the UI), while the full ACL contains information that may not be appropriate for the current authenticated user. As a result, the set of users who can view the full ACL is expected to be much smaller than those who can read the current user privilege set, and hence distinct privileges are needed for each. */ ReadCurrentUserPrivilegeSet = xml.Name{"DAV:", "read-current-user-privilege-set"} /* rfc3744#section-3.8 The DAV:write-acl privilege controls use of the ACL method to modify the DAV:acl property of the resource. */ WriteACL = xml.Name{"DAV:", "write-acl"} /* rfc3744#section-3.9 The DAV:bind privilege allows a method to add a new member URL to the specified collection (for example via PUT or MKCOL). It is ignored for resources that are not collections. */ Bind = xml.Name{"DAV:", "bind"} /* rfc3744#section-3.10 The DAV:unbind privilege allows a method to remove a member URL from the specified collection (for example via DELETE or MOVE). It is ignored for resources that are not collections. */ Unbind = xml.Name{"DAV:", "unbind"} /* rfc3744#section-3.11 DAV:all is an aggregate privilege that contains the entire set of privileges that can be applied to the resource. */ All = xml.Name{"DAV:", "all"} )
var ( CurrentUserPrivilegeSetReadOnly = CurrentUserPrivilegeSet{ Privilege: []Privilege{NewPrivilege(Read)}, } CurrentUserPrivilegeSetReadWrite = CurrentUserPrivilegeSet{ Privilege: []Privilege{NewPrivilege(Read), NewPrivilege(Write)}, } )
convenience CurrentUserPrivilegeSet
var ( /* rfc3744#section-5.6.1 This element indicates that ACEs with deny clauses are not allowed. */ GrantOnly = xml.Name{"DAV:", "grant-only"} /* rfc3744#section-5.6.2 This element indicates that ACEs with the <invert> element are not allowed. */ NoInvert = xml.Name{"DAV:", "no-invert"} /* rfc3744#section-5.6.3 This element indicates that all deny ACEs must precede all grant ACEs. */ DenyBeforeGrant = xml.Name{"DAV:", "deny-before-grant"} )
var ( /* rfc3744#section-8.1.1 The ACEs submitted in the ACL request MUST NOT conflict with each other. This is a catchall error code indicating that an implementation-specific ACL restriction has been violated. */ NoACEConflict = xml.Name{"DAV:", "no-ace-conflict"} /* rfc3744#section-8.1.1 The ACEs submitted in the ACL request MUST NOT conflict with the protected ACEs on the resource. For example, if the resource has a protected ACE granting DAV:write to a given principal, then it would not be consistent if the ACL request submitted an ACE denying DAV:write to the same principal. */ NoProtectedACEConflict = xml.Name{"DAV:", "no-protected-ace-conflict"} /* rfc3744#section-8.1.1 The ACEs submitted in the ACL request MUST NOT conflict with the inherited ACEs on the resource. For example, if the resource inherits an ACE from its parent collection granting DAV:write to a given principal, then it would not be consistent if the ACL request submitted an ACE denying DAV:write to the same principal. Note that reporting of this error will be implementation-dependent. Implementations MUST either report this error or allow the ACE to be set, and then let normal ACE evaluation rules determine whether the new ACE has any impact on the privileges available to a specific principal. */ NoInheritedACEConflict = xml.Name{"DAV:", "no-inherited-ace-conflict"} /* rfc3744#section-8.1.1 The number of ACEs submitted in the ACL request MUST NOT exceed the number of ACEs allowed on that resource. However, ACL-compliant servers MUST support at least one ACE granting privileges to a single principal, and one ACE granting privileges to a group. */ LimitedNumberOfACEs = xml.Name{"DAV:", "limited-number-of-aces"} /* rfc3744#section-8.1.1 The ACL request MUST NOT attempt to grant or deny an abstract privilege */ NoAbstract = xml.Name{"DAV:", "no-abstract"} /* rfc3744#section-8.1.1 The ACEs submitted in the ACL request MUST be supported by the resource. */ NotSupportedPrivilege = xml.Name{"DAV:", "not-supported-privilege"} /* rfc3744#section-8.1.1 The result of the ACL request MUST have at least one ACE for each principal identified in a DAV:required-principal XML element in the ACL semantics of that resource */ MissingRequiredPrincipal = xml.Name{"DAV:", "missing-required-principal"} /* rfc3744#section-8.1.1 Every principal URL in the ACL request MUST identify a principal resource. */ RecognizedPrincipal = xml.Name{"DAV:", "recognized-principal"} /* rfc3744#section-8.1.1 The principals specified in the ACEs submitted in the ACL request MUST be allowed as principals for the resource. For example, a server where only authenticated principals can access resources would not allow the DAV:all or DAV:unauthenticated principals to be used in an ACE, since these would allow unauthenticated access to resources. */ AllowedPrincipal = xml.Name{"DAV:", "allowed-principal"} )
var ( ResourceTypeName = xml.Name{Namespace, "resourcetype"} DisplayNameName = xml.Name{Namespace, "displayname"} GetContentLengthName = xml.Name{Namespace, "getcontentlength"} GetContentTypeName = xml.Name{Namespace, "getcontenttype"} GetLastModifiedName = xml.Name{Namespace, "getlastmodified"} GetETagName = xml.Name{Namespace, "getetag"} CurrentUserPrincipalName = xml.Name{Namespace, "current-user-principal"} CurrentUserPrivilegeSetName = xml.Name{Namespace, "current-user-privilege-set"} )
var CollectionName = xml.Name{Namespace, "collection"}
Functions ¶
func DecodeXMLRequest ¶
func DiscoverContextURL ¶
DiscoverContextURL performs a DNS-based CardDAV/CalDAV service discovery as described in RFC 6764. It returns the URL to the CardDAV/CalDAV server. Specifically it implements points 2 and 3 from the bootstrapping procedure defined in RFC 6764 section 6.
func FormatOverwrite ¶
FormatOverwrite formats an Overwrite header.
func IsNotFound ¶
func IsRequestBodyEmpty ¶
func ParseOverwrite ¶
ParseOverwrite parses an Overwrite header.
func ServeError ¶
func ServeError(w http.ResponseWriter, err error)
func ServeMultiStatus ¶
func ServeMultiStatus(w http.ResponseWriter, ms *MultiStatus) error
Types ¶
type ACE ¶
type ACE struct {
XMLName xml.Name `xml:"DAV: ace"`
/*
rfc3744#section-5.5.1
The DAV:principal element identifies the principal to which this ACE
applies.
*/
Principal Principal `xml:"principal,omitempty"`
Grant *Grant `xml:"grant,omitempty"`
Deny *Deny `xml:"deny,omitempty"`
}
rfc3744#section-5.5
Each DAV:ace element specifies the set of privileges to be either granted or denied to a single principal. If the DAV:acl property is empty, no principal is granted any privilege.
type ACL ¶
rfc3744#section-5.5
This is a protected property that specifies the list of access control entries (ACEs), which define what principals are to get what privileges for this resource.
type AlternateURISet ¶
type AlternateURISet struct {
XMLName xml.Name `xml:"DAV: alternate-URI-set"`
Href []Href `xml:"href,omitempty"`
}
rfc3744#section-4.1
This protected property, if non-empty, contains the URIs of network resources with additional descriptive information about the principal. This property identifies additional network resources (i.e., it contains one or more URIs) that may be consulted by a client to gain additional knowledge concerning a principal. One expected use for this property is the storage of an LDAP [RFC2255] scheme URL. A user-agent encountering an LDAP URL could use LDAP [RFC2251] to retrieve additional machine-readable directory information about the principal, and display that information in its user interface. Support for this property is REQUIRED, and the value is empty if no alternate URI exists for the principal.
type Backend ¶
type Backend interface {
Options(r *http.Request) (caps []string, allow []string, err error)
HeadGet(w http.ResponseWriter, r *http.Request) error
PropFind(w http.ResponseWriter, r *http.Request, pf *PropFind, depth Depth) error
PropPatch(r *http.Request, pu *PropertyUpdate) (*Response, error)
Put(w http.ResponseWriter, r *http.Request) error
Delete(r *http.Request) error
Mkcol(r *http.Request) error
Copy(r *http.Request, dest *Href, recursive, overwrite bool) (created bool, err error)
Move(r *http.Request, dest *Href, overwrite bool) (created bool, err error)
}
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func (*Client) DoMultiStatus ¶
func (c *Client) DoMultiStatus(req *http.Request) (*MultiStatus, error)
func (*Client) NewRequest ¶
func (*Client) NewXMLRequest ¶
type CurrentUserPrincipal ¶
type CurrentUserPrivilegeSet ¶
type CurrentUserPrivilegeSet struct {
XMLName xml.Name `xml:"DAV: current-user-privilege-set"`
Privilege []Privilege `xml:"privilege"`
}
rfc3744#section-5.4
DAV:current-user-privilege-set is a protected property containing the exact set of privileges (as computed by the server) granted to the currently authenticated HTTP user. Aggregate privileges and their contained privileges are listed. A user-agent can use the value of this property to adjust its user interface to make actions inaccessible (e.g., by graying out a menu item or button) for which the current principal does not have permission. This property is also useful for determining what operations the current principal can perform, without having to actually execute an operation.
type Deny ¶
rfc3744#section-5.5.2
Each DAV:grant or DAV:deny element specifies the set of privileges to be either granted or denied to the specified principal. A DAV:grant or DAV:deny element of the DAV:acl of a resource MUST only contain non-abstract elements specified in the DAV:supported-privilege-set of that resource.
type Depth ¶
type Depth int
Depth indicates whether a request applies to the resource's members. It's defined in RFC 4918 section 10.2.
const ( // DepthZero indicates that the request applies only to the resource. DepthZero Depth = 0 // DepthOne indicates that the request applies to the resource and its // internal members only. DepthOne Depth = 1 // DepthInfinity indicates that the request applies to the resource and all // of its members. DepthInfinity Depth = -1 )
type Description ¶
type Description struct {
XMLName xml.Name `xml:"DAV: description"`
Text string `xml:",chardata"`
Lang string `xml:"lang,attr,omitempty"`
}
rfc3744#section-5.3
A description is a human-readable description of what this privilege controls access to. Servers MUST indicate the human language of the description using the xml:lang attribute and SHOULD consider the HTTP Accept-Language request header when selecting one of multiple available languages.
type DisplayName ¶
type Error ¶
type Error struct {
XMLName xml.Name `xml:"DAV: error"`
Raw []RawXMLValue `xml:",any"`
}
type GetContentLength ¶
type GetContentType ¶
type GetLastModified ¶
type Grant ¶
rfc3744#section-5.5.2
Each DAV:grant or DAV:deny element specifies the set of privileges to be either granted or denied to the specified principal. A DAV:grant or DAV:deny element of the DAV:acl of a resource MUST only contain non-abstract elements specified in the DAV:supported-privilege-set of that resource.
type Group ¶
rfc3744#section-5.2
This property identifies a particular principal as being the "group" of the resource. This property is commonly found on repositories that implement the Unix privileges model.
Servers MAY implement DAV:group as protected property and MAY return an empty DAV:group element as property value in case no group information is available.
type GroupMemberSet ¶
type GroupMemberSet struct {
XMLName xml.Name `xml:"DAV: group-member-set"`
Href []Href `xml:"href,omitempty"`
}
rfc3744#section-4.3
This property of a group principal identifies the principals that are direct members of this group. Since a group may be a member of another group, a group may also have indirect members (i.e., the members of its direct members). A URL in the DAV:group-member-set for a principal MUST be the DAV:principal-URL of that principal.
type GroupMembership ¶
type GroupMembership struct {
XMLName xml.Name `xml:"DAV: group-membership"`
Href []Href `xml:"href,omitempty"`
}
rfc3744#section-4.4
This protected property identifies the groups in which the principal is directly a member. Note that a server may allow a group to be a member of another group, in which case the DAV:group-membership of those other groups would need to be queried in order to determine the groups in which the principal is indirectly a member. Support for this property is REQUIRED.
type HTTPClient ¶
HTTPClient performs HTTP requests. It's implemented by *http.Client.
type Include ¶
type Include struct {
XMLName xml.Name `xml:"DAV: include"`
Raw []RawXMLValue `xml:",any"`
}
type MultiStatus ¶
type MultiStatus struct {
XMLName xml.Name `xml:"DAV: multistatus"`
Responses []Response `xml:"response"`
ResponseDescription string `xml:"responsedescription,omitempty"`
SyncToken string `xml:"sync-token,omitempty"`
}
https://tools.ietf.org/html/rfc4918#section-14.16
func NewMultiStatus ¶
func NewMultiStatus(resps ...Response) *MultiStatus
type Owner ¶
rfc3744#section-5.1
This property identifies a particular principal as being the "owner" of the resource. Since the owner of a resource often has special access control capabilities (e.g., the owner frequently has permanent DAV:write-acl privilege), clients might display the resource owner in their user interface.
Servers MAY implement DAV:owner as protected property and MAY return an empty DAV:owner element as property value in case no owner information is available.
type Principal ¶
type Principal struct {
XMLName xml.Name `xml:"DAV: principal"`
Raw *RawXMLValue `xml:",any"`
}
rfc3744#section-4
rfc3744#section-5.5.1
The current user matches DAV:href only if that user is authenticated as being (or being a member of) the principal identified by the URL contained by that DAV:href.
The current user always matches DAV:all.
The current user matches DAV:authenticated only if authenticated.
The current user matches DAV:unauthenticated only if not authenticated.
type PrincipalURL ¶
type PrincipalURL struct {
XMLName xml.Name `xml:"DAV: principal-URL"`
Href Href `xml:"href,omitempty"`
}
rfc3744#section-4.2
A principal may have many URLs, but there must be one "principal URL" that clients can use to uniquely identify a principal. This protected property contains the URL that MUST be used to identify this principal in an ACL request. Support for this property is REQUIRED.
type Privilege ¶
type Privilege struct {
XMLName xml.Name `xml:"DAV: privilege"`
Raw *RawXMLValue `xml:",any"`
}
func NewPrivilege ¶
type Prop ¶
type Prop struct {
XMLName xml.Name `xml:"DAV: prop"`
Raw []RawXMLValue `xml:",any"`
}
https://tools.ietf.org/html/rfc4918#section-14.18
func EncodeProp ¶
type PropFind ¶
type PropFind struct {
XMLName xml.Name `xml:"DAV: propfind"`
Prop *Prop `xml:"prop,omitempty"`
AllProp *struct{} `xml:"allprop,omitempty"`
Include *Include `xml:"include,omitempty"`
PropName *struct{} `xml:"propname,omitempty"`
}
https://tools.ietf.org/html/rfc4918#section-14.20
func NewPropNamePropFind ¶
type PropFindFunc ¶
type PropFindFunc func(raw *RawXMLValue) (interface{}, error)
func PropFindValue ¶
func PropFindValue(value interface{}) PropFindFunc
type PropStat ¶
type PropertyUpdate ¶
type RawXMLValue ¶
type RawXMLValue struct {
// contains filtered or unexported fields
}
RawXMLValue is a raw XML value. It implements xml.Unmarshaler and xml.Marshaler and can be used to delay XML decoding or precompute an XML encoding.
func EncodeRawXMLElement ¶
func EncodeRawXMLElement(v interface{}) (*RawXMLValue, error)
EncodeRawXMLElement encodes a value into a new RawXMLValue. The XML value can only be used for marshalling.
func NewRawXMLElement ¶
func NewRawXMLElement(name xml.Name, attr []xml.Attr, children []RawXMLValue) *RawXMLValue
NewRawXMLElement creates a new RawXMLValue for an element.
func (*RawXMLValue) Decode ¶
func (val *RawXMLValue) Decode(v interface{}) error
func (*RawXMLValue) MarshalXML ¶
func (val *RawXMLValue) MarshalXML(e *xml.Encoder, start xml.StartElement) error
MarshalXML implements xml.Marshaler.
func (*RawXMLValue) TokenReader ¶
func (val *RawXMLValue) TokenReader() xml.TokenReader
TokenReader returns a stream of tokens for the XML value.
func (*RawXMLValue) UnmarshalXML ¶
func (val *RawXMLValue) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
UnmarshalXML implements xml.Unmarshaler.
type ResourceType ¶
type ResourceType struct {
XMLName xml.Name `xml:"DAV: resourcetype"`
Raw []RawXMLValue `xml:",any"`
}
https://tools.ietf.org/html/rfc4918#section-15.9
func NewResourceType ¶
func NewResourceType(names ...xml.Name) *ResourceType
type Response ¶
type Response struct {
XMLName xml.Name `xml:"DAV: response"`
Hrefs []Href `xml:"href"`
PropStats []PropStat `xml:"propstat,omitempty"`
ResponseDescription string `xml:"responsedescription,omitempty"`
Status *Status `xml:"status,omitempty"`
Error *Error `xml:"error,omitempty"`
Location *Location `xml:"location,omitempty"`
}
https://tools.ietf.org/html/rfc4918#section-14.24
func NewErrorResponse ¶
func NewOKResponse ¶
func NewPropFindResponse ¶
func (*Response) DecodeProp ¶
func (*Response) EncodeProp ¶
type SupportedPrivilege ¶
type SupportedPrivilege struct {
XMLName xml.Name `xml:"DAV: supported-privilege"`
Privilege Privilege `xml:"privilege"`
/*
Abstract will be nil if not set
rfc3744#section-5.3
An abstract privilege MUST NOT be used in an ACE for that resource.
Servers MUST fail an attempt to set an abstract privilege.
*/
Abstract *struct{} `xml:"abstract,omitempty"`
Description Description `xml:"description"`
SupportedPrivilege []SupportedPrivilege `xml:"supported-privilege"`
}
rfc3744#section-5.3
Each privilege appears as an XML element, where aggregate privileges list as sub-elements all of the privileges that they aggregate.
type SupportedPrivilegeSet ¶
type SupportedPrivilegeSet struct {
XMLName xml.Name `xml:"DAV: supported-privilege-set"`
SupportedPrivilege []SupportedPrivilege `xml:"supported-privilege"`
}
rfc3744#section-5.3
This is a protected property that identifies the privileges defined for the resource.