diff options
Diffstat (limited to 'vendor/golang.org/x/net/webdav')
-rw-r--r-- | vendor/golang.org/x/net/webdav/file.go | 62 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/file_go1.6.go | 17 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/file_go1.7.go | 16 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/file_test.go | 81 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/internal/xml/example_test.go | 2 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/internal/xml/marshal_test.go | 2 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/internal/xml/read.go | 2 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/internal/xml/typeinfo.go | 2 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/internal/xml/xml_test.go | 2 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/prop.go | 83 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/prop_test.go | 19 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/webdav.go | 51 | ||||
-rw-r--r-- | vendor/golang.org/x/net/webdav/webdav_test.go | 113 |
13 files changed, 300 insertions, 152 deletions
diff --git a/vendor/golang.org/x/net/webdav/file.go b/vendor/golang.org/x/net/webdav/file.go index 3d95c6cba..748118dd3 100644 --- a/vendor/golang.org/x/net/webdav/file.go +++ b/vendor/golang.org/x/net/webdav/file.go @@ -14,6 +14,8 @@ import ( "strings" "sync" "time" + + "golang.org/x/net/context" ) // slashClean is equivalent to but slightly more efficient than @@ -36,11 +38,11 @@ func slashClean(name string) string { // might apply". In particular, whether or not renaming a file or directory // overwriting another existing file or directory is an error is OS-dependent. type FileSystem interface { - Mkdir(name string, perm os.FileMode) error - OpenFile(name string, flag int, perm os.FileMode) (File, error) - RemoveAll(name string) error - Rename(oldName, newName string) error - Stat(name string) (os.FileInfo, error) + Mkdir(ctx context.Context, name string, perm os.FileMode) error + OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (File, error) + RemoveAll(ctx context.Context, name string) error + Rename(ctx context.Context, oldName, newName string) error + Stat(ctx context.Context, name string) (os.FileInfo, error) } // A File is returned by a FileSystem's OpenFile method and can be served by a @@ -76,14 +78,14 @@ func (d Dir) resolve(name string) string { return filepath.Join(dir, filepath.FromSlash(slashClean(name))) } -func (d Dir) Mkdir(name string, perm os.FileMode) error { +func (d Dir) Mkdir(ctx context.Context, name string, perm os.FileMode) error { if name = d.resolve(name); name == "" { return os.ErrNotExist } return os.Mkdir(name, perm) } -func (d Dir) OpenFile(name string, flag int, perm os.FileMode) (File, error) { +func (d Dir) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (File, error) { if name = d.resolve(name); name == "" { return nil, os.ErrNotExist } @@ -94,7 +96,7 @@ func (d Dir) OpenFile(name string, flag int, perm os.FileMode) (File, error) { return f, nil } -func (d Dir) RemoveAll(name string) error { +func (d Dir) RemoveAll(ctx context.Context, name string) error { if name = d.resolve(name); name == "" { return os.ErrNotExist } @@ -105,7 +107,7 @@ func (d Dir) RemoveAll(name string) error { return os.RemoveAll(name) } -func (d Dir) Rename(oldName, newName string) error { +func (d Dir) Rename(ctx context.Context, oldName, newName string) error { if oldName = d.resolve(oldName); oldName == "" { return os.ErrNotExist } @@ -119,7 +121,7 @@ func (d Dir) Rename(oldName, newName string) error { return os.Rename(oldName, newName) } -func (d Dir) Stat(name string) (os.FileInfo, error) { +func (d Dir) Stat(ctx context.Context, name string) (os.FileInfo, error) { if name = d.resolve(name); name == "" { return nil, os.ErrNotExist } @@ -237,7 +239,7 @@ func (fs *memFS) find(op, fullname string) (parent *memFSNode, frag string, err return parent, frag, err } -func (fs *memFS) Mkdir(name string, perm os.FileMode) error { +func (fs *memFS) Mkdir(ctx context.Context, name string, perm os.FileMode) error { fs.mu.Lock() defer fs.mu.Unlock() @@ -260,7 +262,7 @@ func (fs *memFS) Mkdir(name string, perm os.FileMode) error { return nil } -func (fs *memFS) OpenFile(name string, flag int, perm os.FileMode) (File, error) { +func (fs *memFS) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (File, error) { fs.mu.Lock() defer fs.mu.Unlock() @@ -314,7 +316,7 @@ func (fs *memFS) OpenFile(name string, flag int, perm os.FileMode) (File, error) }, nil } -func (fs *memFS) RemoveAll(name string) error { +func (fs *memFS) RemoveAll(ctx context.Context, name string) error { fs.mu.Lock() defer fs.mu.Unlock() @@ -330,7 +332,7 @@ func (fs *memFS) RemoveAll(name string) error { return nil } -func (fs *memFS) Rename(oldName, newName string) error { +func (fs *memFS) Rename(ctx context.Context, oldName, newName string) error { fs.mu.Lock() defer fs.mu.Unlock() @@ -381,7 +383,7 @@ func (fs *memFS) Rename(oldName, newName string) error { return nil } -func (fs *memFS) Stat(name string) (os.FileInfo, error) { +func (fs *memFS) Stat(ctx context.Context, name string) (os.FileInfo, error) { fs.mu.Lock() defer fs.mu.Unlock() @@ -599,9 +601,9 @@ func (f *memFile) Write(p []byte) (int, error) { // moveFiles moves files and/or directories from src to dst. // // See section 9.9.4 for when various HTTP status codes apply. -func moveFiles(fs FileSystem, src, dst string, overwrite bool) (status int, err error) { +func moveFiles(ctx context.Context, fs FileSystem, src, dst string, overwrite bool) (status int, err error) { created := false - if _, err := fs.Stat(dst); err != nil { + if _, err := fs.Stat(ctx, dst); err != nil { if !os.IsNotExist(err) { return http.StatusForbidden, err } @@ -611,13 +613,13 @@ func moveFiles(fs FileSystem, src, dst string, overwrite bool) (status int, err // and the Overwrite header is "T", then prior to performing the move, // the server must perform a DELETE with "Depth: infinity" on the // destination resource. - if err := fs.RemoveAll(dst); err != nil { + if err := fs.RemoveAll(ctx, dst); err != nil { return http.StatusForbidden, err } } else { return http.StatusPreconditionFailed, os.ErrExist } - if err := fs.Rename(src, dst); err != nil { + if err := fs.Rename(ctx, src, dst); err != nil { return http.StatusForbidden, err } if created { @@ -650,7 +652,7 @@ func copyProps(dst, src File) error { // copyFiles copies files and/or directories from src to dst. // // See section 9.8.5 for when various HTTP status codes apply. -func copyFiles(fs FileSystem, src, dst string, overwrite bool, depth int, recursion int) (status int, err error) { +func copyFiles(ctx context.Context, fs FileSystem, src, dst string, overwrite bool, depth int, recursion int) (status int, err error) { if recursion == 1000 { return http.StatusInternalServerError, errRecursionTooDeep } @@ -659,7 +661,7 @@ func copyFiles(fs FileSystem, src, dst string, overwrite bool, depth int, recurs // TODO: section 9.8.3 says that "Note that an infinite-depth COPY of /A/ // into /A/B/ could lead to infinite recursion if not handled correctly." - srcFile, err := fs.OpenFile(src, os.O_RDONLY, 0) + srcFile, err := fs.OpenFile(ctx, src, os.O_RDONLY, 0) if err != nil { if os.IsNotExist(err) { return http.StatusNotFound, err @@ -677,7 +679,7 @@ func copyFiles(fs FileSystem, src, dst string, overwrite bool, depth int, recurs srcPerm := srcStat.Mode() & os.ModePerm created := false - if _, err := fs.Stat(dst); err != nil { + if _, err := fs.Stat(ctx, dst); err != nil { if os.IsNotExist(err) { created = true } else { @@ -687,13 +689,13 @@ func copyFiles(fs FileSystem, src, dst string, overwrite bool, depth int, recurs if !overwrite { return http.StatusPreconditionFailed, os.ErrExist } - if err := fs.RemoveAll(dst); err != nil && !os.IsNotExist(err) { + if err := fs.RemoveAll(ctx, dst); err != nil && !os.IsNotExist(err) { return http.StatusForbidden, err } } if srcStat.IsDir() { - if err := fs.Mkdir(dst, srcPerm); err != nil { + if err := fs.Mkdir(ctx, dst, srcPerm); err != nil { return http.StatusForbidden, err } if depth == infiniteDepth { @@ -705,7 +707,7 @@ func copyFiles(fs FileSystem, src, dst string, overwrite bool, depth int, recurs name := c.Name() s := path.Join(src, name) d := path.Join(dst, name) - cStatus, cErr := copyFiles(fs, s, d, overwrite, depth, recursion) + cStatus, cErr := copyFiles(ctx, fs, s, d, overwrite, depth, recursion) if cErr != nil { // TODO: MultiStatus. return cStatus, cErr @@ -714,7 +716,7 @@ func copyFiles(fs FileSystem, src, dst string, overwrite bool, depth int, recurs } } else { - dstFile, err := fs.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, srcPerm) + dstFile, err := fs.OpenFile(ctx, dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, srcPerm) if err != nil { if os.IsNotExist(err) { return http.StatusConflict, err @@ -747,7 +749,7 @@ func copyFiles(fs FileSystem, src, dst string, overwrite bool, depth int, recurs // Allowed values for depth are 0, 1 or infiniteDepth. For each visited node, // walkFS calls walkFn. If a visited file system node is a directory and // walkFn returns filepath.SkipDir, walkFS will skip traversal of this node. -func walkFS(fs FileSystem, depth int, name string, info os.FileInfo, walkFn filepath.WalkFunc) error { +func walkFS(ctx context.Context, fs FileSystem, depth int, name string, info os.FileInfo, walkFn filepath.WalkFunc) error { // This implementation is based on Walk's code in the standard path/filepath package. err := walkFn(name, info, nil) if err != nil { @@ -764,7 +766,7 @@ func walkFS(fs FileSystem, depth int, name string, info os.FileInfo, walkFn file } // Read directory names. - f, err := fs.OpenFile(name, os.O_RDONLY, 0) + f, err := fs.OpenFile(ctx, name, os.O_RDONLY, 0) if err != nil { return walkFn(name, info, err) } @@ -776,13 +778,13 @@ func walkFS(fs FileSystem, depth int, name string, info os.FileInfo, walkFn file for _, fileInfo := range fileInfos { filename := path.Join(name, fileInfo.Name()) - fileInfo, err := fs.Stat(filename) + fileInfo, err := fs.Stat(ctx, filename) if err != nil { if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir { return err } } else { - err = walkFS(fs, depth, filename, fileInfo, walkFn) + err = walkFS(ctx, fs, depth, filename, fileInfo, walkFn) if err != nil { if !fileInfo.IsDir() || err != filepath.SkipDir { return err diff --git a/vendor/golang.org/x/net/webdav/file_go1.6.go b/vendor/golang.org/x/net/webdav/file_go1.6.go new file mode 100644 index 000000000..fa387700d --- /dev/null +++ b/vendor/golang.org/x/net/webdav/file_go1.6.go @@ -0,0 +1,17 @@ +// Copyright 2016 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. + +// +build !go1.7 + +package webdav + +import ( + "net/http" + + "golang.org/x/net/context" +) + +func getContext(r *http.Request) context.Context { + return context.Background() +} diff --git a/vendor/golang.org/x/net/webdav/file_go1.7.go b/vendor/golang.org/x/net/webdav/file_go1.7.go new file mode 100644 index 000000000..d1c3de832 --- /dev/null +++ b/vendor/golang.org/x/net/webdav/file_go1.7.go @@ -0,0 +1,16 @@ +// Copyright 2016 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. + +// +build go1.7 + +package webdav + +import ( + "context" + "net/http" +) + +func getContext(r *http.Request) context.Context { + return r.Context() +} diff --git a/vendor/golang.org/x/net/webdav/file_test.go b/vendor/golang.org/x/net/webdav/file_test.go index cbd0240ab..bfd96e193 100644 --- a/vendor/golang.org/x/net/webdav/file_test.go +++ b/vendor/golang.org/x/net/webdav/file_test.go @@ -18,6 +18,8 @@ import ( "strconv" "strings" "testing" + + "golang.org/x/net/context" ) func TestSlashClean(t *testing.T) { @@ -195,13 +197,15 @@ func TestWalk(t *testing.T) { }}, } + ctx := context.Background() + for _, tc := range testCases { fs := NewMemFS().(*memFS) parts := strings.Split(tc.dir, "/") for p := 2; p < len(parts); p++ { d := strings.Join(parts[:p], "/") - if err := fs.Mkdir(d, 0666); err != nil { + if err := fs.Mkdir(ctx, d, 0666); err != nil { t.Errorf("tc.dir=%q: mkdir: %q: %v", tc.dir, d, err) } } @@ -231,14 +235,14 @@ func TestWalk(t *testing.T) { // analogous to the Unix find command. // // The returned strings are not guaranteed to be in any particular order. -func find(ss []string, fs FileSystem, name string) ([]string, error) { - stat, err := fs.Stat(name) +func find(ctx context.Context, ss []string, fs FileSystem, name string) ([]string, error) { + stat, err := fs.Stat(ctx, name) if err != nil { return nil, err } ss = append(ss, name) if stat.IsDir() { - f, err := fs.OpenFile(name, os.O_RDONLY, 0) + f, err := fs.OpenFile(ctx, name, os.O_RDONLY, 0) if err != nil { return nil, err } @@ -248,7 +252,7 @@ func find(ss []string, fs FileSystem, name string) ([]string, error) { return nil, err } for _, c := range children { - ss, err = find(ss, fs, path.Join(name, c.Name())) + ss, err = find(ctx, ss, fs, path.Join(name, c.Name())) if err != nil { return nil, err } @@ -403,6 +407,8 @@ func testFS(t *testing.T, fs FileSystem) { "copy__ o=F d=∞ /d/y /d/x want errExist", } + ctx := context.Background() + for i, tc := range testCases { tc = strings.TrimSpace(tc) j := strings.IndexByte(tc, ' ') @@ -420,7 +426,7 @@ func testFS(t *testing.T, fs FileSystem) { if len(parts) != 4 || parts[2] != "want" { t.Fatalf("test case #%d %q: invalid write", i, tc) } - f, opErr := fs.OpenFile(parts[0], os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + f, opErr := fs.OpenFile(ctx, parts[0], os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) if got := errStr(opErr); got != parts[3] { t.Fatalf("test case #%d %q: OpenFile: got %q (%v), want %q", i, tc, got, opErr, parts[3]) } @@ -434,7 +440,7 @@ func testFS(t *testing.T, fs FileSystem) { } case "find": - got, err := find(nil, fs, "/") + got, err := find(ctx, nil, fs, "/") if err != nil { t.Fatalf("test case #%d %q: find: %v", i, tc, err) } @@ -464,17 +470,17 @@ func testFS(t *testing.T, fs FileSystem) { if parts[1] == "d=∞" { depth = infiniteDepth } - _, opErr = copyFiles(fs, parts[2], parts[3], parts[0] == "o=T", depth, 0) + _, opErr = copyFiles(ctx, fs, parts[2], parts[3], parts[0] == "o=T", depth, 0) case "mk-dir": - opErr = fs.Mkdir(parts[0], 0777) + opErr = fs.Mkdir(ctx, parts[0], 0777) case "move__": - _, opErr = moveFiles(fs, parts[1], parts[2], parts[0] == "o=T") + _, opErr = moveFiles(ctx, fs, parts[1], parts[2], parts[0] == "o=T") case "rm-all": - opErr = fs.RemoveAll(parts[0]) + opErr = fs.RemoveAll(ctx, parts[0]) case "stat": var stat os.FileInfo fileName := parts[0] - if stat, opErr = fs.Stat(fileName); opErr == nil { + if stat, opErr = fs.Stat(ctx, fileName); opErr == nil { if stat.IsDir() { got = "dir" } else { @@ -526,9 +532,10 @@ func TestMemFS(t *testing.T) { } func TestMemFSRoot(t *testing.T) { + ctx := context.Background() fs := NewMemFS() for i := 0; i < 5; i++ { - stat, err := fs.Stat("/") + stat, err := fs.Stat(ctx, "/") if err != nil { t.Fatalf("i=%d: Stat: %v", i, err) } @@ -536,7 +543,7 @@ func TestMemFSRoot(t *testing.T) { t.Fatalf("i=%d: Stat.IsDir is false, want true", i) } - f, err := fs.OpenFile("/", os.O_RDONLY, 0) + f, err := fs.OpenFile(ctx, "/", os.O_RDONLY, 0) if err != nil { t.Fatalf("i=%d: OpenFile: %v", i, err) } @@ -553,19 +560,20 @@ func TestMemFSRoot(t *testing.T) { t.Fatalf("i=%d: Write: got nil error, want non-nil", i) } - if err := fs.Mkdir(fmt.Sprintf("/dir%d", i), 0777); err != nil { + if err := fs.Mkdir(ctx, fmt.Sprintf("/dir%d", i), 0777); err != nil { t.Fatalf("i=%d: Mkdir: %v", i, err) } } } func TestMemFileReaddir(t *testing.T) { + ctx := context.Background() fs := NewMemFS() - if err := fs.Mkdir("/foo", 0777); err != nil { + if err := fs.Mkdir(ctx, "/foo", 0777); err != nil { t.Fatalf("Mkdir: %v", err) } readdir := func(count int) ([]os.FileInfo, error) { - f, err := fs.OpenFile("/foo", os.O_RDONLY, 0) + f, err := fs.OpenFile(ctx, "/foo", os.O_RDONLY, 0) if err != nil { t.Fatalf("OpenFile: %v", err) } @@ -649,9 +657,11 @@ func TestMemFile(t *testing.T) { "seek cur -99 want err", } + ctx := context.Background() + const filename = "/foo" fs := NewMemFS() - f, err := fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + f, err := fs.OpenFile(ctx, filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { t.Fatalf("OpenFile: %v", err) } @@ -745,7 +755,7 @@ func TestMemFile(t *testing.T) { } case "wantData": - g, err := fs.OpenFile(filename, os.O_RDONLY, 0666) + g, err := fs.OpenFile(ctx, filename, os.O_RDONLY, 0666) if err != nil { t.Fatalf("test case #%d %q: OpenFile: %v", i, tc, err) } @@ -771,7 +781,7 @@ func TestMemFile(t *testing.T) { if err != nil { t.Fatalf("test case #%d %q: invalid size %q", i, tc, arg) } - fi, err := fs.Stat(filename) + fi, err := fs.Stat(ctx, filename) if err != nil { t.Fatalf("test case #%d %q: Stat: %v", i, tc, err) } @@ -789,8 +799,9 @@ func TestMemFileWriteAllocs(t *testing.T) { if runtime.Compiler == "gccgo" { t.Skip("gccgo allocates here") } + ctx := context.Background() fs := NewMemFS() - f, err := fs.OpenFile("/xxx", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + f, err := fs.OpenFile(ctx, "/xxx", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { t.Fatalf("OpenFile: %v", err) } @@ -812,6 +823,7 @@ func TestMemFileWriteAllocs(t *testing.T) { } func BenchmarkMemFileWrite(b *testing.B) { + ctx := context.Background() fs := NewMemFS() xxx := make([]byte, 1024) for i := range xxx { @@ -820,7 +832,7 @@ func BenchmarkMemFileWrite(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - f, err := fs.OpenFile("/xxx", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + f, err := fs.OpenFile(ctx, "/xxx", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { b.Fatalf("OpenFile: %v", err) } @@ -830,16 +842,17 @@ func BenchmarkMemFileWrite(b *testing.B) { if err := f.Close(); err != nil { b.Fatalf("Close: %v", err) } - if err := fs.RemoveAll("/xxx"); err != nil { + if err := fs.RemoveAll(ctx, "/xxx"); err != nil { b.Fatalf("RemoveAll: %v", err) } } } func TestCopyMoveProps(t *testing.T) { + ctx := context.Background() fs := NewMemFS() create := func(name string) error { - f, err := fs.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + f, err := fs.OpenFile(ctx, name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { return err } @@ -851,7 +864,7 @@ func TestCopyMoveProps(t *testing.T) { return cErr } patch := func(name string, patches ...Proppatch) error { - f, err := fs.OpenFile(name, os.O_RDWR, 0666) + f, err := fs.OpenFile(ctx, name, os.O_RDWR, 0666) if err != nil { return err } @@ -863,7 +876,7 @@ func TestCopyMoveProps(t *testing.T) { return cErr } props := func(name string) (map[xml.Name]Property, error) { - f, err := fs.OpenFile(name, os.O_RDWR, 0666) + f, err := fs.OpenFile(ctx, name, os.O_RDWR, 0666) if err != nil { return nil, err } @@ -901,10 +914,10 @@ func TestCopyMoveProps(t *testing.T) { if err := patch("/src", Proppatch{Props: []Property{p0, p1}}); err != nil { t.Fatalf("patch /src +p0 +p1: %v", err) } - if _, err := copyFiles(fs, "/src", "/tmp", true, infiniteDepth, 0); err != nil { + if _, err := copyFiles(ctx, fs, "/src", "/tmp", true, infiniteDepth, 0); err != nil { t.Fatalf("copyFiles /src /tmp: %v", err) } - if _, err := moveFiles(fs, "/tmp", "/dst", true); err != nil { + if _, err := moveFiles(ctx, fs, "/tmp", "/dst", true); err != nil { t.Fatalf("moveFiles /tmp /dst: %v", err) } if err := patch("/src", Proppatch{Props: []Property{p0}, Remove: true}); err != nil { @@ -1099,6 +1112,7 @@ func TestWalkFS(t *testing.T) { "/a/b/z", }, }} + ctx := context.Background() for _, tc := range testCases { fs, err := buildTestFS(tc.buildfs) if err != nil { @@ -1115,11 +1129,11 @@ func TestWalkFS(t *testing.T) { got = append(got, path) return nil } - fi, err := fs.Stat(tc.startAt) + fi, err := fs.Stat(ctx, tc.startAt) if err != nil { t.Fatalf("%s: cannot stat: %v", tc.desc, err) } - err = walkFS(fs, tc.depth, tc.startAt, fi, traceFn) + err = walkFS(ctx, fs, tc.depth, tc.startAt, fi, traceFn) if err != nil { t.Errorf("%s:\ngot error %v, want nil", tc.desc, err) continue @@ -1136,23 +1150,24 @@ func TestWalkFS(t *testing.T) { func buildTestFS(buildfs []string) (FileSystem, error) { // TODO: Could this be merged with the build logic in TestFS? + ctx := context.Background() fs := NewMemFS() for _, b := range buildfs { op := strings.Split(b, " ") switch op[0] { case "mkdir": - err := fs.Mkdir(op[1], os.ModeDir|0777) + err := fs.Mkdir(ctx, op[1], os.ModeDir|0777) if err != nil { return nil, err } case "touch": - f, err := fs.OpenFile(op[1], os.O_RDWR|os.O_CREATE, 0666) + f, err := fs.OpenFile(ctx, op[1], os.O_RDWR|os.O_CREATE, 0666) if err != nil { return nil, err } f.Close() case "write": - f, err := fs.OpenFile(op[1], os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + f, err := fs.OpenFile(ctx, op[1], os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { return nil, err } diff --git a/vendor/golang.org/x/net/webdav/internal/xml/example_test.go b/vendor/golang.org/x/net/webdav/internal/xml/example_test.go index becedd583..21b48dea5 100644 --- a/vendor/golang.org/x/net/webdav/internal/xml/example_test.go +++ b/vendor/golang.org/x/net/webdav/internal/xml/example_test.go @@ -1,4 +1,4 @@ -// Copyright 2012 The Go Authors. All rights reserved. +// Copyright 2012 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. diff --git a/vendor/golang.org/x/net/webdav/internal/xml/marshal_test.go b/vendor/golang.org/x/net/webdav/internal/xml/marshal_test.go index 5dc78e748..226cfd013 100644 --- a/vendor/golang.org/x/net/webdav/internal/xml/marshal_test.go +++ b/vendor/golang.org/x/net/webdav/internal/xml/marshal_test.go @@ -1868,7 +1868,7 @@ func TestRace9796(t *testing.T) { for i := 0; i < 2; i++ { wg.Add(1) go func() { - Marshal(B{[]A{A{}}}) + Marshal(B{[]A{{}}}) wg.Done() }() } diff --git a/vendor/golang.org/x/net/webdav/internal/xml/read.go b/vendor/golang.org/x/net/webdav/internal/xml/read.go index 75b9f2ba1..3ece08c49 100644 --- a/vendor/golang.org/x/net/webdav/internal/xml/read.go +++ b/vendor/golang.org/x/net/webdav/internal/xml/read.go @@ -1,4 +1,4 @@ -// Copyright 2009 The Go Authors. All rights reserved. +// Copyright 2009 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. diff --git a/vendor/golang.org/x/net/webdav/internal/xml/typeinfo.go b/vendor/golang.org/x/net/webdav/internal/xml/typeinfo.go index c9a6421f2..fdde288bc 100644 --- a/vendor/golang.org/x/net/webdav/internal/xml/typeinfo.go +++ b/vendor/golang.org/x/net/webdav/internal/xml/typeinfo.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. diff --git a/vendor/golang.org/x/net/webdav/internal/xml/xml_test.go b/vendor/golang.org/x/net/webdav/internal/xml/xml_test.go index 312a7c98a..af4cf8ea8 100644 --- a/vendor/golang.org/x/net/webdav/internal/xml/xml_test.go +++ b/vendor/golang.org/x/net/webdav/internal/xml/xml_test.go @@ -1,4 +1,4 @@ -// Copyright 2009 The Go Authors. All rights reserved. +// Copyright 2009 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. diff --git a/vendor/golang.org/x/net/webdav/prop.go b/vendor/golang.org/x/net/webdav/prop.go index 145946637..e36a3b31d 100644 --- a/vendor/golang.org/x/net/webdav/prop.go +++ b/vendor/golang.org/x/net/webdav/prop.go @@ -5,6 +5,7 @@ package webdav import ( + "bytes" "encoding/xml" "fmt" "io" @@ -13,6 +14,8 @@ import ( "os" "path/filepath" "strconv" + + "golang.org/x/net/context" ) // Proppatch describes a property update instruction as defined in RFC 4918. @@ -100,23 +103,23 @@ type DeadPropsHolder interface { var liveProps = map[xml.Name]struct { // findFn implements the propfind function of this property. If nil, // it indicates a hidden property. - findFn func(FileSystem, LockSystem, string, os.FileInfo) (string, error) + findFn func(context.Context, FileSystem, LockSystem, string, os.FileInfo) (string, error) // dir is true if the property applies to directories. dir bool }{ - xml.Name{Space: "DAV:", Local: "resourcetype"}: { + {Space: "DAV:", Local: "resourcetype"}: { findFn: findResourceType, dir: true, }, - xml.Name{Space: "DAV:", Local: "displayname"}: { + {Space: "DAV:", Local: "displayname"}: { findFn: findDisplayName, dir: true, }, - xml.Name{Space: "DAV:", Local: "getcontentlength"}: { + {Space: "DAV:", Local: "getcontentlength"}: { findFn: findContentLength, dir: false, }, - xml.Name{Space: "DAV:", Local: "getlastmodified"}: { + {Space: "DAV:", Local: "getlastmodified"}: { findFn: findLastModified, // http://webdav.org/specs/rfc4918.html#PROPERTY_getlastmodified // suggests that getlastmodified should only apply to GETable @@ -127,19 +130,19 @@ var liveProps = map[xml.Name]struct { // See golang.org/issue/15334. dir: true, }, - xml.Name{Space: "DAV:", Local: "creationdate"}: { + {Space: "DAV:", Local: "creationdate"}: { findFn: nil, dir: false, }, - xml.Name{Space: "DAV:", Local: "getcontentlanguage"}: { + {Space: "DAV:", Local: "getcontentlanguage"}: { findFn: nil, dir: false, }, - xml.Name{Space: "DAV:", Local: "getcontenttype"}: { + {Space: "DAV:", Local: "getcontenttype"}: { findFn: findContentType, dir: false, }, - xml.Name{Space: "DAV:", Local: "getetag"}: { + {Space: "DAV:", Local: "getetag"}: { findFn: findETag, // findETag implements ETag as the concatenated hex values of a file's // modification time and size. This is not a reliable synchronization @@ -150,8 +153,8 @@ var liveProps = map[xml.Name]struct { // TODO: The lockdiscovery property requires LockSystem to list the // active locks on a resource. - xml.Name{Space: "DAV:", Local: "lockdiscovery"}: {}, - xml.Name{Space: "DAV:", Local: "supportedlock"}: { + {Space: "DAV:", Local: "lockdiscovery"}: {}, + {Space: "DAV:", Local: "supportedlock"}: { findFn: findSupportedLock, dir: true, }, @@ -163,8 +166,8 @@ var liveProps = map[xml.Name]struct { // // Each Propstat has a unique status and each property name will only be part // of one Propstat element. -func props(fs FileSystem, ls LockSystem, name string, pnames []xml.Name) ([]Propstat, error) { - f, err := fs.OpenFile(name, os.O_RDONLY, 0) +func props(ctx context.Context, fs FileSystem, ls LockSystem, name string, pnames []xml.Name) ([]Propstat, error) { + f, err := fs.OpenFile(ctx, name, os.O_RDONLY, 0) if err != nil { return nil, err } @@ -193,7 +196,7 @@ func props(fs FileSystem, ls LockSystem, name string, pnames []xml.Name) ([]Prop } // Otherwise, it must either be a live property or we don't know it. if prop := liveProps[pn]; prop.findFn != nil && (prop.dir || !isDir) { - innerXML, err := prop.findFn(fs, ls, name, fi) + innerXML, err := prop.findFn(ctx, fs, ls, name, fi) if err != nil { return nil, err } @@ -211,8 +214,8 @@ func props(fs FileSystem, ls LockSystem, name string, pnames []xml.Name) ([]Prop } // Propnames returns the property names defined for resource name. -func propnames(fs FileSystem, ls LockSystem, name string) ([]xml.Name, error) { - f, err := fs.OpenFile(name, os.O_RDONLY, 0) +func propnames(ctx context.Context, fs FileSystem, ls LockSystem, name string) ([]xml.Name, error) { + f, err := fs.OpenFile(ctx, name, os.O_RDONLY, 0) if err != nil { return nil, err } @@ -251,8 +254,8 @@ func propnames(fs FileSystem, ls LockSystem, name string) ([]xml.Name, error) { // returned if they are named in 'include'. // // See http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND -func allprop(fs FileSystem, ls LockSystem, name string, include []xml.Name) ([]Propstat, error) { - pnames, err := propnames(fs, ls, name) +func allprop(ctx context.Context, fs FileSystem, ls LockSystem, name string, include []xml.Name) ([]Propstat, error) { + pnames, err := propnames(ctx, fs, ls, name) if err != nil { return nil, err } @@ -266,12 +269,12 @@ func allprop(fs FileSystem, ls LockSystem, name string, include []xml.Name) ([]P pnames = append(pnames, pn) } } - return props(fs, ls, name, pnames) + return props(ctx, fs, ls, name, pnames) } // Patch patches the properties of resource name. The return values are // constrained in the same manner as DeadPropsHolder.Patch. -func patch(fs FileSystem, ls LockSystem, name string, patches []Proppatch) ([]Propstat, error) { +func patch(ctx context.Context, fs FileSystem, ls LockSystem, name string, patches []Proppatch) ([]Propstat, error) { conflict := false loop: for _, patch := range patches { @@ -302,7 +305,7 @@ loop: return makePropstats(pstatForbidden, pstatFailedDep), nil } - f, err := fs.OpenFile(name, os.O_RDWR, 0) + f, err := fs.OpenFile(ctx, name, os.O_RDWR, 0) if err != nil { return nil, err } @@ -333,31 +336,51 @@ loop: return []Propstat{pstat}, nil } -func findResourceType(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { +func escapeXML(s string) string { + for i := 0; i < len(s); i++ { + // As an optimization, if s contains only ASCII letters, digits or a + // few special characters, the escaped value is s itself and we don't + // need to allocate a buffer and convert between string and []byte. + switch c := s[i]; { + case c == ' ' || c == '_' || + ('+' <= c && c <= '9') || // Digits as well as + , - . and / + ('A' <= c && c <= 'Z') || + ('a' <= c && c <= 'z'): + continue + } + // Otherwise, go through the full escaping process. + var buf bytes.Buffer + xml.EscapeText(&buf, []byte(s)) + return buf.String() + } + return s +} + +func findResourceType(ctx context.Context, fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { if fi.IsDir() { return `<D:collection xmlns:D="DAV:"/>`, nil } return "", nil } -func findDisplayName(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { +func findDisplayName(ctx context.Context, fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { if slashClean(name) == "/" { // Hide the real name of a possibly prefixed root directory. return "", nil } - return fi.Name(), nil + return escapeXML(fi.Name()), nil } -func findContentLength(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { +func findContentLength(ctx context.Context, fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { return strconv.FormatInt(fi.Size(), 10), nil } -func findLastModified(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { +func findLastModified(ctx context.Context, fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { return fi.ModTime().Format(http.TimeFormat), nil } -func findContentType(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { - f, err := fs.OpenFile(name, os.O_RDONLY, 0) +func findContentType(ctx context.Context, fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { + f, err := fs.OpenFile(ctx, name, os.O_RDONLY, 0) if err != nil { return "", err } @@ -379,14 +402,14 @@ func findContentType(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) return ctype, err } -func findETag(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { +func findETag(ctx context.Context, fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { // The Apache http 2.4 web server by default concatenates the // modification time and size of a file. We replicate the heuristic // with nanosecond granularity. return fmt.Sprintf(`"%x%x"`, fi.ModTime().UnixNano(), fi.Size()), nil } -func findSupportedLock(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { +func findSupportedLock(ctx context.Context, fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { return `` + `<D:lockentry xmlns:D="DAV:">` + `<D:lockscope><D:exclusive/></D:lockscope>` + diff --git a/vendor/golang.org/x/net/webdav/prop_test.go b/vendor/golang.org/x/net/webdav/prop_test.go index 0834dc9f1..57d0e826f 100644 --- a/vendor/golang.org/x/net/webdav/prop_test.go +++ b/vendor/golang.org/x/net/webdav/prop_test.go @@ -12,13 +12,16 @@ import ( "reflect" "sort" "testing" + + "golang.org/x/net/context" ) func TestMemPS(t *testing.T) { + ctx := context.Background() // calcProps calculates the getlastmodified and getetag DAV: property // values in pstats for resource name in file-system fs. calcProps := func(name string, fs FileSystem, ls LockSystem, pstats []Propstat) error { - fi, err := fs.Stat(name) + fi, err := fs.Stat(ctx, name) if err != nil { return err } @@ -32,7 +35,7 @@ func TestMemPS(t *testing.T) { if fi.IsDir() { continue } - etag, err := findETag(fs, ls, name, fi) + etag, err := findETag(ctx, fs, ls, name, fi) if err != nil { return err } @@ -519,7 +522,7 @@ func TestMemPS(t *testing.T) { var propstats []Propstat switch op.op { case "propname": - pnames, err := propnames(fs, ls, op.name) + pnames, err := propnames(ctx, fs, ls, op.name) if err != nil { t.Errorf("%s: got error %v, want nil", desc, err) continue @@ -531,11 +534,11 @@ func TestMemPS(t *testing.T) { } continue case "allprop": - propstats, err = allprop(fs, ls, op.name, op.pnames) + propstats, err = allprop(ctx, fs, ls, op.name, op.pnames) case "propfind": - propstats, err = props(fs, ls, op.name, op.pnames) + propstats, err = props(ctx, fs, ls, op.name, op.pnames) case "proppatch": - propstats, err = patch(fs, ls, op.name, op.patches) + propstats, err = patch(ctx, fs, ls, op.name, op.patches) default: t.Fatalf("%s: %s not implemented", desc, op.op) } @@ -588,8 +591,8 @@ type noDeadPropsFS struct { FileSystem } -func (fs noDeadPropsFS) OpenFile(name string, flag int, perm os.FileMode) (File, error) { - f, err := fs.FileSystem.OpenFile(name, flag, perm) +func (fs noDeadPropsFS) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (File, error) { + f, err := fs.FileSystem.OpenFile(ctx, name, flag, perm) if err != nil { return nil, err } diff --git a/vendor/golang.org/x/net/webdav/webdav.go b/vendor/golang.org/x/net/webdav/webdav.go index 4ce09728b..7b56687fc 100644 --- a/vendor/golang.org/x/net/webdav/webdav.go +++ b/vendor/golang.org/x/net/webdav/webdav.go @@ -174,8 +174,9 @@ func (h *Handler) handleOptions(w http.ResponseWriter, r *http.Request) (status if err != nil { return status, err } + ctx := getContext(r) allow := "OPTIONS, LOCK, PUT, MKCOL" - if fi, err := h.FileSystem.Stat(reqPath); err == nil { + if fi, err := h.FileSystem.Stat(ctx, reqPath); err == nil { if fi.IsDir() { allow = "OPTIONS, LOCK, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND" } else { @@ -196,7 +197,8 @@ func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request) (sta return status, err } // TODO: check locks for read-only access?? - f, err := h.FileSystem.OpenFile(reqPath, os.O_RDONLY, 0) + ctx := getContext(r) + f, err := h.FileSystem.OpenFile(ctx, reqPath, os.O_RDONLY, 0) if err != nil { return http.StatusNotFound, err } @@ -208,7 +210,7 @@ func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request) (sta if fi.IsDir() { return http.StatusMethodNotAllowed, nil } - etag, err := findETag(h.FileSystem, h.LockSystem, reqPath, fi) + etag, err := findETag(ctx, h.FileSystem, h.LockSystem, reqPath, fi) if err != nil { return http.StatusInternalServerError, err } @@ -229,18 +231,20 @@ func (h *Handler) handleDelete(w http.ResponseWriter, r *http.Request) (status i } defer release() + ctx := getContext(r) + // TODO: return MultiStatus where appropriate. // "godoc os RemoveAll" says that "If the path does not exist, RemoveAll // returns nil (no error)." WebDAV semantics are that it should return a // "404 Not Found". We therefore have to Stat before we RemoveAll. - if _, err := h.FileSystem.Stat(reqPath); err != nil { + if _, err := h.FileSystem.Stat(ctx, reqPath); err != nil { if os.IsNotExist(err) { return http.StatusNotFound, err } return http.StatusMethodNotAllowed, err } - if err := h.FileSystem.RemoveAll(reqPath); err != nil { + if err := h.FileSystem.RemoveAll(ctx, reqPath); err != nil { return http.StatusMethodNotAllowed, err } return http.StatusNoContent, nil @@ -258,8 +262,9 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request) (status int, defer release() // TODO(rost): Support the If-Match, If-None-Match headers? See bradfitz' // comments in http.checkEtag. + ctx := getContext(r) - f, err := h.FileSystem.OpenFile(reqPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + f, err := h.FileSystem.OpenFile(ctx, reqPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { return http.StatusNotFound, err } @@ -276,7 +281,7 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request) (status int, if closeErr != nil { return http.StatusMethodNotAllowed, closeErr } - etag, err := findETag(h.FileSystem, h.LockSystem, reqPath, fi) + etag, err := findETag(ctx, h.FileSystem, h.LockSystem, reqPath, fi) if err != nil { return http.StatusInternalServerError, err } @@ -295,10 +300,12 @@ func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request) (status in } defer release() + ctx := getContext(r) + if r.ContentLength > 0 { return http.StatusUnsupportedMediaType, nil } - if err := h.FileSystem.Mkdir(reqPath, 0777); err != nil { + if err := h.FileSystem.Mkdir(ctx, reqPath, 0777); err != nil { if os.IsNotExist(err) { return http.StatusConflict, err } @@ -337,6 +344,8 @@ func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request) (status return http.StatusForbidden, errDestinationEqualsSource } + ctx := getContext(r) + if r.Method == "COPY" { // Section 7.5.1 says that a COPY only needs to lock the destination, // not both destination and source. Strictly speaking, this is racy, @@ -360,7 +369,7 @@ func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request) (status return http.StatusBadRequest, errInvalidDepth } } - return copyFiles(h.FileSystem, src, dst, r.Header.Get("Overwrite") != "F", depth, 0) + return copyFiles(ctx, h.FileSystem, src, dst, r.Header.Get("Overwrite") != "F", depth, 0) } release, status, err := h.confirmLocks(r, src, dst) @@ -377,7 +386,7 @@ func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request) (status return http.StatusBadRequest, errInvalidDepth } } - return moveFiles(h.FileSystem, src, dst, r.Header.Get("Overwrite") == "T") + return moveFiles(ctx, h.FileSystem, src, dst, r.Header.Get("Overwrite") == "T") } func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request) (retStatus int, retErr error) { @@ -390,6 +399,7 @@ func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request) (retStatus return status, err } + ctx := getContext(r) token, ld, now, created := "", LockDetails{}, time.Now(), false if li == (lockInfo{}) { // An empty lockInfo means to refresh the lock. @@ -447,8 +457,8 @@ func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request) (retStatus }() // Create the resource if it didn't previously exist. - if _, err := h.FileSystem.Stat(reqPath); err != nil { - f, err := h.FileSystem.OpenFile(reqPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if _, err := h.FileSystem.Stat(ctx, reqPath); err != nil { + f, err := h.FileSystem.OpenFile(ctx, reqPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { // TODO: detect missing intermediate dirs and return http.StatusConflict? return http.StatusInternalServerError, err @@ -501,7 +511,8 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status if err != nil { return status, err } - fi, err := h.FileSystem.Stat(reqPath) + ctx := getContext(r) + fi, err := h.FileSystem.Stat(ctx, reqPath) if err != nil { if os.IsNotExist(err) { return http.StatusNotFound, err @@ -528,7 +539,7 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status } var pstats []Propstat if pf.Propname != nil { - pnames, err := propnames(h.FileSystem, h.LockSystem, reqPath) + pnames, err := propnames(ctx, h.FileSystem, h.LockSystem, reqPath) if err != nil { return err } @@ -538,9 +549,9 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status } pstats = append(pstats, pstat) } else if pf.Allprop != nil { - pstats, err = allprop(h.FileSystem, h.LockSystem, reqPath, pf.Prop) + pstats, err = allprop(ctx, h.FileSystem, h.LockSystem, reqPath, pf.Prop) } else { - pstats, err = props(h.FileSystem, h.LockSystem, reqPath, pf.Prop) + pstats, err = props(ctx, h.FileSystem, h.LockSystem, reqPath, pf.Prop) } if err != nil { return err @@ -548,7 +559,7 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status return mw.write(makePropstatResponse(path.Join(h.Prefix, reqPath), pstats)) } - walkErr := walkFS(h.FileSystem, depth, reqPath, fi, walkFn) + walkErr := walkFS(ctx, h.FileSystem, depth, reqPath, fi, walkFn) closeErr := mw.close() if walkErr != nil { return http.StatusInternalServerError, walkErr @@ -570,7 +581,9 @@ func (h *Handler) handleProppatch(w http.ResponseWriter, r *http.Request) (statu } defer release() - if _, err := h.FileSystem.Stat(reqPath); err != nil { + ctx := getContext(r) + + if _, err := h.FileSystem.Stat(ctx, reqPath); err != nil { if os.IsNotExist(err) { return http.StatusNotFound, err } @@ -580,7 +593,7 @@ func (h *Handler) handleProppatch(w http.ResponseWriter, r *http.Request) (statu if err != nil { return status, err } - pstats, err := patch(h.FileSystem, h.LockSystem, reqPath, patches) + pstats, err := patch(ctx, h.FileSystem, h.LockSystem, reqPath, patches) if err != nil { return http.StatusInternalServerError, err } diff --git a/vendor/golang.org/x/net/webdav/webdav_test.go b/vendor/golang.org/x/net/webdav/webdav_test.go index b068aab32..25e0d5421 100644 --- a/vendor/golang.org/x/net/webdav/webdav_test.go +++ b/vendor/golang.org/x/net/webdav/webdav_test.go @@ -18,6 +18,8 @@ import ( "sort" "strings" "testing" + + "golang.org/x/net/context" ) // TODO: add tests to check XML responses with the expected prefix path @@ -48,7 +50,7 @@ func TestPrefix(t *testing.T) { req.Header.Add(headers[0], headers[1]) headers = headers[2:] } - res, err := http.DefaultClient.Do(req) + res, err := http.DefaultTransport.RoundTrip(req) if err != nil { return nil, err } @@ -65,6 +67,7 @@ func TestPrefix(t *testing.T) { "/a/b/", "/a/b/c/", } + ctx := context.Background() for _, prefix := range prefixes { fs := NewMemFS() h := &Handler{ @@ -183,7 +186,7 @@ func TestPrefix(t *testing.T) { continue } - got, err := find(nil, fs, "/") + got, err := find(ctx, nil, fs, "/") if err != nil { t.Errorf("prefix=%-9q find: %v", prefix, err) continue @@ -202,57 +205,110 @@ func TestPrefix(t *testing.T) { } } +func TestEscapeXML(t *testing.T) { + // These test cases aren't exhaustive, and there is more than one way to + // escape e.g. a quot (as """ or """) or an apos. We presume that + // the encoding/xml package tests xml.EscapeText more thoroughly. This test + // here is just a sanity check for this package's escapeXML function, and + // its attempt to provide a fast path (and avoid a bytes.Buffer allocation) + // when escaping filenames is obviously a no-op. + testCases := map[string]string{ + "": "", + " ": " ", + "&": "&", + "*": "*", + "+": "+", + ",": ",", + "-": "-", + ".": ".", + "/": "/", + "0": "0", + "9": "9", + ":": ":", + "<": "<", + ">": ">", + "A": "A", + "_": "_", + "a": "a", + "~": "~", + "\u0201": "\u0201", + "&": "&amp;", + "foo&<b/ar>baz": "foo&<b/ar>baz", + } + + for in, want := range testCases { + if got := escapeXML(in); got != want { + t.Errorf("in=%q: got %q, want %q", in, got, want) + } + } +} + func TestFilenameEscape(t *testing.T) { - re := regexp.MustCompile(`<D:href>([^<]*)</D:href>`) - do := func(method, urlStr string) (string, error) { + hrefRe := regexp.MustCompile(`<D:href>([^<]*)</D:href>`) + displayNameRe := regexp.MustCompile(`<D:displayname>([^<]*)</D:displayname>`) + do := func(method, urlStr string) (string, string, error) { req, err := http.NewRequest(method, urlStr, nil) if err != nil { - return "", err + return "", "", err } res, err := http.DefaultClient.Do(req) if err != nil { - return "", err + return "", "", err } defer res.Body.Close() b, err := ioutil.ReadAll(res.Body) if err != nil { - return "", err + return "", "", err + } + hrefMatch := hrefRe.FindStringSubmatch(string(b)) + if len(hrefMatch) != 2 { + return "", "", errors.New("D:href not found") } - m := re.FindStringSubmatch(string(b)) - if len(m) != 2 { - return "", errors.New("D:href not found") + displayNameMatch := displayNameRe.FindStringSubmatch(string(b)) + if len(displayNameMatch) != 2 { + return "", "", errors.New("D:displayname not found") } - return m[1], nil + return hrefMatch[1], displayNameMatch[1], nil } testCases := []struct { - name, want string + name, wantHref, wantDisplayName string }{{ - name: `/foo%bar`, - want: `/foo%25bar`, + name: `/foo%bar`, + wantHref: `/foo%25bar`, + wantDisplayName: `foo%bar`, }, { - name: `/こんにちわ世界`, - want: `/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%82%8F%E4%B8%96%E7%95%8C`, + name: `/こんにちわ世界`, + wantHref: `/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%82%8F%E4%B8%96%E7%95%8C`, + wantDisplayName: `こんにちわ世界`, }, { - name: `/Program Files/`, - want: `/Program%20Files`, + name: `/Program Files/`, + wantHref: `/Program%20Files`, + wantDisplayName: `Program Files`, }, { - name: `/go+lang`, - want: `/go+lang`, + name: `/go+lang`, + wantHref: `/go+lang`, + wantDisplayName: `go+lang`, }, { - name: `/go&lang`, - want: `/go&lang`, + name: `/go&lang`, + wantHref: `/go&lang`, + wantDisplayName: `go&lang`, + }, { + name: `/go<lang`, + wantHref: `/go%3Clang`, + wantDisplayName: `go<lang`, }} + ctx := context.Background() fs := NewMemFS() for _, tc := range testCases { if strings.HasSuffix(tc.name, "/") { - if err := fs.Mkdir(tc.name, 0755); err != nil { + if err := fs.Mkdir(ctx, tc.name, 0755); err != nil { t.Fatalf("name=%q: Mkdir: %v", tc.name, err) } } else { - f, err := fs.OpenFile(tc.name, os.O_CREATE, 0644) + f, err := fs.OpenFile(ctx, tc.name, os.O_CREATE, 0644) if err != nil { t.Fatalf("name=%q: OpenFile: %v", tc.name, err) } @@ -273,13 +329,16 @@ func TestFilenameEscape(t *testing.T) { for _, tc := range testCases { u.Path = tc.name - got, err := do("PROPFIND", u.String()) + gotHref, gotDisplayName, err := do("PROPFIND", u.String()) if err != nil { t.Errorf("name=%q: PROPFIND: %v", tc.name, err) continue } - if got != tc.want { - t.Errorf("name=%q: got %q, want %q", tc.name, got, tc.want) + if gotHref != tc.wantHref { + t.Errorf("name=%q: got href %q, want %q", tc.name, gotHref, tc.wantHref) + } + if gotDisplayName != tc.wantDisplayName { + t.Errorf("name=%q: got dispayname %q, want %q", tc.name, gotDisplayName, tc.wantDisplayName) } } } |