"html"
"html/template"
"io"
- "log"
"net/http"
"net/url"
"os"
+ "path/filepath"
"sort"
"strconv"
"strings"
"git.curoverse.com/arvados.git/sdk/go/health"
"git.curoverse.com/arvados.git/sdk/go/httpserver"
"git.curoverse.com/arvados.git/sdk/go/keepclient"
+ log "github.com/Sirupsen/logrus"
"golang.org/x/net/webdav"
)
}
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)
}
"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.
} else if w.WroteStatus() == 0 {
w.WriteHeader(statusCode)
} else if w.WroteStatus() != statusCode {
- httpserver.Log(r.RemoteAddr, "WARNING",
+ log.WithField("RequestID", r.Header.Get("X-Request-Id")).Warn(
fmt.Sprintf("Our status changed from %d to %d after we sent headers", w.WroteStatus(), statusCode))
}
if statusText == "" {
statusText = http.StatusText(statusCode)
}
- httpserver.Log(remoteAddr, statusCode, statusText, w.WroteBodyBytes(), r.Method, r.Host, r.URL.Path, r.URL.RawQuery)
}()
if strings.HasPrefix(r.URL.Path, "/_health/") && r.Method == "GET" {
} else if r.URL.Path == "/status.json" {
h.serveStatus(w, r)
return
- } else if r.URL.Path == "/" || (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...]
return
}
+ if useSiteFS {
+ if tokens == nil {
+ tokens = auth.NewCredentialsFromHTTPRequest(r).Tokens
+ }
+ h.serveSiteFS(w, r, tokens, credentialsOK, attachment)
+ return
+ }
+
targetPath := pathParts[stripParts:]
if tokens == nil && len(targetPath) > 0 && strings.HasPrefix(targetPath[0], "t=") {
// http://ID.example/t=TOKEN/PATH...
tokens = append(reqTokens, h.Config.AnonymousTokens...)
}
- if useSiteFS {
- h.serveSiteFS(w, r, tokens)
- return
- }
-
if len(targetPath) > 0 && targetPath[0] == "_" {
// If a collection has a directory called "t=foo" or
// "_", it can be served at
statusCode, statusText = http.StatusInternalServerError, err.Error()
return
}
+ kc.RequestID = r.Header.Get("X-Request-Id")
var basename string
if len(targetPath) > 0 {
}
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 {
}
}
-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)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
- client := &arvados.Client{
+ kc.RequestID = r.Header.Get("X-Request-Id")
+ 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: "/",
<UL>
{{range .Files}}
{{if .IsDir }}
- <LI>{{" " | printf "%15s " | nbsp}}<A href="{{.Name}}/">{{.Name}}/</A></LI>
+ <LI>{{" " | printf "%15s " | nbsp}}<A href="{{print "./" .Name}}/">{{.Name}}/</A></LI>
{{else}}
- <LI>{{.Size | printf "%15d " | nbsp}}<A href="{{.Name}}">{{.Name}}</A></LI>
+ <LI>{{.Size | printf "%15d " | nbsp}}<A href="{{print "./" .Name}}">{{.Name}}</A></LI>
{{end}}
{{end}}
</UL>