webdav_test.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package webdav
  5. import (
  6. "fmt"
  7. "io"
  8. "net/http"
  9. "net/http/httptest"
  10. "reflect"
  11. "sort"
  12. "strings"
  13. "testing"
  14. )
  15. // TestStripPrefix tests the StripPrefix function. We can't test the
  16. // StripPrefix function with the litmus test, even though all of the litmus
  17. // test paths start with "/litmus/", because one of the first things that the
  18. // litmus test does is "MKCOL /litmus/". That request succeeds without a
  19. // StripPrefix, but fails with a StripPrefix because you cannot MKCOL the root
  20. // directory of a FileSystem.
  21. func TestStripPrefix(t *testing.T) {
  22. const dst, blah = "Destination", "blah blah blah"
  23. do := func(method, urlStr string, body io.Reader, wantStatusCode int, headers ...string) error {
  24. req, err := http.NewRequest(method, urlStr, body)
  25. if err != nil {
  26. return err
  27. }
  28. for len(headers) >= 2 {
  29. req.Header.Add(headers[0], headers[1])
  30. headers = headers[2:]
  31. }
  32. res, err := http.DefaultClient.Do(req)
  33. if err != nil {
  34. return err
  35. }
  36. defer res.Body.Close()
  37. if res.StatusCode != wantStatusCode {
  38. return fmt.Errorf("got status code %d, want %d", res.StatusCode, wantStatusCode)
  39. }
  40. return nil
  41. }
  42. prefixes := []string{
  43. "/",
  44. "/a/",
  45. "/a/b/",
  46. "/a/b/c/",
  47. }
  48. for _, prefix := range prefixes {
  49. fs := NewMemFS()
  50. h := http.Handler(&Handler{
  51. FileSystem: fs,
  52. LockSystem: NewMemLS(),
  53. })
  54. mux := http.NewServeMux()
  55. if prefix != "/" {
  56. // Note that this is webdav.StripPrefix, not http.StripPrefix.
  57. h = StripPrefix(prefix, h)
  58. }
  59. mux.Handle(prefix, h)
  60. srv := httptest.NewServer(mux)
  61. defer srv.Close()
  62. // The script is:
  63. // MKCOL /a
  64. // MKCOL /a/b
  65. // PUT /a/b/c
  66. // COPY /a/b/c /a/b/d
  67. // MKCOL /a/b/e
  68. // MOVE /a/b/d /a/b/e/f
  69. // which should yield the (possibly stripped) filenames /a/b/c and
  70. // /a/b/e/f, plus their parent directories.
  71. wantA := map[string]int{
  72. "/": http.StatusCreated,
  73. "/a/": http.StatusMovedPermanently,
  74. "/a/b/": http.StatusNotFound,
  75. "/a/b/c/": http.StatusNotFound,
  76. }[prefix]
  77. if err := do("MKCOL", srv.URL+"/a", nil, wantA); err != nil {
  78. t.Errorf("prefix=%-9q MKCOL /a: %v", prefix, err)
  79. continue
  80. }
  81. wantB := map[string]int{
  82. "/": http.StatusCreated,
  83. "/a/": http.StatusCreated,
  84. "/a/b/": http.StatusMovedPermanently,
  85. "/a/b/c/": http.StatusNotFound,
  86. }[prefix]
  87. if err := do("MKCOL", srv.URL+"/a/b", nil, wantB); err != nil {
  88. t.Errorf("prefix=%-9q MKCOL /a/b: %v", prefix, err)
  89. continue
  90. }
  91. wantC := map[string]int{
  92. "/": http.StatusCreated,
  93. "/a/": http.StatusCreated,
  94. "/a/b/": http.StatusCreated,
  95. "/a/b/c/": http.StatusMovedPermanently,
  96. }[prefix]
  97. if err := do("PUT", srv.URL+"/a/b/c", strings.NewReader(blah), wantC); err != nil {
  98. t.Errorf("prefix=%-9q PUT /a/b/c: %v", prefix, err)
  99. continue
  100. }
  101. wantD := map[string]int{
  102. "/": http.StatusCreated,
  103. "/a/": http.StatusCreated,
  104. "/a/b/": http.StatusCreated,
  105. "/a/b/c/": http.StatusMovedPermanently,
  106. }[prefix]
  107. if err := do("COPY", srv.URL+"/a/b/c", nil, wantD, dst, srv.URL+"/a/b/d"); err != nil {
  108. t.Errorf("prefix=%-9q COPY /a/b/c /a/b/d: %v", prefix, err)
  109. continue
  110. }
  111. wantE := map[string]int{
  112. "/": http.StatusCreated,
  113. "/a/": http.StatusCreated,
  114. "/a/b/": http.StatusCreated,
  115. "/a/b/c/": http.StatusNotFound,
  116. }[prefix]
  117. if err := do("MKCOL", srv.URL+"/a/b/e", nil, wantE); err != nil {
  118. t.Errorf("prefix=%-9q MKCOL /a/b/e: %v", prefix, err)
  119. continue
  120. }
  121. wantF := map[string]int{
  122. "/": http.StatusCreated,
  123. "/a/": http.StatusCreated,
  124. "/a/b/": http.StatusCreated,
  125. "/a/b/c/": http.StatusNotFound,
  126. }[prefix]
  127. if err := do("MOVE", srv.URL+"/a/b/d", nil, wantF, dst, srv.URL+"/a/b/e/f"); err != nil {
  128. t.Errorf("prefix=%-9q MOVE /a/b/d /a/b/e/f: %v", prefix, err)
  129. continue
  130. }
  131. got, err := find(nil, fs, "/")
  132. if err != nil {
  133. t.Errorf("prefix=%-9q find: %v", prefix, err)
  134. continue
  135. }
  136. sort.Strings(got)
  137. want := map[string][]string{
  138. "/": []string{"/", "/a", "/a/b", "/a/b/c", "/a/b/e", "/a/b/e/f"},
  139. "/a/": []string{"/", "/b", "/b/c", "/b/e", "/b/e/f"},
  140. "/a/b/": []string{"/", "/c", "/e", "/e/f"},
  141. "/a/b/c/": []string{"/"},
  142. }[prefix]
  143. if !reflect.DeepEqual(got, want) {
  144. t.Errorf("prefix=%-9q find:\ngot %v\nwant %v", prefix, got, want)
  145. continue
  146. }
  147. }
  148. }