Vendor dependencies with dep
This commit is contained in:
parent
df8a5792f1
commit
91edebf1fe
1691 changed files with 466360 additions and 0 deletions
519
vendor/golang.org/x/net/webdav/xml.go
generated
vendored
Normal file
519
vendor/golang.org/x/net/webdav/xml.go
generated
vendored
Normal file
|
@ -0,0 +1,519 @@
|
|||
// Copyright 2014 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 webdav
|
||||
|
||||
// The XML encoding is covered by Section 14.
|
||||
// http://www.webdav.org/specs/rfc4918.html#xml.element.definitions
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
// As of https://go-review.googlesource.com/#/c/12772/ which was submitted
|
||||
// in July 2015, this package uses an internal fork of the standard
|
||||
// library's encoding/xml package, due to changes in the way namespaces
|
||||
// were encoded. Such changes were introduced in the Go 1.5 cycle, but were
|
||||
// rolled back in response to https://github.com/golang/go/issues/11841
|
||||
//
|
||||
// However, this package's exported API, specifically the Property and
|
||||
// DeadPropsHolder types, need to refer to the standard library's version
|
||||
// of the xml.Name type, as code that imports this package cannot refer to
|
||||
// the internal version.
|
||||
//
|
||||
// This file therefore imports both the internal and external versions, as
|
||||
// ixml and xml, and converts between them.
|
||||
//
|
||||
// In the long term, this package should use the standard library's version
|
||||
// only, and the internal fork deleted, once
|
||||
// https://github.com/golang/go/issues/13400 is resolved.
|
||||
ixml "golang.org/x/net/webdav/internal/xml"
|
||||
)
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_lockinfo
|
||||
type lockInfo struct {
|
||||
XMLName ixml.Name `xml:"lockinfo"`
|
||||
Exclusive *struct{} `xml:"lockscope>exclusive"`
|
||||
Shared *struct{} `xml:"lockscope>shared"`
|
||||
Write *struct{} `xml:"locktype>write"`
|
||||
Owner owner `xml:"owner"`
|
||||
}
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_owner
|
||||
type owner struct {
|
||||
InnerXML string `xml:",innerxml"`
|
||||
}
|
||||
|
||||
func readLockInfo(r io.Reader) (li lockInfo, status int, err error) {
|
||||
c := &countingReader{r: r}
|
||||
if err = ixml.NewDecoder(c).Decode(&li); err != nil {
|
||||
if err == io.EOF {
|
||||
if c.n == 0 {
|
||||
// An empty body means to refresh the lock.
|
||||
// http://www.webdav.org/specs/rfc4918.html#refreshing-locks
|
||||
return lockInfo{}, 0, nil
|
||||
}
|
||||
err = errInvalidLockInfo
|
||||
}
|
||||
return lockInfo{}, http.StatusBadRequest, err
|
||||
}
|
||||
// We only support exclusive (non-shared) write locks. In practice, these are
|
||||
// the only types of locks that seem to matter.
|
||||
if li.Exclusive == nil || li.Shared != nil || li.Write == nil {
|
||||
return lockInfo{}, http.StatusNotImplemented, errUnsupportedLockInfo
|
||||
}
|
||||
return li, 0, nil
|
||||
}
|
||||
|
||||
type countingReader struct {
|
||||
n int
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
func (c *countingReader) Read(p []byte) (int, error) {
|
||||
n, err := c.r.Read(p)
|
||||
c.n += n
|
||||
return n, err
|
||||
}
|
||||
|
||||
func writeLockInfo(w io.Writer, token string, ld LockDetails) (int, error) {
|
||||
depth := "infinity"
|
||||
if ld.ZeroDepth {
|
||||
depth = "0"
|
||||
}
|
||||
timeout := ld.Duration / time.Second
|
||||
return fmt.Fprintf(w, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"+
|
||||
"<D:prop xmlns:D=\"DAV:\"><D:lockdiscovery><D:activelock>\n"+
|
||||
" <D:locktype><D:write/></D:locktype>\n"+
|
||||
" <D:lockscope><D:exclusive/></D:lockscope>\n"+
|
||||
" <D:depth>%s</D:depth>\n"+
|
||||
" <D:owner>%s</D:owner>\n"+
|
||||
" <D:timeout>Second-%d</D:timeout>\n"+
|
||||
" <D:locktoken><D:href>%s</D:href></D:locktoken>\n"+
|
||||
" <D:lockroot><D:href>%s</D:href></D:lockroot>\n"+
|
||||
"</D:activelock></D:lockdiscovery></D:prop>",
|
||||
depth, ld.OwnerXML, timeout, escape(token), escape(ld.Root),
|
||||
)
|
||||
}
|
||||
|
||||
func escape(s string) string {
|
||||
for i := 0; i < len(s); i++ {
|
||||
switch s[i] {
|
||||
case '"', '&', '\'', '<', '>':
|
||||
b := bytes.NewBuffer(nil)
|
||||
ixml.EscapeText(b, []byte(s))
|
||||
return b.String()
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Next returns the next token, if any, in the XML stream of d.
|
||||
// RFC 4918 requires to ignore comments, processing instructions
|
||||
// and directives.
|
||||
// http://www.webdav.org/specs/rfc4918.html#property_values
|
||||
// http://www.webdav.org/specs/rfc4918.html#xml-extensibility
|
||||
func next(d *ixml.Decoder) (ixml.Token, error) {
|
||||
for {
|
||||
t, err := d.Token()
|
||||
if err != nil {
|
||||
return t, err
|
||||
}
|
||||
switch t.(type) {
|
||||
case ixml.Comment, ixml.Directive, ixml.ProcInst:
|
||||
continue
|
||||
default:
|
||||
return t, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_prop (for propfind)
|
||||
type propfindProps []xml.Name
|
||||
|
||||
// UnmarshalXML appends the property names enclosed within start to pn.
|
||||
//
|
||||
// It returns an error if start does not contain any properties or if
|
||||
// properties contain values. Character data between properties is ignored.
|
||||
func (pn *propfindProps) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement) error {
|
||||
for {
|
||||
t, err := next(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch t.(type) {
|
||||
case ixml.EndElement:
|
||||
if len(*pn) == 0 {
|
||||
return fmt.Errorf("%s must not be empty", start.Name.Local)
|
||||
}
|
||||
return nil
|
||||
case ixml.StartElement:
|
||||
name := t.(ixml.StartElement).Name
|
||||
t, err = next(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := t.(ixml.EndElement); !ok {
|
||||
return fmt.Errorf("unexpected token %T", t)
|
||||
}
|
||||
*pn = append(*pn, xml.Name(name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propfind
|
||||
type propfind struct {
|
||||
XMLName ixml.Name `xml:"DAV: propfind"`
|
||||
Allprop *struct{} `xml:"DAV: allprop"`
|
||||
Propname *struct{} `xml:"DAV: propname"`
|
||||
Prop propfindProps `xml:"DAV: prop"`
|
||||
Include propfindProps `xml:"DAV: include"`
|
||||
}
|
||||
|
||||
func readPropfind(r io.Reader) (pf propfind, status int, err error) {
|
||||
c := countingReader{r: r}
|
||||
if err = ixml.NewDecoder(&c).Decode(&pf); err != nil {
|
||||
if err == io.EOF {
|
||||
if c.n == 0 {
|
||||
// An empty body means to propfind allprop.
|
||||
// http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND
|
||||
return propfind{Allprop: new(struct{})}, 0, nil
|
||||
}
|
||||
err = errInvalidPropfind
|
||||
}
|
||||
return propfind{}, http.StatusBadRequest, err
|
||||
}
|
||||
|
||||
if pf.Allprop == nil && pf.Include != nil {
|
||||
return propfind{}, http.StatusBadRequest, errInvalidPropfind
|
||||
}
|
||||
if pf.Allprop != nil && (pf.Prop != nil || pf.Propname != nil) {
|
||||
return propfind{}, http.StatusBadRequest, errInvalidPropfind
|
||||
}
|
||||
if pf.Prop != nil && pf.Propname != nil {
|
||||
return propfind{}, http.StatusBadRequest, errInvalidPropfind
|
||||
}
|
||||
if pf.Propname == nil && pf.Allprop == nil && pf.Prop == nil {
|
||||
return propfind{}, http.StatusBadRequest, errInvalidPropfind
|
||||
}
|
||||
return pf, 0, nil
|
||||
}
|
||||
|
||||
// Property represents a single DAV resource property as defined in RFC 4918.
|
||||
// See http://www.webdav.org/specs/rfc4918.html#data.model.for.resource.properties
|
||||
type Property struct {
|
||||
// XMLName is the fully qualified name that identifies this property.
|
||||
XMLName xml.Name
|
||||
|
||||
// Lang is an optional xml:lang attribute.
|
||||
Lang string `xml:"xml:lang,attr,omitempty"`
|
||||
|
||||
// InnerXML contains the XML representation of the property value.
|
||||
// See http://www.webdav.org/specs/rfc4918.html#property_values
|
||||
//
|
||||
// Property values of complex type or mixed-content must have fully
|
||||
// expanded XML namespaces or be self-contained with according
|
||||
// XML namespace declarations. They must not rely on any XML
|
||||
// namespace declarations within the scope of the XML document,
|
||||
// even including the DAV: namespace.
|
||||
InnerXML []byte `xml:",innerxml"`
|
||||
}
|
||||
|
||||
// ixmlProperty is the same as the Property type except it holds an ixml.Name
|
||||
// instead of an xml.Name.
|
||||
type ixmlProperty struct {
|
||||
XMLName ixml.Name
|
||||
Lang string `xml:"xml:lang,attr,omitempty"`
|
||||
InnerXML []byte `xml:",innerxml"`
|
||||
}
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_error
|
||||
// See multistatusWriter for the "D:" namespace prefix.
|
||||
type xmlError struct {
|
||||
XMLName ixml.Name `xml:"D:error"`
|
||||
InnerXML []byte `xml:",innerxml"`
|
||||
}
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propstat
|
||||
// See multistatusWriter for the "D:" namespace prefix.
|
||||
type propstat struct {
|
||||
Prop []Property `xml:"D:prop>_ignored_"`
|
||||
Status string `xml:"D:status"`
|
||||
Error *xmlError `xml:"D:error"`
|
||||
ResponseDescription string `xml:"D:responsedescription,omitempty"`
|
||||
}
|
||||
|
||||
// ixmlPropstat is the same as the propstat type except it holds an ixml.Name
|
||||
// instead of an xml.Name.
|
||||
type ixmlPropstat struct {
|
||||
Prop []ixmlProperty `xml:"D:prop>_ignored_"`
|
||||
Status string `xml:"D:status"`
|
||||
Error *xmlError `xml:"D:error"`
|
||||
ResponseDescription string `xml:"D:responsedescription,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalXML prepends the "D:" namespace prefix on properties in the DAV: namespace
|
||||
// before encoding. See multistatusWriter.
|
||||
func (ps propstat) MarshalXML(e *ixml.Encoder, start ixml.StartElement) error {
|
||||
// Convert from a propstat to an ixmlPropstat.
|
||||
ixmlPs := ixmlPropstat{
|
||||
Prop: make([]ixmlProperty, len(ps.Prop)),
|
||||
Status: ps.Status,
|
||||
Error: ps.Error,
|
||||
ResponseDescription: ps.ResponseDescription,
|
||||
}
|
||||
for k, prop := range ps.Prop {
|
||||
ixmlPs.Prop[k] = ixmlProperty{
|
||||
XMLName: ixml.Name(prop.XMLName),
|
||||
Lang: prop.Lang,
|
||||
InnerXML: prop.InnerXML,
|
||||
}
|
||||
}
|
||||
|
||||
for k, prop := range ixmlPs.Prop {
|
||||
if prop.XMLName.Space == "DAV:" {
|
||||
prop.XMLName = ixml.Name{Space: "", Local: "D:" + prop.XMLName.Local}
|
||||
ixmlPs.Prop[k] = prop
|
||||
}
|
||||
}
|
||||
// Distinct type to avoid infinite recursion of MarshalXML.
|
||||
type newpropstat ixmlPropstat
|
||||
return e.EncodeElement(newpropstat(ixmlPs), start)
|
||||
}
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_response
|
||||
// See multistatusWriter for the "D:" namespace prefix.
|
||||
type response struct {
|
||||
XMLName ixml.Name `xml:"D:response"`
|
||||
Href []string `xml:"D:href"`
|
||||
Propstat []propstat `xml:"D:propstat"`
|
||||
Status string `xml:"D:status,omitempty"`
|
||||
Error *xmlError `xml:"D:error"`
|
||||
ResponseDescription string `xml:"D:responsedescription,omitempty"`
|
||||
}
|
||||
|
||||
// MultistatusWriter marshals one or more Responses into a XML
|
||||
// multistatus response.
|
||||
// See http://www.webdav.org/specs/rfc4918.html#ELEMENT_multistatus
|
||||
// TODO(rsto, mpl): As a workaround, the "D:" namespace prefix, defined as
|
||||
// "DAV:" on this element, is prepended on the nested response, as well as on all
|
||||
// its nested elements. All property names in the DAV: namespace are prefixed as
|
||||
// well. This is because some versions of Mini-Redirector (on windows 7) ignore
|
||||
// elements with a default namespace (no prefixed namespace). A less intrusive fix
|
||||
// should be possible after golang.org/cl/11074. See https://golang.org/issue/11177
|
||||
type multistatusWriter struct {
|
||||
// ResponseDescription contains the optional responsedescription
|
||||
// of the multistatus XML element. Only the latest content before
|
||||
// close will be emitted. Empty response descriptions are not
|
||||
// written.
|
||||
responseDescription string
|
||||
|
||||
w http.ResponseWriter
|
||||
enc *ixml.Encoder
|
||||
}
|
||||
|
||||
// Write validates and emits a DAV response as part of a multistatus response
|
||||
// element.
|
||||
//
|
||||
// It sets the HTTP status code of its underlying http.ResponseWriter to 207
|
||||
// (Multi-Status) and populates the Content-Type header. If r is the
|
||||
// first, valid response to be written, Write prepends the XML representation
|
||||
// of r with a multistatus tag. Callers must call close after the last response
|
||||
// has been written.
|
||||
func (w *multistatusWriter) write(r *response) error {
|
||||
switch len(r.Href) {
|
||||
case 0:
|
||||
return errInvalidResponse
|
||||
case 1:
|
||||
if len(r.Propstat) > 0 != (r.Status == "") {
|
||||
return errInvalidResponse
|
||||
}
|
||||
default:
|
||||
if len(r.Propstat) > 0 || r.Status == "" {
|
||||
return errInvalidResponse
|
||||
}
|
||||
}
|
||||
err := w.writeHeader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return w.enc.Encode(r)
|
||||
}
|
||||
|
||||
// writeHeader writes a XML multistatus start element on w's underlying
|
||||
// http.ResponseWriter and returns the result of the write operation.
|
||||
// After the first write attempt, writeHeader becomes a no-op.
|
||||
func (w *multistatusWriter) writeHeader() error {
|
||||
if w.enc != nil {
|
||||
return nil
|
||||
}
|
||||
w.w.Header().Add("Content-Type", "text/xml; charset=utf-8")
|
||||
w.w.WriteHeader(StatusMulti)
|
||||
_, err := fmt.Fprintf(w.w, `<?xml version="1.0" encoding="UTF-8"?>`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.enc = ixml.NewEncoder(w.w)
|
||||
return w.enc.EncodeToken(ixml.StartElement{
|
||||
Name: ixml.Name{
|
||||
Space: "DAV:",
|
||||
Local: "multistatus",
|
||||
},
|
||||
Attr: []ixml.Attr{{
|
||||
Name: ixml.Name{Space: "xmlns", Local: "D"},
|
||||
Value: "DAV:",
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
||||
// Close completes the marshalling of the multistatus response. It returns
|
||||
// an error if the multistatus response could not be completed. If both the
|
||||
// return value and field enc of w are nil, then no multistatus response has
|
||||
// been written.
|
||||
func (w *multistatusWriter) close() error {
|
||||
if w.enc == nil {
|
||||
return nil
|
||||
}
|
||||
var end []ixml.Token
|
||||
if w.responseDescription != "" {
|
||||
name := ixml.Name{Space: "DAV:", Local: "responsedescription"}
|
||||
end = append(end,
|
||||
ixml.StartElement{Name: name},
|
||||
ixml.CharData(w.responseDescription),
|
||||
ixml.EndElement{Name: name},
|
||||
)
|
||||
}
|
||||
end = append(end, ixml.EndElement{
|
||||
Name: ixml.Name{Space: "DAV:", Local: "multistatus"},
|
||||
})
|
||||
for _, t := range end {
|
||||
err := w.enc.EncodeToken(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return w.enc.Flush()
|
||||
}
|
||||
|
||||
var xmlLangName = ixml.Name{Space: "http://www.w3.org/XML/1998/namespace", Local: "lang"}
|
||||
|
||||
func xmlLang(s ixml.StartElement, d string) string {
|
||||
for _, attr := range s.Attr {
|
||||
if attr.Name == xmlLangName {
|
||||
return attr.Value
|
||||
}
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
type xmlValue []byte
|
||||
|
||||
func (v *xmlValue) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement) error {
|
||||
// The XML value of a property can be arbitrary, mixed-content XML.
|
||||
// To make sure that the unmarshalled value contains all required
|
||||
// namespaces, we encode all the property value XML tokens into a
|
||||
// buffer. This forces the encoder to redeclare any used namespaces.
|
||||
var b bytes.Buffer
|
||||
e := ixml.NewEncoder(&b)
|
||||
for {
|
||||
t, err := next(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if e, ok := t.(ixml.EndElement); ok && e.Name == start.Name {
|
||||
break
|
||||
}
|
||||
if err = e.EncodeToken(t); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err := e.Flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*v = b.Bytes()
|
||||
return nil
|
||||
}
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_prop (for proppatch)
|
||||
type proppatchProps []Property
|
||||
|
||||
// UnmarshalXML appends the property names and values enclosed within start
|
||||
// to ps.
|
||||
//
|
||||
// An xml:lang attribute that is defined either on the DAV:prop or property
|
||||
// name XML element is propagated to the property's Lang field.
|
||||
//
|
||||
// UnmarshalXML returns an error if start does not contain any properties or if
|
||||
// property values contain syntactically incorrect XML.
|
||||
func (ps *proppatchProps) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement) error {
|
||||
lang := xmlLang(start, "")
|
||||
for {
|
||||
t, err := next(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch elem := t.(type) {
|
||||
case ixml.EndElement:
|
||||
if len(*ps) == 0 {
|
||||
return fmt.Errorf("%s must not be empty", start.Name.Local)
|
||||
}
|
||||
return nil
|
||||
case ixml.StartElement:
|
||||
p := Property{
|
||||
XMLName: xml.Name(t.(ixml.StartElement).Name),
|
||||
Lang: xmlLang(t.(ixml.StartElement), lang),
|
||||
}
|
||||
err = d.DecodeElement(((*xmlValue)(&p.InnerXML)), &elem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*ps = append(*ps, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_set
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_remove
|
||||
type setRemove struct {
|
||||
XMLName ixml.Name
|
||||
Lang string `xml:"xml:lang,attr,omitempty"`
|
||||
Prop proppatchProps `xml:"DAV: prop"`
|
||||
}
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propertyupdate
|
||||
type propertyupdate struct {
|
||||
XMLName ixml.Name `xml:"DAV: propertyupdate"`
|
||||
Lang string `xml:"xml:lang,attr,omitempty"`
|
||||
SetRemove []setRemove `xml:",any"`
|
||||
}
|
||||
|
||||
func readProppatch(r io.Reader) (patches []Proppatch, status int, err error) {
|
||||
var pu propertyupdate
|
||||
if err = ixml.NewDecoder(r).Decode(&pu); err != nil {
|
||||
return nil, http.StatusBadRequest, err
|
||||
}
|
||||
for _, op := range pu.SetRemove {
|
||||
remove := false
|
||||
switch op.XMLName {
|
||||
case ixml.Name{Space: "DAV:", Local: "set"}:
|
||||
// No-op.
|
||||
case ixml.Name{Space: "DAV:", Local: "remove"}:
|
||||
for _, p := range op.Prop {
|
||||
if len(p.InnerXML) > 0 {
|
||||
return nil, http.StatusBadRequest, errInvalidProppatch
|
||||
}
|
||||
}
|
||||
remove = true
|
||||
default:
|
||||
return nil, http.StatusBadRequest, errInvalidProppatch
|
||||
}
|
||||
patches = append(patches, Proppatch{Remove: remove, Props: op.Prop})
|
||||
}
|
||||
return patches, 0, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue