"sync"
"git.arvados.org/arvados.git/lib/cmd"
+ "git.arvados.org/arvados.git/lib/webdavfs"
"git.arvados.org/arvados.git/sdk/go/arvados"
"git.arvados.org/arvados.git/sdk/go/arvadosclient"
"git.arvados.org/arvados.git/sdk/go/auth"
Cache cache
Cluster *arvados.Cluster
setupOnce sync.Once
- webdavLS webdav.LockSystem
}
var urlPDHDecoder = strings.NewReplacer(" ", "+", "-", "+")
func (h *handler) setup() {
keepclient.DefaultBlockCache.MaxBlocks = h.Cluster.Collections.WebDAVCache.MaxBlockEntries
-
- // Even though we don't accept LOCK requests, every webdav
- // handler must have a non-nil LockSystem.
- h.webdavLS = &noLockSystem{}
}
func (h *handler) serveStatus(w http.ResponseWriter, r *http.Request) {
return
}
- pathParts := strings.Split(r.URL.Path[1:], "/")
+ webdavPrefix := ""
+ arvPath := r.URL.Path
+ if prefix := r.Header.Get("X-Webdav-Prefix"); prefix != "" {
+ // Enable a proxy (e.g., container log handler in
+ // controller) to satisfy a request for path
+ // "/foo/bar/baz.txt" using content from
+ // "//abc123-4.internal/bar/baz.txt", by adding a
+ // request header "X-Webdav-Prefix: /foo"
+ if !strings.HasPrefix(arvPath, prefix) {
+ http.Error(w, "X-Webdav-Prefix header is not a prefix of the requested path", http.StatusBadRequest)
+ return
+ }
+ arvPath = r.URL.Path[len(prefix):]
+ if arvPath == "" {
+ arvPath = "/"
+ }
+ w.Header().Set("Vary", "X-Webdav-Prefix, "+w.Header().Get("Vary"))
+ webdavPrefix = prefix
+ }
+ pathParts := strings.Split(arvPath[1:], "/")
var stripParts int
var collectionID string
fsprefix := ""
if useSiteFS {
if writeMethod[r.Method] {
- http.Error(w, errReadOnly.Error(), http.StatusMethodNotAllowed)
+ http.Error(w, webdavfs.ErrReadOnly.Error(), http.StatusMethodNotAllowed)
return
}
if len(reqTokens) == 0 {
basename = targetPath[len(targetPath)-1]
}
if arvadosclient.PDHMatch(collectionID) && writeMethod[r.Method] {
- http.Error(w, errReadOnly.Error(), http.StatusMethodNotAllowed)
+ http.Error(w, webdavfs.ErrReadOnly.Error(), http.StatusMethodNotAllowed)
return
}
if !h.userPermittedToUploadOrDownload(r.Method, tokenUser) {
if r.Method == http.MethodGet {
applyContentDispositionHdr(w, r, basename, attachment)
}
+ if webdavPrefix == "" {
+ webdavPrefix = "/" + strings.Join(pathParts[:stripParts], "/")
+ }
wh := webdav.Handler{
- Prefix: "/" + strings.Join(pathParts[:stripParts], "/"),
- FileSystem: &webdavFS{
- collfs: sessionFS,
- prefix: fsprefix,
- writing: writeMethod[r.Method],
- alwaysReadEOF: r.Method == "PROPFIND",
+ Prefix: webdavPrefix,
+ FileSystem: &webdavfs.FS{
+ FileSystem: sessionFS,
+ Prefix: fsprefix,
+ Writing: writeMethod[r.Method],
+ AlwaysReadEOF: r.Method == "PROPFIND",
},
- LockSystem: h.webdavLS,
+ LockSystem: webdavfs.NoLockSystem,
Logger: func(r *http.Request, err error) {
if err != nil {
ctxlog.FromContext(r.Context()).WithError(err).Error("error reported by webdav handler")