Skip to content

Commit e45385e

Browse files
committed
webdav: have the exported API use the standard library's xml.Name type.
In particular, the Property and DeadPropsHolder types need to refer to the standard xml package, not the internal fork, to be usable by other packages. Inside the package, the XML marshaling and unmarshaling is still done by the etc/internal/xml package, and will remain that way until golang/go#13400 is resolved. Fixes golang/go#15128. Change-Id: Ie7e7927d8b30d97d10b1a4a654d774fdf3e7a1e3 Reviewed-on: https://go-review.googlesource.com/21635 Reviewed-by: Andrew Gerrand <[email protected]>
1 parent 8f3641d commit e45385e

File tree

6 files changed

+83
-36
lines changed

6 files changed

+83
-36
lines changed

webdav/file.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package webdav
66

77
import (
8+
"encoding/xml"
89
"io"
910
"net/http"
1011
"os"
@@ -13,8 +14,6 @@ import (
1314
"strings"
1415
"sync"
1516
"time"
16-
17-
"golang.org/x/net/webdav/internal/xml"
1817
)
1918

2019
// slashClean is equivalent to but slightly more efficient than

webdav/file_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package webdav
66

77
import (
8+
"encoding/xml"
89
"fmt"
910
"io"
1011
"io/ioutil"
@@ -17,8 +18,6 @@ import (
1718
"strconv"
1819
"strings"
1920
"testing"
20-
21-
"golang.org/x/net/webdav/internal/xml"
2221
)
2322

2423
func TestSlashClean(t *testing.T) {

webdav/prop.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
package webdav
66

77
import (
8+
"encoding/xml"
89
"fmt"
910
"io"
1011
"mime"
1112
"net/http"
1213
"os"
1314
"path/filepath"
1415
"strconv"
15-
16-
"golang.org/x/net/webdav/internal/xml"
1716
)
1817

1918
// Proppatch describes a property update instruction as defined in RFC 4918.

webdav/prop_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@
55
package webdav
66

77
import (
8+
"encoding/xml"
89
"fmt"
910
"net/http"
1011
"os"
1112
"reflect"
1213
"sort"
1314
"testing"
14-
15-
"golang.org/x/net/webdav/internal/xml"
1615
)
1716

1817
func TestMemPS(t *testing.T) {

webdav/xml.go

+60-10
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,29 @@ package webdav
99

1010
import (
1111
"bytes"
12+
"encoding/xml"
1213
"fmt"
1314
"io"
1415
"net/http"
1516
"time"
1617

18+
// As of https://go-review.googlesource.com/#/c/12772/ which was submitted
19+
// in July 2015, this package uses an internal fork of the standard
20+
// library's encoding/xml package, due to changes in the way namespaces
21+
// were encoded. Such changes were introduced in the Go 1.5 cycle, but were
22+
// rolled back in response to https://github.com/golang/go/issues/11841
23+
//
24+
// However, this package's exported API, specifically the Property and
25+
// DeadPropsHolder types, need to refer to the standard library's version
26+
// of the xml.Name type, as code that imports this package cannot refer to
27+
// the internal version.
28+
//
29+
// This file therefore imports both the internal and external versions, as
30+
// ixml and xml, and converts between them.
31+
//
32+
// In the long term, this package should use the standard library's version
33+
// only, and the internal fork deleted, once
34+
// https://github.com/golang/go/issues/13400 is resolved.
1735
ixml "golang.org/x/net/webdav/internal/xml"
1836
)
1937

@@ -116,7 +134,7 @@ func next(d *ixml.Decoder) (ixml.Token, error) {
116134
}
117135

118136
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_prop (for propfind)
119-
type propfindProps []ixml.Name
137+
type propfindProps []xml.Name
120138

121139
// UnmarshalXML appends the property names enclosed within start to pn.
122140
//
@@ -143,7 +161,7 @@ func (pn *propfindProps) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement)
143161
if _, ok := t.(ixml.EndElement); !ok {
144162
return fmt.Errorf("unexpected token %T", t)
145163
}
146-
*pn = append(*pn, name)
164+
*pn = append(*pn, xml.Name(name))
147165
}
148166
}
149167
}
@@ -190,7 +208,7 @@ func readPropfind(r io.Reader) (pf propfind, status int, err error) {
190208
// See http://www.webdav.org/specs/rfc4918.html#data.model.for.resource.properties
191209
type Property struct {
192210
// XMLName is the fully qualified name that identifies this property.
193-
XMLName ixml.Name
211+
XMLName xml.Name
194212

195213
// Lang is an optional xml:lang attribute.
196214
Lang string `xml:"xml:lang,attr,omitempty"`
@@ -206,6 +224,14 @@ type Property struct {
206224
InnerXML []byte `xml:",innerxml"`
207225
}
208226

227+
// ixmlProperty is the same as the Property type except it holds an ixml.Name
228+
// instead of an xml.Name.
229+
type ixmlProperty struct {
230+
XMLName ixml.Name
231+
Lang string `xml:"xml:lang,attr,omitempty"`
232+
InnerXML []byte `xml:",innerxml"`
233+
}
234+
209235
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_error
210236
// See multistatusWriter for the "D:" namespace prefix.
211237
type xmlError struct {
@@ -222,18 +248,42 @@ type propstat struct {
222248
ResponseDescription string `xml:"D:responsedescription,omitempty"`
223249
}
224250

251+
// ixmlPropstat is the same as the propstat type except it holds an ixml.Name
252+
// instead of an xml.Name.
253+
type ixmlPropstat struct {
254+
Prop []ixmlProperty `xml:"D:prop>_ignored_"`
255+
Status string `xml:"D:status"`
256+
Error *xmlError `xml:"D:error"`
257+
ResponseDescription string `xml:"D:responsedescription,omitempty"`
258+
}
259+
225260
// MarshalXML prepends the "D:" namespace prefix on properties in the DAV: namespace
226261
// before encoding. See multistatusWriter.
227262
func (ps propstat) MarshalXML(e *ixml.Encoder, start ixml.StartElement) error {
263+
// Convert from a propstat to an ixmlPropstat.
264+
ixmlPs := ixmlPropstat{
265+
Prop: make([]ixmlProperty, len(ps.Prop)),
266+
Status: ps.Status,
267+
Error: ps.Error,
268+
ResponseDescription: ps.ResponseDescription,
269+
}
228270
for k, prop := range ps.Prop {
271+
ixmlPs.Prop[k] = ixmlProperty{
272+
XMLName: ixml.Name(prop.XMLName),
273+
Lang: prop.Lang,
274+
InnerXML: prop.InnerXML,
275+
}
276+
}
277+
278+
for k, prop := range ixmlPs.Prop {
229279
if prop.XMLName.Space == "DAV:" {
230280
prop.XMLName = ixml.Name{Space: "", Local: "D:" + prop.XMLName.Local}
231-
ps.Prop[k] = prop
281+
ixmlPs.Prop[k] = prop
232282
}
233283
}
234284
// Distinct type to avoid infinite recursion of MarshalXML.
235-
type newpropstat propstat
236-
return e.EncodeElement(newpropstat(ps), start)
285+
type newpropstat ixmlPropstat
286+
return e.EncodeElement(newpropstat(ixmlPs), start)
237287
}
238288

239289
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_response
@@ -350,9 +400,6 @@ func (w *multistatusWriter) close() error {
350400
return w.enc.Flush()
351401
}
352402

353-
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_prop (for proppatch)
354-
type proppatchProps []Property
355-
356403
var xmlLangName = ixml.Name{Space: "http://www.w3.org/XML/1998/namespace", Local: "lang"}
357404

358405
func xmlLang(s ixml.StartElement, d string) string {
@@ -393,6 +440,9 @@ func (v *xmlValue) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement) error
393440
return nil
394441
}
395442

443+
// http://www.webdav.org/specs/rfc4918.html#ELEMENT_prop (for proppatch)
444+
type proppatchProps []Property
445+
396446
// UnmarshalXML appends the property names and values enclosed within start
397447
// to ps.
398448
//
@@ -416,7 +466,7 @@ func (ps *proppatchProps) UnmarshalXML(d *ixml.Decoder, start ixml.StartElement)
416466
return nil
417467
case ixml.StartElement:
418468
p := Property{
419-
XMLName: t.(ixml.StartElement).Name,
469+
XMLName: xml.Name(t.(ixml.StartElement).Name),
420470
Lang: xmlLang(t.(ixml.StartElement), lang),
421471
}
422472
err = d.DecodeElement(((*xmlValue)(&p.InnerXML)), &elem)

webdav/xml_test.go

+19-18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package webdav
66

77
import (
88
"bytes"
9+
"encoding/xml"
910
"fmt"
1011
"io"
1112
"net/http"
@@ -176,7 +177,7 @@ func TestReadPropfind(t *testing.T) {
176177
wantPF: propfind{
177178
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
178179
Allprop: new(struct{}),
179-
Include: propfindProps{ixml.Name{Space: "DAV:", Local: "displayname"}},
180+
Include: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
180181
},
181182
}, {
182183
desc: "propfind: include followed by allprop",
@@ -188,7 +189,7 @@ func TestReadPropfind(t *testing.T) {
188189
wantPF: propfind{
189190
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
190191
Allprop: new(struct{}),
191-
Include: propfindProps{ixml.Name{Space: "DAV:", Local: "displayname"}},
192+
Include: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
192193
},
193194
}, {
194195
desc: "propfind: propfind",
@@ -198,7 +199,7 @@ func TestReadPropfind(t *testing.T) {
198199
"</A:propfind>",
199200
wantPF: propfind{
200201
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
201-
Prop: propfindProps{ixml.Name{Space: "DAV:", Local: "displayname"}},
202+
Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
202203
},
203204
}, {
204205
desc: "propfind: prop with ignored comments",
@@ -211,7 +212,7 @@ func TestReadPropfind(t *testing.T) {
211212
"</A:propfind>",
212213
wantPF: propfind{
213214
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
214-
Prop: propfindProps{ixml.Name{Space: "DAV:", Local: "displayname"}},
215+
Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
215216
},
216217
}, {
217218
desc: "propfind: propfind with ignored whitespace",
@@ -221,7 +222,7 @@ func TestReadPropfind(t *testing.T) {
221222
"</A:propfind>",
222223
wantPF: propfind{
223224
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
224-
Prop: propfindProps{ixml.Name{Space: "DAV:", Local: "displayname"}},
225+
Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
225226
},
226227
}, {
227228
desc: "propfind: propfind with ignored mixed-content",
@@ -231,7 +232,7 @@ func TestReadPropfind(t *testing.T) {
231232
"</A:propfind>",
232233
wantPF: propfind{
233234
XMLName: ixml.Name{Space: "DAV:", Local: "propfind"},
234-
Prop: propfindProps{ixml.Name{Space: "DAV:", Local: "displayname"}},
235+
Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}},
235236
},
236237
}, {
237238
desc: "propfind: propname with ignored element (section A.4)",
@@ -364,15 +365,15 @@ func TestMultistatusWriter(t *testing.T) {
364365
Href: []string{"http://example.com/foo"},
365366
Propstat: []propstat{{
366367
Prop: []Property{{
367-
XMLName: ixml.Name{
368+
XMLName: xml.Name{
368369
Space: "http://ns.example.com/",
369370
Local: "Authors",
370371
},
371372
}},
372373
Status: "HTTP/1.1 424 Failed Dependency",
373374
}, {
374375
Prop: []Property{{
375-
XMLName: ixml.Name{
376+
XMLName: xml.Name{
376377
Space: "http://ns.example.com/",
377378
Local: "Copyright-Owner",
378379
},
@@ -427,13 +428,13 @@ func TestMultistatusWriter(t *testing.T) {
427428
Href: []string{"http://example.com/foo"},
428429
Propstat: []propstat{{
429430
Prop: []Property{{
430-
XMLName: ixml.Name{Space: "http://ns.example.com/boxschema/", Local: "bigbox"},
431+
XMLName: xml.Name{Space: "http://ns.example.com/boxschema/", Local: "bigbox"},
431432
InnerXML: []byte(`` +
432433
`<BoxType xmlns="http://ns.example.com/boxschema/">` +
433434
`Box type A` +
434435
`</BoxType>`),
435436
}, {
436-
XMLName: ixml.Name{Space: "http://ns.example.com/boxschema/", Local: "author"},
437+
XMLName: xml.Name{Space: "http://ns.example.com/boxschema/", Local: "author"},
437438
InnerXML: []byte(`` +
438439
`<Name xmlns="http://ns.example.com/boxschema/">` +
439440
`J.J. Johnson` +
@@ -442,9 +443,9 @@ func TestMultistatusWriter(t *testing.T) {
442443
Status: "HTTP/1.1 200 OK",
443444
}, {
444445
Prop: []Property{{
445-
XMLName: ixml.Name{Space: "http://ns.example.com/boxschema/", Local: "DingALing"},
446+
XMLName: xml.Name{Space: "http://ns.example.com/boxschema/", Local: "DingALing"},
446447
}, {
447-
XMLName: ixml.Name{Space: "http://ns.example.com/boxschema/", Local: "Random"},
448+
XMLName: xml.Name{Space: "http://ns.example.com/boxschema/", Local: "Random"},
448449
}},
449450
Status: "HTTP/1.1 403 Forbidden",
450451
ResponseDescription: "The user does not have access to the DingALing property.",
@@ -494,7 +495,7 @@ func TestMultistatusWriter(t *testing.T) {
494495
responses: []response{{
495496
Propstat: []propstat{{
496497
Prop: []Property{{
497-
XMLName: ixml.Name{
498+
XMLName: xml.Name{
498499
Space: "http://example.com/",
499500
Local: "foo",
500501
},
@@ -527,7 +528,7 @@ func TestMultistatusWriter(t *testing.T) {
527528
Href: []string{"http://example.com/foo"},
528529
Propstat: []propstat{{
529530
Prop: []Property{{
530-
XMLName: ixml.Name{
531+
XMLName: xml.Name{
531532
Space: "http://example.com/",
532533
Local: "foo",
533534
},
@@ -548,7 +549,7 @@ func TestMultistatusWriter(t *testing.T) {
548549
},
549550
Propstat: []propstat{{
550551
Prop: []Property{{
551-
XMLName: ixml.Name{
552+
XMLName: xml.Name{
552553
Space: "http://example.com/",
553554
Local: "foo",
554555
},
@@ -638,14 +639,14 @@ func TestReadProppatch(t *testing.T) {
638639
`</D:propertyupdate>`,
639640
wantPP: []Proppatch{{
640641
Props: []Property{{
641-
ixml.Name{Space: "http://ns.example.com/z/", Local: "Authors"},
642+
xml.Name{Space: "http://ns.example.com/z/", Local: "Authors"},
642643
"",
643644
[]byte(`somevalue`),
644645
}},
645646
}, {
646647
Remove: true,
647648
Props: []Property{{
648-
ixml.Name{Space: "http://ns.example.com/z/", Local: "Copyright-Owner"},
649+
xml.Name{Space: "http://ns.example.com/z/", Local: "Copyright-Owner"},
649650
"",
650651
nil,
651652
}},
@@ -663,7 +664,7 @@ func TestReadProppatch(t *testing.T) {
663664
`</D:propertyupdate>`,
664665
wantPP: []Proppatch{{
665666
Props: []Property{{
666-
ixml.Name{Space: "http://example.com/ns", Local: "foo"},
667+
xml.Name{Space: "http://example.com/ns", Local: "foo"},
667668
"en",
668669
nil,
669670
}},

0 commit comments

Comments
 (0)