serve webdav: fix serveDir not being updated with changes from webdav

Fixes an issue where changes such as renaming done using webdav
would not be reflected in the html directory listing
This commit is contained in:
Gary Kim 2019-06-13 17:51:16 +08:00 committed by Nick Craig-Wood
parent 5597d6d871
commit 6e8e620e71
3 changed files with 55 additions and 25 deletions

View File

@ -43,7 +43,7 @@ control the stats printing.
cmd.CheckArgs(1, 1, command, args)
f := cmd.NewFsSrc(args)
cmd.Run(false, true, command, func() error {
s := NewServer(f, &httpflags.Opt)
s := newServer(f, &httpflags.Opt)
err := s.Serve()
if err != nil {
return err
@ -54,29 +54,28 @@ control the stats printing.
},
}
// Server contains everything to run the Server
type Server struct {
// server contains everything to run the server
type server struct {
*httplib.Server
f fs.Fs
vfs *vfs.VFS
}
// NewServer creates a new http server
func NewServer(f fs.Fs, opt *httplib.Options) *Server {
func newServer(f fs.Fs, opt *httplib.Options) *server {
mux := http.NewServeMux()
s := &Server{
s := &server{
Server: httplib.NewServer(mux, opt),
f: f,
vfs: vfs.New(f, &vfsflags.Opt),
}
mux.HandleFunc("/", s.Handler)
mux.HandleFunc("/", s.handler)
return s
}
// Serve runs the http Server in the background.
// Serve runs the http server in the background.
//
// Use s.Close() and s.Wait() to shutdown Server
func (s *Server) Serve() error {
// Use s.Close() and s.Wait() to shutdown server
func (s *server) Serve() error {
err := s.Server.Serve()
if err != nil {
return err
@ -85,8 +84,8 @@ func (s *Server) Serve() error {
return nil
}
// Handler reads incoming requests and dispatches them
func (s *Server) Handler(w http.ResponseWriter, r *http.Request) {
// handler reads incoming requests and dispatches them
func (s *server) handler(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" && r.Method != "HEAD" {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
@ -105,7 +104,7 @@ func (s *Server) Handler(w http.ResponseWriter, r *http.Request) {
}
// serveDir serves a directory index at dirRemote
func (s *Server) serveDir(w http.ResponseWriter, r *http.Request, dirRemote string) {
func (s *server) serveDir(w http.ResponseWriter, r *http.Request, dirRemote string) {
// List the directory
node, err := s.vfs.Stat(dirRemote)
if err == vfs.ENOENT {
@ -136,7 +135,7 @@ func (s *Server) serveDir(w http.ResponseWriter, r *http.Request, dirRemote stri
}
// serveFile serves a file object at remote
func (s *Server) serveFile(w http.ResponseWriter, r *http.Request, remote string) {
func (s *server) serveFile(w http.ResponseWriter, r *http.Request, remote string) {
node, err := s.vfs.Stat(remote)
if err == vfs.ENOENT {
fs.Infof(remote, "%s: File not found", r.RemoteAddr)

View File

@ -19,7 +19,7 @@ import (
var (
updateGolden = flag.Bool("updategolden", false, "update golden files for regression test")
httpServer *Server
httpServer *server
testURL string
)
@ -30,7 +30,7 @@ const (
func startServer(t *testing.T, f fs.Fs) {
opt := httplib.DefaultOpt
opt.ListenAddr = testBindAddress
httpServer = NewServer(f, &opt)
httpServer = newServer(f, &opt)
assert.NoError(t, httpServer.Serve())
testURL = httpServer.Server.URL()

View File

@ -9,9 +9,9 @@ import (
"strings"
"github.com/ncw/rclone/cmd"
rhttp "github.com/ncw/rclone/cmd/serve/http"
"github.com/ncw/rclone/cmd/serve/httplib"
"github.com/ncw/rclone/cmd/serve/httplib/httpflags"
"github.com/ncw/rclone/cmd/serve/httplib/serve"
"github.com/ncw/rclone/fs"
"github.com/ncw/rclone/fs/hash"
"github.com/ncw/rclone/fs/log"
@ -41,8 +41,8 @@ var Command = &cobra.Command{
Long: `
rclone serve webdav implements a basic webdav server to serve the
remote over HTTP via the webdav protocol. This can be viewed with a
webdav client or you can make a remote of type webdav to read and
write it.
webdav client, through a web browser, or you can make a remote of
type webdav to read and write it.
### Webdav options
@ -103,7 +103,6 @@ type WebDAV struct {
f fs.Fs
vfs *vfs.VFS
webdavhandler *webdav.Handler
httpserver *rhttp.Server
}
// check interface
@ -121,21 +120,53 @@ func newWebDAV(f fs.Fs, opt *httplib.Options) *WebDAV {
Logger: w.logRequest, // FIXME
}
w.webdavhandler = webdavHandler
if !disableGETDir {
w.httpserver = rhttp.NewServer(f, opt)
}
w.Server = httplib.NewServer(http.HandlerFunc(w.handler), opt)
return w
}
func (w *WebDAV) handler(rw http.ResponseWriter, r *http.Request) {
if !disableGETDir && (r.Method == "GET" || r.Method == "HEAD") && strings.HasSuffix(r.URL.Path, "/") {
w.httpserver.Handler(rw, r)
urlPath := r.URL.Path
isDir := strings.HasSuffix(urlPath, "/")
remote := strings.Trim(urlPath, "/")
if !disableGETDir && (r.Method == "GET" || r.Method == "HEAD") && isDir {
w.serveDir(rw, r, remote)
return
}
w.webdavhandler.ServeHTTP(rw, r)
}
// serveDir serves a directory index at dirRemote
// This is similar to serveDir in serve http.
func (w *WebDAV) serveDir(rw http.ResponseWriter, r *http.Request, dirRemote string) {
// List the directory
node, err := w.vfs.Stat(dirRemote)
if err == vfs.ENOENT {
http.Error(rw, "Directory not found", http.StatusNotFound)
return
} else if err != nil {
serve.Error(dirRemote, rw, "Failed to list directory", err)
return
}
if !node.IsDir() {
http.Error(rw, "Not a directory", http.StatusNotFound)
return
}
dir := node.(*vfs.Dir)
dirEntries, err := dir.ReadDirAll()
if err != nil {
serve.Error(dirRemote, rw, "Failed to list directory", err)
return
}
// Make the entries for display
directory := serve.NewDirectory(dirRemote, w.HTMLTemplate)
for _, node := range dirEntries {
directory.AddEntry(node.Path(), node.IsDir())
}
directory.Serve(rw, r)
}
// serve runs the http server in the background.
//
// Use s.Close() and s.Wait() to shutdown server