diff --git a/entry/http/file.go b/entry/http/file.go new file mode 100644 index 0000000..34d0f24 --- /dev/null +++ b/entry/http/file.go @@ -0,0 +1,100 @@ +package http + +import ( + "io/fs" + "net/http" + "time" +) + +type ( + FS struct { + fs http.FileSystem + modtime time.Time + } + + File struct { + fp http.File + modtime time.Time + } + + FileInfo struct { + name string + size int64 + mode fs.FileMode + isDir bool + modtime time.Time + } +) + +func (fi *FileInfo) Name() string { + return fi.name +} + +func (fi *FileInfo) Size() int64 { + return fi.size +} + +func (fi *FileInfo) Mode() fs.FileMode { + return fi.mode +} + +func (fi *FileInfo) ModTime() time.Time { + return fi.modtime +} + +func (fi *FileInfo) IsDir() bool { + return fi.isDir +} + +func (fi *FileInfo) Sys() any { + return nil +} + +func (file *File) Close() error { + return file.fp.Close() +} + +func (file *File) Read(p []byte) (n int, err error) { + return file.fp.Read(p) +} + +func (file *File) Seek(offset int64, whence int) (int64, error) { + return file.fp.Seek(offset, whence) +} + +func (file *File) Readdir(count int) ([]fs.FileInfo, error) { + return file.fp.Readdir(count) +} + +func (file *File) Stat() (fs.FileInfo, error) { + fi, err := file.fp.Stat() + if err != nil { + return nil, err + } + return newFileInfo(fi, file.modtime), nil +} + +func (fs *FS) Open(name string) (http.File, error) { + fp, err := fs.fs.Open(name) + if err != nil { + return nil, err + } + return &File{fp: fp, modtime: fs.modtime}, nil +} + +func newFS(modtime time.Time, fs http.FileSystem) *FS { + return &FS{ + fs: fs, + modtime: modtime, + } +} + +func newFileInfo(fi fs.FileInfo, modtime time.Time) *FileInfo { + return &FileInfo{ + name: fi.Name(), + size: fi.Size(), + mode: fi.Mode(), + isDir: fi.IsDir(), + modtime: modtime, + } +} diff --git a/entry/http/server.go b/entry/http/server.go index 3df9e24..6568de1 100644 --- a/entry/http/server.go +++ b/entry/http/server.go @@ -9,6 +9,7 @@ import ( "path" "strings" "sync" + "time" ) var ( @@ -20,6 +21,7 @@ type Server struct { serve *http.Server router *router.Router middleware []Middleware + uptime time.Time anyRequests map[string]http.Handler } @@ -115,7 +117,7 @@ func (svr *Server) Embed(prefix string, root string, embedFs embed.FS) { filename = "/" + filename } ctx.Request().URL.Path = filename - http.FileServer(httpFs).ServeHTTP(ctx.Response(), ctx.Request()) + http.FileServer(newFS(svr.uptime, httpFs)).ServeHTTP(ctx.Response(), ctx.Request()) return }) } @@ -190,6 +192,7 @@ func (svr *Server) Shutdown() (err error) { func New(ctx context.Context) *Server { svr := &Server{ ctx: ctx, + uptime: time.Now(), router: router.New(), anyRequests: make(map[string]http.Handler), middleware: make([]Middleware, 0, 10),