From d1625891767e8b7ca7d7b2e79862e2d1f896eed8 Mon Sep 17 00:00:00 2001 From: Shulhan Date: Wed, 20 Sep 2023 01:07:59 +0700 Subject: [PATCH] wip --- NOTES | 57 ++++++++++++++++ TODO | 7 ++ _doc/RFC_2183__CONTENT-DISPOSITION.adoc | 44 ++++++++++++ _doc/lib/websocket/AUTOBAHN.adoc | 1 + cmd/hexo/main.go | 90 +++++++++++++++++++++++++ lib/http/internal/cmd/httpd/main.go | 31 +++++++++ lib/http/internal/internal.go | 64 ++++++++++++++++++ 7 files changed, 294 insertions(+) create mode 100644 NOTES create mode 100644 TODO create mode 100644 _doc/RFC_2183__CONTENT-DISPOSITION.adoc create mode 120000 _doc/lib/websocket/AUTOBAHN.adoc create mode 100644 cmd/hexo/main.go create mode 100644 lib/http/internal/cmd/httpd/main.go create mode 100644 lib/http/internal/internal.go diff --git a/NOTES b/NOTES new file mode 100644 index 00000000..02f3b9df --- /dev/null +++ b/NOTES @@ -0,0 +1,57 @@ +2023/07/03 16:17:45 MemFS.Update /tmp/TestDirWatcher_renameDirectory593980368/001/subdir/testfile: Node.Update /tmp/TestDirWatcher_renameDirectory593980368/001/subdir/testfile: stat /tmp/TestDirWatcher_renameDirectory593980368/001/subdir/testfile: no such file or directory +================== +WARNING: DATA RACE +Read at 0x00c00022d7d0 by goroutine 7: + runtime.mapiterinit() + /opt/hostedtoolcache/go/1.20.5/x64/src/runtime/map.go:815 +0x0 + github.com/shuLhan/share/lib/memfs.(*DirWatcher).dirsKeys() + /home/runner/work/share/share/lib/memfs/dirwatcher.go:122 +0x766 + github.com/shuLhan/share/lib/memfs.TestDirWatcher_renameDirectory() + /home/runner/work/share/share/lib/memfs/dirwatcher_test.go:81 +0x8f4 + testing.tRunner() + /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:1576 +0x216 + testing.(*T).Run.func1() + /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:1629 +0x47 + +Previous write at 0x00c00022d7d0 by goroutine 9: + runtime.mapassign_faststr() + /opt/hostedtoolcache/go/1.20.5/x64/src/runtime/map_faststr.go:203 +0x0 + github.com/shuLhan/share/lib/memfs.(*DirWatcher).onContentChange() + /home/runner/work/share/share/lib/memfs/dirwatcher.go:246 +0x90b + github.com/shuLhan/share/lib/memfs.(*DirWatcher).start() + /home/runner/work/share/share/lib/memfs/dirwatcher.go:377 +0xdba + github.com/shuLhan/share/lib/memfs.(*DirWatcher).Start.func1() + /home/runner/work/share/share/lib/memfs/dirwatcher.go:107 +0x39 + +Goroutine 7 (running) created at: + testing.(*T).Run() + /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:1629 +0x805 + testing.runTests.func1() + /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:2036 +0x8d + testing.tRunner() + /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:1576 +0x216 + testing.runTests() + /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:2034 +0x87c + testing.(*M).Run() + /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:1906 +0xb44 + github.com/shuLhan/share/lib/memfs.TestMain() + /home/runner/work/share/share/lib/memfs/memfs_test.go:85 +0x644 + main.main() + _testmain.go:120 +0x33d + +Goroutine 9 (running) created at: + github.com/shuLhan/share/lib/memfs.(*DirWatcher).Start() + /home/runner/work/share/share/lib/memfs/dirwatcher.go:107 +0x1dd + github.com/shuLhan/share/lib/memfs.TestDirWatcher_renameDirectory() + /home/runner/work/share/share/lib/memfs/dirwatcher_test.go:57 +0x3fd + testing.tRunner() + /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:1576 +0x216 + testing.(*T).Run.func1() + /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:1629 +0x47 +================== +--- FAIL: TestDirWatcher_renameDirectory (0.62s) + testing.go:1446: race detected during execution of test +2023/07/03 16:17:46 DirWatcher: on file changes /new.adoc: file does not exist +2023/07/03 16:17:46 DirWatcher: on file changes /subdir/new.adoc: file does not exist +2023/07/03 16:17:47 DirWatcher: on file changes /file: file does not exist +FAIL diff --git a/TODO b/TODO new file mode 100644 index 00000000..e483f416 --- /dev/null +++ b/TODO @@ -0,0 +1,7 @@ += TODO + +[ ] lib/ini: allow unmarshal value into []byte +[ ] lib/ini: remove ';' as comment. +[x] lib/ascii/ascii_example_test.go:115:2: SA1019: rand.Seed has been deprecated +[x] lib/numbers/int.go:36:2: SA1019: rand.Seed has been deprecated +[x] lib/mining/knn/neighbor_test.go:58:2: SA1019: rand.Seed has been deprecated diff --git a/_doc/RFC_2183__CONTENT-DISPOSITION.adoc b/_doc/RFC_2183__CONTENT-DISPOSITION.adoc new file mode 100644 index 00000000..8c6c13d1 --- /dev/null +++ b/_doc/RFC_2183__CONTENT-DISPOSITION.adoc @@ -0,0 +1,44 @@ += The Content-Disposition Header Field +:toc: +:sectlinks: +:sectnums: +:url-rfc2183: https://tools.ietf.org/html/rfc2183 + +This document provide note and summary of +{url-rfc2183}[RFC 2183^], Communicating Presentation Information in Internet +Messages: The Content-Disposition Header Field. + + +== Syntax + +---- +disposition := "Content-Disposition" ":" + disposition-type + *(";" disposition-parm) + +disposition-type := "inline" + / "attachment" + / extension-token + ; values are not case-sensitive + +disposition-parm := filename-parm + / creation-date-parm + / modification-date-parm + / read-date-parm + / size-parm + / parameter + +filename-parm := "filename" "=" value + +creation-date-parm := "creation-date" "=" quoted-date-time + +modification-date-parm := "modification-date" "=" quoted-date-time + +read-date-parm := "read-date" "=" quoted-date-time + +size-parm := "size" "=" 1*DIGIT + +quoted-date-time := quoted-string + ; contents MUST be an RFC 822 `date-time' + ; numeric timezones (+HHMM or -HHMM) MUST be used +---- diff --git a/_doc/lib/websocket/AUTOBAHN.adoc b/_doc/lib/websocket/AUTOBAHN.adoc new file mode 120000 index 00000000..740de7d0 --- /dev/null +++ b/_doc/lib/websocket/AUTOBAHN.adoc @@ -0,0 +1 @@ +../../../lib/websocket/AUTOBAHN.adoc \ No newline at end of file diff --git a/cmd/hexo/main.go b/cmd/hexo/main.go new file mode 100644 index 00000000..09587adb --- /dev/null +++ b/cmd/hexo/main.go @@ -0,0 +1,90 @@ +// Program hexcho print the input hex as hex itself, int64, octal, bytes, +// string, and binary. +package main + +import ( + "flag" + "fmt" + "log" + "os" + "strconv" + + libbytes "github.com/shuLhan/share/lib/bytes" +) + +func main() { + var ( + optFile bool + ) + + flag.BoolVar(&optFile, `file`, false, `make each arguments as files`) + flag.Parse() + + var ( + arg string + hex int64 + err error + b byte + ) + + if optFile { + dumpFiles() + return + } + + for _, arg = range flag.Args() { + fmt.Printf("[0x%s]\n", arg) + + hex, err = strconv.ParseInt(arg, 16, 64) + if err != nil { + log.Println(err) + continue + } + + var bytes = make([]byte, 0, 8) + for x := 56; x >= 0; x -= 8 { + bytes = append(bytes, byte(hex>>x)) + } + + fmt.Printf(" int64: %d\n", hex) + + fmt.Printf(" hex:") + for _, b = range bytes { + fmt.Printf(" %8x", b) + } + fmt.Println() + + fmt.Printf(" bytes:") + for _, b = range bytes { + fmt.Printf(" %8d", b) + } + fmt.Println() + + fmt.Printf(" char:") + for _, b = range bytes { + fmt.Printf(" %8c", b) + } + fmt.Println() + fmt.Printf(" binary:") + for _, b = range bytes { + fmt.Printf(" %08b", b) + } + fmt.Println() + } +} + +func dumpFiles() { + var ( + arg string + content []byte + err error + ) + for _, arg = range flag.Args() { + content, err = os.ReadFile(arg) + if err != nil { + log.Fatalf(`hexo: file %s: %s`, arg, err) + } + + libbytes.DumpPrettyTable(os.Stdout, arg, content) + } +} diff --git a/lib/http/internal/cmd/httpd/main.go b/lib/http/internal/cmd/httpd/main.go new file mode 100644 index 00000000..d3b486d0 --- /dev/null +++ b/lib/http/internal/cmd/httpd/main.go @@ -0,0 +1,31 @@ +// Program httpd run HTTP server that serve files in directory testdata for +// testing with external tools. +// This program should be run from directory lib/http. +package main + +import ( + "fmt" + "log" + + libhttp "github.com/shuLhan/share/lib/http" + "github.com/shuLhan/share/lib/http/internal" +) + +func main() { + var ( + srv *libhttp.Server + err error + ) + + srv, err = internal.NewTestServer() + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Starting test server at http://%s\n", srv.Options.Address) + + err = srv.Start() + if err != nil { + log.Println(err) + } +} diff --git a/lib/http/internal/internal.go b/lib/http/internal/internal.go new file mode 100644 index 00000000..b7916fb2 --- /dev/null +++ b/lib/http/internal/internal.go @@ -0,0 +1,64 @@ +// Package internal contains helpers for testing http. +package internal + +import ( + "fmt" + "net/http" + "strings" + + libhttp "github.com/shuLhan/share/lib/http" + "github.com/shuLhan/share/lib/memfs" +) + +// NewTestServer create new HTTP server for testing. +func NewTestServer() (srv *libhttp.Server, err error) { + var ( + logp = `NewTestServer` + opts = &libhttp.ServerOptions{ + Memfs: &memfs.MemFS{ + Opts: &memfs.Options{ + Root: `./testdata`, + MaxFileSize: 30, + TryDirect: true, + }, + }, + HandleFS: handleFS, + Address: `127.0.0.1:14832`, + } + ) + + srv, err = libhttp.NewServer(opts) + if err != nil { + return nil, fmt.Errorf(`%s: %w`, logp, err) + } + + return srv, nil +} + +// handleFS authenticate the request to Memfs using cookie. +// +// If the node does not start with "/auth/" it will return true. +// +// If the node path is start with "/auth/" and cookie name "sid" exist +// with value "authz" it will return true; +// otherwise it will redirect to "/" and return false. +func handleFS(node *memfs.Node, res http.ResponseWriter, req *http.Request) bool { + var ( + lowerPath = strings.ToLower(node.Path) + + cookieSid *http.Cookie + err error + ) + if strings.HasPrefix(lowerPath, "/auth/") { + cookieSid, err = req.Cookie("sid") + if err != nil { + http.Redirect(res, req, "/", http.StatusSeeOther) + return false + } + if cookieSid.Value != "authz" { + http.Redirect(res, req, "/", http.StatusSeeOther) + return false + } + } + return true +}