~xdavidwu/listables

57462b11d759a15fd430e1ed7ebc605e66f2fad6 — Pinghao Wu 20 days ago 896fe7f
deref symlink for file info
1 files changed, 37 insertions(+), 11 deletions(-)

M server.go
M server.go => server.go +37 -11
@@ 12,6 12,7 @@ import (
	"flag"
	"html/template"
	"io/fs"
	"log/slog"
	"mime"
	"net"
	"net/http"


@@ 169,16 170,14 @@ var (
		</thead>
		<tbody>
			<tr><td><a href="..">..</a></td></tr>
		{{range .Entries}}
		{{range $name, $e := .Entries}}
			<tr>
				<td><a href="{{.Name}}">{{.Name}}{{if .IsDir}}/{{end}}</a></td>
				{{with .Info}}
					<td>{{.ModTime | timefmt}}</td>
					{{if .IsDir}}
						<td data-numeric="0">- </td>
					{{else}}
						<td data-numeric="{{.Size}}">{{.Size | numfmt}}</td>
					{{end}}
				<td><a href="{{$name}}">{{$name}}{{if $e.IsDir}}/{{end}}</a></td>
				<td>{{$e.ModTime | timefmt}}</td>
				{{if $e.IsDir}}
					<td data-numeric="0">- </td>
				{{else}}
					<td data-numeric="{{$e.Size}}">{{$e.Size | numfmt}}</td>
				{{end}}
			</tr>
		{{end}}


@@ 194,7 193,7 @@ var (

type Data struct {
	Path    string
	Entries []fs.DirEntry
	Entries map[string]fs.FileInfo
	Footer  string
}



@@ 219,6 218,11 @@ func main() {
	if !ok {
		panic("fs impl not supporting fs.ReadDirFS")
	}
	sf, ok := f.(fs.StatFS)
	if !ok {
		panic("fs impl not supporting fs.StatFS")
	}

	staticHandler := http.FileServerFS(f)
	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		l := len(r.URL.Path)


@@ 239,7 243,29 @@ func main() {
				w.WriteHeader(404)
				return
			}
			tpl.Execute(w, Data{r.URL.Path, ds, *foot})

			entries := map[string]fs.FileInfo{}
			for _, d := range ds {
				dname := d.Name()
				fp := p + "/" + dname
				if d.Type()&fs.ModeSymlink == fs.ModeSymlink {
					e, err := sf.Stat(fp)
					if err != nil {
						slog.Warn("cannot stat symlink", "file", fp, "error", err)
					} else {
						entries[dname] = e
					}
				} else {
					e, err := d.Info()
					if err != nil {
						slog.Warn("cannot fs.DirEntry.Info()", "file", fp, "error", err)
					} else {
						entries[dname] = e
					}
				}
			}

			tpl.Execute(w, Data{r.URL.Path, entries, *foot})
		} else {
			staticHandler.ServeHTTP(w, r)
		}