serve http: add Last-Modified headers to files and directories

This means that using `rclone serve http` preserves modification times
when used with the http backend.

Fixes #4201
This commit is contained in:
Nick Craig-Wood 2020-05-05 09:41:08 +01:00
parent ef9e6794c2
commit bdc91eda0f
2 changed files with 29 additions and 0 deletions

View file

@ -138,6 +138,9 @@ func (s *server) serveDir(w http.ResponseWriter, r *http.Request, dirRemote stri
orderParm := r.URL.Query().Get("order")
directory.ProcessQueryParams(sortParm, orderParm)
// Set the Last-Modified header to the timestamp
w.Header().Set("Last-Modified", dir.ModTime().UTC().Format(http.TimeFormat))
directory.Serve(w, r)
}
@ -175,6 +178,9 @@ func (s *server) serveFile(w http.ResponseWriter, r *http.Request, remote string
w.Header().Set("Content-Type", mimeType)
}
// Set the Last-Modified header to the timestamp
w.Header().Set("Last-Modified", file.ModTime().UTC().Format(http.TimeFormat))
// If HEAD no need to read the object since we have set the headers
if r.Method == "HEAD" {
return

View file

@ -1,6 +1,7 @@
package http
import (
"context"
"flag"
"io/ioutil"
"net/http"
@ -50,6 +51,11 @@ func startServer(t *testing.T, f fs.Fs) {
}
var (
datedObject = "two.txt"
expectedTime = time.Date(2000, 1, 2, 3, 4, 5, 0, time.UTC)
)
func TestInit(t *testing.T) {
// Configure the remote
config.LoadConfig()
@ -65,6 +71,11 @@ func TestInit(t *testing.T) {
f, err := fs.NewFs("testdata/files")
require.NoError(t, err)
// set date of datedObject to expectedTime
obj, err := f.NewObject(context.Background(), datedObject)
require.NoError(t, err)
require.NoError(t, obj.SetModTime(context.Background(), expectedTime))
startServer(t, f)
}
@ -195,6 +206,18 @@ func TestGET(t *testing.T) {
body, err := ioutil.ReadAll(resp.Body)
require.NoError(t, err)
// Check we got a Last-Modifed header and that it is a valid date
if test.Status == http.StatusOK || test.Status == http.StatusPartialContent {
lastModified := resp.Header.Get("Last-Modified")
assert.NotEqual(t, "", lastModified, test.Golden)
modTime, err := http.ParseTime(lastModified)
assert.NoError(t, err, test.Golden)
// check the actual date on our special file
if test.URL == datedObject {
assert.Equal(t, expectedTime, modTime, test.Golden)
}
}
checkGolden(t, test.Golden, body)
}
}