aboutsummaryrefslogtreecommitdiff
path: root/lib/http
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2025-01-22 20:49:40 +0700
committerShulhan <ms@kilabit.info>2025-01-22 21:34:16 +0700
commit18d3a3aad4b6ad3358159d48cd158c2cb2c71e5a (patch)
tree85d4d09371e4077091ba94988e3f8c5d799dc155 /lib/http
parentb9cff7d8f66d679218d1eaf4b015febbc48abc9e (diff)
downloadpakakeh.go-18d3a3aad4b6ad3358159d48cd158c2cb2c71e5a.tar.xz
lib/http: always refresh a directory on GET request
On server with TryDirect is true, any GET request to a directory should always rescan the content and the generate the new index.html. While at it, return the generated time in UTC instead of local time.
Diffstat (limited to 'lib/http')
-rw-r--r--lib/http/server.go2
-rw-r--r--lib/http/server_test.go77
-rw-r--r--lib/http/testdata/Server_HandleFS_test.txt33
3 files changed, 111 insertions, 1 deletions
diff --git a/lib/http/server.go b/lib/http/server.go
index a9761582..5801832f 100644
--- a/lib/http/server.go
+++ b/lib/http/server.go
@@ -499,7 +499,7 @@ func (srv *Server) HandleFS(res http.ResponseWriter, req *http.Request) {
responseETag = strconv.FormatInt(nodeModtime, 10)
requestETag = req.Header.Get(HeaderIfNoneMatch)
)
- if requestETag == responseETag {
+ if !node.IsDir() && requestETag == responseETag {
res.WriteHeader(http.StatusNotModified)
return
}
diff --git a/lib/http/server_test.go b/lib/http/server_test.go
index 8961bace..a3a82d9e 100644
--- a/lib/http/server_test.go
+++ b/lib/http/server_test.go
@@ -17,6 +17,7 @@ import (
"net/http/httputil"
"os"
"path/filepath"
+ "regexp"
"strings"
"testing"
"time"
@@ -860,6 +861,82 @@ func TestStatusError(t *testing.T) {
}
}
+func TestServer_HandleFS(t *testing.T) {
+ var tdata *test.Data
+ var err error
+ tdata, err = test.LoadData(`testdata/Server_HandleFS_test.txt`)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var root = t.TempDir()
+ var mfsOpts = memfs.Options{
+ Root: root,
+ MaxFileSize: -1,
+ TryDirect: true,
+ }
+ var mfs *memfs.MemFS
+ mfs, err = memfs.New(&mfsOpts)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var serverOpts = ServerOptions{
+ Memfs: mfs,
+ Address: `127.0.0.1:15213`,
+ EnableIndexHTML: true,
+ }
+ var httpd *Server
+ httpd, err = NewServer(serverOpts)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var redactTime = regexp.MustCompile(`\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d`)
+ var redactedTime = []byte(`0000-00-00T00:00:00`)
+ var simreq = libhttptest.SimulateRequest{
+ Path: `/`,
+ }
+ var simres *libhttptest.SimulateResult
+ var exp string
+ var got []byte
+
+ t.Run(`OnEmptyRoot`, func(t *testing.T) {
+ simres, err = libhttptest.Simulate(httpd.ServeHTTP, &simreq)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ exp = string(tdata.Output[t.Name()])
+ got, err = simres.DumpResponse([]string{HeaderETag})
+ if err != nil {
+ t.Fatal(err)
+ }
+ test.Assert(t, `response`, exp, string(got))
+ })
+
+ t.Run(`OnNewDirectory`, func(t *testing.T) {
+ var newDir = filepath.Join(root, `dirA`)
+ err = os.MkdirAll(newDir, 0755)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ simres, err = libhttptest.Simulate(httpd.ServeHTTP, &simreq)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ exp = string(tdata.Output[t.Name()])
+ got, err = simres.DumpResponse([]string{HeaderETag})
+ if err != nil {
+ t.Fatal(err)
+ }
+ got = redactTime.ReplaceAll(got, redactedTime)
+ test.Assert(t, `response`, exp, string(got))
+ })
+}
+
// TestServer_Options_HandleFS test GET on memfs with authorization.
func TestServer_Options_HandleFS(t *testing.T) {
type testCase struct {
diff --git a/lib/http/testdata/Server_HandleFS_test.txt b/lib/http/testdata/Server_HandleFS_test.txt
new file mode 100644
index 00000000..23dd32c9
--- /dev/null
+++ b/lib/http/testdata/Server_HandleFS_test.txt
@@ -0,0 +1,33 @@
+
+<<< TestServer_HandleFS/OnEmptyRoot
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html; charset=utf-8
+
+<!DOCTYPE html><html>
+<head>
+<meta name="viewport" content="width=device-width">
+<style>
+body{font-family:monospace; white-space:pre;}
+</style>
+</head>
+<body>
+<h3>Index of /</h3>
+</body></html>
+
+<<< TestServer_HandleFS/OnNewDirectory
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html; charset=utf-8
+
+<!DOCTYPE html><html>
+<head>
+<meta name="viewport" content="width=device-width">
+<style>
+body{font-family:monospace; white-space:pre;}
+</style>
+</head>
+<body>
+<h3>Index of /</h3>
+<div>drwxr-xr-x <tt> 0</tt> 0000-00-00T00:00:00Z <a href="/dirA">dirA</a></div><br/>
+</body></html>