Skip to content

Commit 22563a7

Browse files
authored
file_server: use the UTC timezone for modified time (#6830)
* use UTC timezone for modified time * use http.ParseTime to handle If-Modified-Since * use time.Compare to simplify comparison * take the directory's modtime into consideration when calculating lastModified * update comments about If-Modified-Since's handling
1 parent 9b74a53 commit 22563a7

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

modules/caddyhttp/fileserver/browse.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,9 @@ func (fsrv *FileServer) serveBrowse(fileSystem fs.FS, root, dirPath string, w ht
130130

131131
// speed up browser/client experience and caching by supporting If-Modified-Since
132132
if ifModSinceStr := r.Header.Get("If-Modified-Since"); ifModSinceStr != "" {
133-
ifModSince, err := time.ParseInLocation(http.TimeFormat, ifModSinceStr, time.Local)
134-
lastModTrunc := listing.lastModified.Truncate(time.Second)
135-
if err == nil && (lastModTrunc.Equal(ifModSince) || lastModTrunc.Before(ifModSince)) {
133+
// basically a copy of stdlib file server's handling of If-Modified-Since
134+
ifModSince, err := http.ParseTime(ifModSinceStr)
135+
if err == nil && listing.lastModified.Truncate(time.Second).Compare(ifModSince) <= 0 {
136136
w.WriteHeader(http.StatusNotModified)
137137
return nil
138138
}
@@ -213,6 +213,11 @@ func (fsrv *FileServer) serveBrowse(fileSystem fs.FS, root, dirPath string, w ht
213213
}
214214

215215
func (fsrv *FileServer) loadDirectoryContents(ctx context.Context, fileSystem fs.FS, dir fs.ReadDirFile, root, urlPath string, repl *caddy.Replacer) (*browseTemplateContext, error) {
216+
// modTime for the directory itself
217+
stat, err := dir.Stat()
218+
if err != nil {
219+
return nil, err
220+
}
216221
dirLimit := defaultDirEntryLimit
217222
if fsrv.Browse.FileLimit != 0 {
218223
dirLimit = fsrv.Browse.FileLimit
@@ -225,7 +230,7 @@ func (fsrv *FileServer) loadDirectoryContents(ctx context.Context, fileSystem fs
225230
// user can presumably browse "up" to parent folder if path is longer than "/"
226231
canGoUp := len(urlPath) > 1
227232

228-
return fsrv.directoryListing(ctx, fileSystem, files, canGoUp, root, urlPath, repl), nil
233+
return fsrv.directoryListing(ctx, fileSystem, stat.ModTime(), files, canGoUp, root, urlPath, repl), nil
229234
}
230235

231236
// browseApplyQueryParams applies query parameters to the listing.

modules/caddyhttp/fileserver/browsetplcontext.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,16 @@ import (
3535
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
3636
)
3737

38-
func (fsrv *FileServer) directoryListing(ctx context.Context, fileSystem fs.FS, entries []fs.DirEntry, canGoUp bool, root, urlPath string, repl *caddy.Replacer) *browseTemplateContext {
38+
func (fsrv *FileServer) directoryListing(ctx context.Context, fileSystem fs.FS, parentModTime time.Time, entries []fs.DirEntry, canGoUp bool, root, urlPath string, repl *caddy.Replacer) *browseTemplateContext {
3939
filesToHide := fsrv.transformHidePaths(repl)
4040

4141
name, _ := url.PathUnescape(urlPath)
4242

4343
tplCtx := &browseTemplateContext{
44-
Name: path.Base(name),
45-
Path: urlPath,
46-
CanGoUp: canGoUp,
44+
Name: path.Base(name),
45+
Path: urlPath,
46+
CanGoUp: canGoUp,
47+
lastModified: parentModTime,
4748
}
4849

4950
for _, entry := range entries {
@@ -131,6 +132,10 @@ func (fsrv *FileServer) directoryListing(ctx context.Context, fileSystem fs.FS,
131132
})
132133
}
133134

135+
// this time is used for the Last-Modified header and comparing If-Modified-Since from client
136+
// both are expected to be in UTC, so we convert to UTC here
137+
// see: https://github.com/caddyserver/caddy/issues/6828
138+
tplCtx.lastModified = tplCtx.lastModified.UTC()
134139
return tplCtx
135140
}
136141

0 commit comments

Comments
 (0)