Ready to use x's webdav components.
This commit is contained in:
		| @ -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) | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user