diff --git a/.gitignore b/.gitignore index 9627f353d..eb20c39cf 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ docs/public rclone.iml .idea .history +.vscode *.test *.iml fuzz-build.zip diff --git a/docs/content/flags.md b/docs/content/flags.md index d5768783e..358520448 100644 --- a/docs/content/flags.md +++ b/docs/content/flags.md @@ -281,6 +281,7 @@ Flags to control the Remote Control API. --rc-realm string Realm for authentication --rc-salt string Password hashing salt (default "dlPL2MqE") --rc-serve Enable the serving of remote objects + --rc-serve-no-modtime Don't read the modification time (can speed things up) --rc-server-read-timeout Duration Timeout for server reading data (default 1h0m0s) --rc-server-write-timeout Duration Timeout for server writing data (default 1h0m0s) --rc-template string User-specified template diff --git a/docs/content/rc.md b/docs/content/rc.md index 953bc4a51..d0cec5cc8 100644 --- a/docs/content/rc.md +++ b/docs/content/rc.md @@ -77,6 +77,12 @@ remotes using this syntax http://127.0.0.1:5572/[remote:path]/path/to/object Default Off. +### --rc-serve-no-modtime + +Set this flag to skip reading the modification time (can speed things up). + +Default Off. + ### --rc-files /path/to/directory Path to local files to serve on the HTTP server. diff --git a/fs/rc/rc.go b/fs/rc/rc.go index b7db4e587..ad2b47b52 100644 --- a/fs/rc/rc.go +++ b/fs/rc/rc.go @@ -23,6 +23,7 @@ type Options struct { Template libhttp.TemplateConfig Enabled bool // set to enable the server Serve bool // set to serve files from remotes + ServeNoModTime bool // don't read the modification time Files string // set to enable serving files locally NoAuth bool // set to disable auth checks on AuthRequired methods WebUI bool // set to launch the web ui diff --git a/fs/rc/rcflags/rcflags.go b/fs/rc/rcflags/rcflags.go index 6711d5255..60c89092b 100644 --- a/fs/rc/rcflags/rcflags.go +++ b/fs/rc/rcflags/rcflags.go @@ -21,6 +21,7 @@ func AddFlags(flagSet *pflag.FlagSet) { flags.BoolVarP(flagSet, &Opt.Enabled, "rc", "", false, "Enable the remote control server", "RC") flags.StringVarP(flagSet, &Opt.Files, "rc-files", "", "", "Path to local files to serve on the HTTP server", "RC") flags.BoolVarP(flagSet, &Opt.Serve, "rc-serve", "", false, "Enable the serving of remote objects", "RC") + flags.BoolVarP(flagSet, &Opt.ServeNoModTime, "rc-serve-no-modtime", "", false, "Don't read the modification time (can speed things up)", "RC") flags.BoolVarP(flagSet, &Opt.NoAuth, "rc-no-auth", "", false, "Don't require auth for certain methods", "RC") flags.BoolVarP(flagSet, &Opt.WebUI, "rc-web-gui", "", false, "Launch WebGUI on localhost", "RC") flags.BoolVarP(flagSet, &Opt.WebGUIUpdate, "rc-web-gui-update", "", false, "Check and update to latest version of web gui", "RC") diff --git a/fs/rc/rcserver/rcserver.go b/fs/rc/rcserver/rcserver.go index 4ded73a6c..21378e8ec 100644 --- a/fs/rc/rcserver/rcserver.go +++ b/fs/rc/rcserver/rcserver.go @@ -340,8 +340,11 @@ func (s *Server) serveRemote(w http.ResponseWriter, r *http.Request, path string directory := serve.NewDirectory(path, s.server.HTMLTemplate()) for _, entry := range entries { _, isDir := entry.(fs.Directory) - //directory.AddHTMLEntry(entry.Remote(), isDir, entry.Size(), entry.ModTime(r.Context())) - directory.AddHTMLEntry(entry.Remote(), isDir, entry.Size(), time.Time{}) + var modTime time.Time + if !s.opt.ServeNoModTime { + modTime = entry.ModTime(r.Context()) + } + directory.AddHTMLEntry(entry.Remote(), isDir, entry.Size(), modTime) } sortParm := r.URL.Query().Get("sort") orderParm := r.URL.Query().Get("order") diff --git a/fs/rc/rcserver/rcserver_test.go b/fs/rc/rcserver/rcserver_test.go index 05889ecc9..47ec89e58 100644 --- a/fs/rc/rcserver/rcserver_test.go +++ b/fs/rc/rcserver/rcserver_test.go @@ -8,6 +8,7 @@ import ( "net/http" "net/http/httptest" "os" + "path/filepath" "regexp" "strings" "testing" @@ -23,10 +24,10 @@ import ( ) const ( - testBindAddress = "localhost:0" - testTemplate = "testdata/golden/testindex.html" - testFs = "testdata/files" - remoteURL = "[" + testFs + "]/" // initial URL path to fetch from that remote + testBindAddress = "localhost:0" + defaultTestTemplate = "testdata/golden/testindex.html" + testFs = "testdata/files" + remoteURL = "[" + testFs + "]/" // initial URL path to fetch from that remote ) func TestMain(m *testing.M) { @@ -49,7 +50,7 @@ func TestMain(m *testing.M) { func TestRcServer(t *testing.T) { opt := rc.DefaultOpt opt.HTTP.ListenAddr = []string{testBindAddress} - opt.Template.Path = testTemplate + opt.Template.Path = defaultTestTemplate opt.Enabled = true opt.Serve = true opt.Files = testFs @@ -102,15 +103,21 @@ type testRun struct { // Run a suite of tests func testServer(t *testing.T, tests []testRun, opt *rc.Options) { + t.Helper() + ctx := context.Background() configfile.Install() - opt.Template.Path = testTemplate + if opt.Template.Path == "" { + opt.Template.Path = defaultTestTemplate + } rcServer, err := newServer(ctx, opt, http.DefaultServeMux) require.NoError(t, err) testURL := rcServer.server.URLs()[0] mux := rcServer.server.Router() for _, test := range tests { t.Run(test.Name, func(t *testing.T) { + t.Helper() + method := test.Method if method == "" { method = "GET" @@ -172,6 +179,7 @@ func TestFileServing(t *testing.T) { Expected: `
 dir/
 file.txt
+modtime/
 
`, }, { @@ -243,6 +251,7 @@ func TestRemoteServing(t *testing.T) {

Directory listing of /

dir/
+modtime/
file.txt
@@ -804,3 +813,37 @@ func TestRCDebug(t *testing.T) { opt.Files = "" testServer(t, tests, &opt) } + +func TestServeModTime(t *testing.T) { + for file, mtime := range map[string]time.Time{ + "dir": time.Date(2023, 4, 12, 21, 15, 17, 0, time.UTC), + "modtime.txt": time.Date(2021, 1, 18, 5, 2, 28, 0, time.UTC), + } { + path := filepath.Join(testFs, "modtime", file) + err := os.Chtimes(path, mtime, mtime) + require.NoError(t, err) + } + + opt := newTestOpt() + opt.Serve = true + opt.Template.Path = "testdata/golden/testmodtime.html" + + tests := []testRun{{ + Name: "modtime", + Method: "GET", + URL: remoteURL + "modtime/", + Status: http.StatusOK, + Expected: "* dir/ - 2023-04-12T21:15:17Z\n* modtime.txt - 2021-01-18T05:02:28Z\n", + }} + testServer(t, tests, &opt) + + opt.ServeNoModTime = true + tests = []testRun{{ + Name: "no modtime", + Method: "GET", + URL: remoteURL + "modtime/", + Status: http.StatusOK, + Expected: "* dir/ - 0001-01-01T00:00:00Z\n* modtime.txt - 0001-01-01T00:00:00Z\n", + }} + testServer(t, tests, &opt) +} diff --git a/fs/rc/rcserver/testdata/files/modtime/dir/.gitkeep b/fs/rc/rcserver/testdata/files/modtime/dir/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/fs/rc/rcserver/testdata/files/modtime/modtime.txt b/fs/rc/rcserver/testdata/files/modtime/modtime.txt new file mode 100644 index 000000000..e69de29bb diff --git a/fs/rc/rcserver/testdata/golden/testmodtime.html b/fs/rc/rcserver/testdata/golden/testmodtime.html new file mode 100644 index 000000000..095770221 --- /dev/null +++ b/fs/rc/rcserver/testdata/golden/testmodtime.html @@ -0,0 +1,2 @@ +{{ range .Entries }}* {{ .Leaf }} - {{ .ModTime.UTC.Format "2006-01-02T15:04:05Z07:00" }} +{{ end }} \ No newline at end of file