Ready to use x's webdav components.
This commit is contained in:
parent
83cf140fa1
commit
ff81448611
@ -155,6 +155,7 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http
|
|||||||
|
|
||||||
fmt.Printf("PROPFIND %s\n", subPath)
|
fmt.Printf("PROPFIND %s\n", subPath)
|
||||||
|
|
||||||
|
// read depth
|
||||||
depth := this.ParseDepth(request)
|
depth := this.ParseDepth(request)
|
||||||
|
|
||||||
propfind := dav.ReadPropfind(request.Body)
|
propfind := dav.ReadPropfind(request.Body)
|
||||||
|
@ -526,7 +526,7 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status
|
|||||||
return http.StatusBadRequest, errInvalidDepth
|
return http.StatusBadRequest, errInvalidDepth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pf, status, err := readPropfind(r.Body)
|
pf, status, err := ReadPropfind(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return status, err
|
return status, err
|
||||||
}
|
}
|
||||||
|
@ -134,13 +134,13 @@ func next(d *ixml.Decoder) (ixml.Token, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_prop (for propfind)
|
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_prop (for propfind)
|
||||||
type propfindProps []xml.Name
|
type PropfindProps []xml.Name
|
||||||
|
|
||||||
// UnmarshalXML appends the property names enclosed within start to pn.
|
// UnmarshalXML appends the property names enclosed within start to pn.
|
||||||
//
|
//
|
||||||
// It returns an error if start does not contain any properties or if
|
// It returns an error if start does not contain any properties or if
|
||||||
// properties contain values. Character data between properties is ignored.
|
// properties contain values. Character data between properties is ignored.
|
||||||
func (pn *propfindProps) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement) error {
|
func (pn *PropfindProps) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement) error {
|
||||||
for {
|
for {
|
||||||
t, err := next(d)
|
t, err := next(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -167,39 +167,39 @@ func (pn *propfindProps) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propfind
|
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propfind
|
||||||
type propfind struct {
|
type Propfind struct {
|
||||||
XMLName ixml.Name `xml:"DAV: propfind"`
|
XMLName ixml.Name `xml:"DAV: propfind"`
|
||||||
Allprop *struct{} `xml:"DAV: allprop"`
|
Allprop *struct{} `xml:"DAV: allprop"`
|
||||||
Propname *struct{} `xml:"DAV: propname"`
|
Propname *struct{} `xml:"DAV: propname"`
|
||||||
Prop propfindProps `xml:"DAV: prop"`
|
Prop PropfindProps `xml:"DAV: prop"`
|
||||||
Include propfindProps `xml:"DAV: include"`
|
Include PropfindProps `xml:"DAV: include"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func readPropfind(r io.Reader) (pf propfind, status int, err error) {
|
func ReadPropfind(r io.Reader) (pf Propfind, status int, err error) {
|
||||||
c := countingReader{r: r}
|
c := countingReader{r: r}
|
||||||
if err = ixml.NewDecoder(&c).Decode(&pf); err != nil {
|
if err = ixml.NewDecoder(&c).Decode(&pf); err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
if c.n == 0 {
|
if c.n == 0 {
|
||||||
// An empty body means to propfind allprop.
|
// An empty body means to propfind allprop.
|
||||||
// http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND
|
// http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND
|
||||||
return propfind{Allprop: new(struct{})}, 0, nil
|
return Propfind{Allprop: new(struct{})}, 0, nil
|
||||||
}
|
}
|
||||||
err = errInvalidPropfind
|
err = errInvalidPropfind
|
||||||
}
|
}
|
||||||
return propfind{}, http.StatusBadRequest, err
|
return Propfind{}, http.StatusBadRequest, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if pf.Allprop == nil && pf.Include != nil {
|
if pf.Allprop == nil && pf.Include != nil {
|
||||||
return propfind{}, http.StatusBadRequest, errInvalidPropfind
|
return Propfind{}, http.StatusBadRequest, errInvalidPropfind
|
||||||
}
|
}
|
||||||
if pf.Allprop != nil && (pf.Prop != nil || pf.Propname != nil) {
|
if pf.Allprop != nil && (pf.Prop != nil || pf.Propname != nil) {
|
||||||
return propfind{}, http.StatusBadRequest, errInvalidPropfind
|
return Propfind{}, http.StatusBadRequest, errInvalidPropfind
|
||||||
}
|
}
|
||||||
if pf.Prop != nil && pf.Propname != nil {
|
if pf.Prop != nil && pf.Propname != nil {
|
||||||
return propfind{}, http.StatusBadRequest, errInvalidPropfind
|
return Propfind{}, http.StatusBadRequest, errInvalidPropfind
|
||||||
}
|
}
|
||||||
if pf.Propname == nil && pf.Allprop == nil && pf.Prop == nil {
|
if pf.Propname == nil && pf.Allprop == nil && pf.Prop == nil {
|
||||||
return propfind{}, http.StatusBadRequest, errInvalidPropfind
|
return Propfind{}, http.StatusBadRequest, errInvalidPropfind
|
||||||
}
|
}
|
||||||
return pf, 0, nil
|
return pf, 0, nil
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ func TestReadPropfind(t *testing.T) {
|
|||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
input string
|
input string
|
||||||
wantPF propfind
|
wantPF Propfind
|
||||||
wantStatus int
|
wantStatus int
|
||||||
}{{
|
}{{
|
||||||
desc: "propfind: propname",
|
desc: "propfind: propname",
|
||||||
@ -147,14 +147,14 @@ func TestReadPropfind(t *testing.T) {
|
|||||||
"<A:propfind xmlns:A='DAV:'>\n" +
|
"<A:propfind xmlns:A='DAV:'>\n" +
|
||||||
" <A:propname/>\n" +
|
" <A:propname/>\n" +
|
||||||
"</A:propfind>",
|
"</A:propfind>",
|
||||||
wantPF: propfind{
|
wantPF: Propfind{
|
||||||
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
||||||
Propname: new(struct{}),
|
Propname: new(struct{}),
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
desc: "propfind: empty body means allprop",
|
desc: "propfind: empty body means allprop",
|
||||||
input: "",
|
input: "",
|
||||||
wantPF: propfind{
|
wantPF: Propfind{
|
||||||
Allprop: new(struct{}),
|
Allprop: new(struct{}),
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
@ -163,7 +163,7 @@ func TestReadPropfind(t *testing.T) {
|
|||||||
"<A:propfind xmlns:A='DAV:'>\n" +
|
"<A:propfind xmlns:A='DAV:'>\n" +
|
||||||
" <A:allprop/>\n" +
|
" <A:allprop/>\n" +
|
||||||
"</A:propfind>",
|
"</A:propfind>",
|
||||||
wantPF: propfind{
|
wantPF: Propfind{
|
||||||
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
||||||
Allprop: new(struct{}),
|
Allprop: new(struct{}),
|
||||||
},
|
},
|
||||||
@ -174,10 +174,10 @@ func TestReadPropfind(t *testing.T) {
|
|||||||
" <A:allprop/>\n" +
|
" <A:allprop/>\n" +
|
||||||
" <A:include><A:displayname/></A:include>\n" +
|
" <A:include><A:displayname/></A:include>\n" +
|
||||||
"</A:propfind>",
|
"</A:propfind>",
|
||||||
wantPF: propfind{
|
wantPF: Propfind{
|
||||||
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
||||||
Allprop: new(struct{}),
|
Allprop: new(struct{}),
|
||||||
Include: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
Include: PropfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
desc: "propfind: include followed by allprop",
|
desc: "propfind: include followed by allprop",
|
||||||
@ -186,10 +186,10 @@ func TestReadPropfind(t *testing.T) {
|
|||||||
" <A:include><A:displayname/></A:include>\n" +
|
" <A:include><A:displayname/></A:include>\n" +
|
||||||
" <A:allprop/>\n" +
|
" <A:allprop/>\n" +
|
||||||
"</A:propfind>",
|
"</A:propfind>",
|
||||||
wantPF: propfind{
|
wantPF: Propfind{
|
||||||
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
||||||
Allprop: new(struct{}),
|
Allprop: new(struct{}),
|
||||||
Include: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
Include: PropfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
desc: "propfind: propfind",
|
desc: "propfind: propfind",
|
||||||
@ -197,9 +197,9 @@ func TestReadPropfind(t *testing.T) {
|
|||||||
"<A:propfind xmlns:A='DAV:'>\n" +
|
"<A:propfind xmlns:A='DAV:'>\n" +
|
||||||
" <A:prop><A:displayname/></A:prop>\n" +
|
" <A:prop><A:displayname/></A:prop>\n" +
|
||||||
"</A:propfind>",
|
"</A:propfind>",
|
||||||
wantPF: propfind{
|
wantPF: Propfind{
|
||||||
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
||||||
Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
Prop: PropfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
desc: "propfind: prop with ignored comments",
|
desc: "propfind: prop with ignored comments",
|
||||||
@ -210,9 +210,9 @@ func TestReadPropfind(t *testing.T) {
|
|||||||
" <A:displayname><!-- ignore --></A:displayname>\n" +
|
" <A:displayname><!-- ignore --></A:displayname>\n" +
|
||||||
" </A:prop>\n" +
|
" </A:prop>\n" +
|
||||||
"</A:propfind>",
|
"</A:propfind>",
|
||||||
wantPF: propfind{
|
wantPF: Propfind{
|
||||||
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
||||||
Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
Prop: PropfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
desc: "propfind: propfind with ignored whitespace",
|
desc: "propfind: propfind with ignored whitespace",
|
||||||
@ -220,9 +220,9 @@ func TestReadPropfind(t *testing.T) {
|
|||||||
"<A:propfind xmlns:A='DAV:'>\n" +
|
"<A:propfind xmlns:A='DAV:'>\n" +
|
||||||
" <A:prop> <A:displayname/></A:prop>\n" +
|
" <A:prop> <A:displayname/></A:prop>\n" +
|
||||||
"</A:propfind>",
|
"</A:propfind>",
|
||||||
wantPF: propfind{
|
wantPF: Propfind{
|
||||||
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
||||||
Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
Prop: PropfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
desc: "propfind: propfind with ignored mixed-content",
|
desc: "propfind: propfind with ignored mixed-content",
|
||||||
@ -230,9 +230,9 @@ func TestReadPropfind(t *testing.T) {
|
|||||||
"<A:propfind xmlns:A='DAV:'>\n" +
|
"<A:propfind xmlns:A='DAV:'>\n" +
|
||||||
" <A:prop>foo<A:displayname/>bar</A:prop>\n" +
|
" <A:prop>foo<A:displayname/>bar</A:prop>\n" +
|
||||||
"</A:propfind>",
|
"</A:propfind>",
|
||||||
wantPF: propfind{
|
wantPF: Propfind{
|
||||||
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
||||||
Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
Prop: PropfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
desc: "propfind: propname with ignored element (section A.4)",
|
desc: "propfind: propname with ignored element (section A.4)",
|
||||||
@ -241,7 +241,7 @@ func TestReadPropfind(t *testing.T) {
|
|||||||
" <A:propname/>\n" +
|
" <A:propname/>\n" +
|
||||||
" <E:leave-out xmlns:E='E:'>*boss*</E:leave-out>\n" +
|
" <E:leave-out xmlns:E='E:'>*boss*</E:leave-out>\n" +
|
||||||
"</A:propfind>",
|
"</A:propfind>",
|
||||||
wantPF: propfind{
|
wantPF: Propfind{
|
||||||
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
|
||||||
Propname: new(struct{}),
|
Propname: new(struct{}),
|
||||||
},
|
},
|
||||||
@ -330,7 +330,7 @@ func TestReadPropfind(t *testing.T) {
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
pf, status, err := readPropfind(strings.NewReader(tc.input))
|
pf, status, err := ReadPropfind(strings.NewReader(tc.input))
|
||||||
if tc.wantStatus != 0 {
|
if tc.wantStatus != 0 {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("%s: got nil error, want non-nil", tc.desc)
|
t.Errorf("%s: got nil error, want non-nil", tc.desc)
|
||||||
|
Loading…
Reference in New Issue
Block a user