X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/418c57bce3aac1a22548e53e1018a1547d9efee4..fd86245d5c68c0c82224030e98b7f26974dc1b5c:/services/keep-web/handler.go diff --git a/services/keep-web/handler.go b/services/keep-web/handler.go index 00af0f4eab..4ffac26797 100644 --- a/services/keep-web/handler.go +++ b/services/keep-web/handler.go @@ -14,6 +14,7 @@ import ( "net/http" "net/url" "os" + "path/filepath" "sort" "strconv" "strings" @@ -112,12 +113,12 @@ type updateOnSuccess struct { } func (uos *updateOnSuccess) Write(p []byte) (int, error) { - if uos.err != nil { - return 0, uos.err - } if !uos.sentHeader { uos.WriteHeader(http.StatusOK) } + if uos.err != nil { + return 0, uos.err + } return uos.ResponseWriter.Write(p) } @@ -163,6 +164,12 @@ var ( "HEAD": true, "POST": true, } + // top-level dirs to serve with siteFS + siteFSDir = map[string]bool{ + "": true, // root directory + "by_id": true, + "users": true, + } ) // ServeHTTP implements http.Handler. @@ -250,7 +257,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) { } else if r.URL.Path == "/status.json" { h.serveStatus(w, r) return - } else if len(pathParts) >= 1 && pathParts[0] == "users" { + } else if siteFSDir[pathParts[0]] { useSiteFS = true } else if len(pathParts) >= 1 && strings.HasPrefix(pathParts[0], "c=") { // /c=ID[/PATH...] @@ -329,7 +336,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) { } if useSiteFS { - h.serveSiteFS(w, r, tokens) + h.serveSiteFS(w, r, tokens, credentialsOK, attachment) return } @@ -417,11 +424,11 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) { } applyContentDispositionHdr(w, r, basename, attachment) - client := &arvados.Client{ + client := (&arvados.Client{ APIHost: arv.ApiServer, AuthToken: arv.ApiToken, Insecure: arv.ApiInsecure, - } + }).WithRequestID(r.Header.Get("X-Request-Id")) fs, err := collection.FileSystem(client, kc) if err != nil { @@ -499,7 +506,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) { } } -func (h *handler) serveSiteFS(w http.ResponseWriter, r *http.Request, tokens []string) { +func (h *handler) serveSiteFS(w http.ResponseWriter, r *http.Request, tokens []string, credentialsOK, attachment bool) { if len(tokens) == 0 { w.Header().Add("WWW-Authenticate", "Basic realm=\"collections\"") http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) @@ -522,24 +529,32 @@ func (h *handler) serveSiteFS(w http.ResponseWriter, r *http.Request, tokens []s http.Error(w, err.Error(), http.StatusInternalServerError) return } - client := &arvados.Client{ + client := (&arvados.Client{ APIHost: arv.ApiServer, AuthToken: arv.ApiToken, Insecure: arv.ApiInsecure, - } + }).WithRequestID(r.Header.Get("X-Request-Id")) fs := client.SiteFileSystem(kc) - if f, err := fs.Open(r.URL.Path); os.IsNotExist(err) { + f, err := fs.Open(r.URL.Path) + if os.IsNotExist(err) { http.Error(w, err.Error(), http.StatusNotFound) return } else if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return - } else if fi, err := f.Stat(); err == nil && fi.IsDir() && r.Method == "GET" { - - h.serveDirectory(w, r, fi.Name(), fs, r.URL.Path, false) + } + defer f.Close() + if fi, err := f.Stat(); err == nil && fi.IsDir() && r.Method == "GET" { + if !strings.HasSuffix(r.URL.Path, "/") { + h.seeOtherWithCookie(w, r, r.URL.Path+"/", credentialsOK) + } else { + h.serveDirectory(w, r, fi.Name(), fs, r.URL.Path, false) + } return - } else { - f.Close() + } + if r.Method == "GET" { + _, basename := filepath.Split(r.URL.Path) + applyContentDispositionHdr(w, r, basename, attachment) } wh := webdav.Handler{ Prefix: "/",