chore: bootstrap CHFS NG workspace
This commit is contained in:
Submodule
+1
Submodule PlexPt added at 21afcc3034
@@ -0,0 +1,14 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"chfs-ng/internal/api"
|
||||||
|
"chfs-ng/internal/storage"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
s := &api.Server{Store: storage.Local{Root: "/data"}}
|
||||||
|
log.Println("chfs-ng development server listening on :80")
|
||||||
|
log.Fatal(http.ListenAndServe(":80", s.Handler()))
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
module chfs-ng
|
||||||
|
|
||||||
|
go 1.22
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"chfs-ng/internal/storage"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Server struct{ Store storage.Storage }
|
||||||
|
|
||||||
|
func (s *Server) Handler() http.Handler {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("/chfs/files", s.files)
|
||||||
|
mux.HandleFunc("/chfs/newdir", s.newdir)
|
||||||
|
mux.HandleFunc("/chfs/rename", s.rename)
|
||||||
|
mux.HandleFunc("/chfs/rmfiles", s.remove)
|
||||||
|
mux.HandleFunc("/chfs/exist", s.exist)
|
||||||
|
mux.HandleFunc("/chfs/session", s.session)
|
||||||
|
return mux
|
||||||
|
}
|
||||||
|
func notImpl(w http.ResponseWriter) { http.Error(w, "not implemented", http.StatusNotImplemented) }
|
||||||
|
func (s *Server) files(w http.ResponseWriter, r *http.Request) { notImpl(w) }
|
||||||
|
func (s *Server) newdir(w http.ResponseWriter, r *http.Request) { notImpl(w) }
|
||||||
|
func (s *Server) rename(w http.ResponseWriter, r *http.Request) { notImpl(w) }
|
||||||
|
func (s *Server) remove(w http.ResponseWriter, r *http.Request) { notImpl(w) }
|
||||||
|
func (s *Server) exist(w http.ResponseWriter, r *http.Request) { notImpl(w) }
|
||||||
|
func (s *Server) session(w http.ResponseWriter, r *http.Request) { notImpl(w) }
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
type PermMask uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
None PermMask = 0
|
||||||
|
Read PermMask = 1 << iota
|
||||||
|
Write
|
||||||
|
Delete
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p PermMask) HasRead() bool { return p&Read != 0 }
|
||||||
|
func (p PermMask) HasWrite() bool { return p&Write != 0 }
|
||||||
|
func (p PermMask) HasDelete() bool { return p&Delete != 0 }
|
||||||
|
|
||||||
|
type Account struct {
|
||||||
|
Username, Password string
|
||||||
|
Mask PermMask
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Storage interface {
|
||||||
|
Stat(path string) (os.FileInfo, error)
|
||||||
|
Open(path string) (*os.File, error)
|
||||||
|
Create(path string) (*os.File, error)
|
||||||
|
Remove(path string) error
|
||||||
|
Rename(oldPath, newPath string) error
|
||||||
|
MkdirAll(path string) error
|
||||||
|
List(path string) ([]os.FileInfo, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Local struct{ Root string }
|
||||||
|
|
||||||
|
func (s Local) real(path string) string { return filepath.Join(s.Root, filepath.Clean("/"+path)) }
|
||||||
|
func (s Local) Stat(path string) (os.FileInfo, error) { return os.Stat(s.real(path)) }
|
||||||
|
func (s Local) Open(path string) (*os.File, error) { return os.Open(s.real(path)) }
|
||||||
|
func (s Local) Create(path string) (*os.File, error) {
|
||||||
|
p := s.real(path)
|
||||||
|
if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return os.Create(p)
|
||||||
|
}
|
||||||
|
func (s Local) Remove(path string) error { return os.RemoveAll(s.real(path)) }
|
||||||
|
func (s Local) Rename(a, b string) error { return os.Rename(s.real(a), s.real(b)) }
|
||||||
|
func (s Local) MkdirAll(path string) error { return os.MkdirAll(s.real(path), 0755) }
|
||||||
|
func (s Local) List(path string) ([]os.FileInfo, error) {
|
||||||
|
f, err := os.Open(s.real(path))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
return f.Readdir(-1)
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# CHFS v1 compatibility surface
|
||||||
|
|
||||||
|
Keep legacy endpoints stable during migration.
|
||||||
|
|
||||||
|
- session: login/logout
|
||||||
|
- files: directory listing
|
||||||
|
- shared: direct file access
|
||||||
|
- newdir: create directory
|
||||||
|
- rename: rename file/directory
|
||||||
|
- rmfiles: delete
|
||||||
|
- search: global search
|
||||||
|
- upload/upload2: upload
|
||||||
|
- newtext/updatetext: text file editing
|
||||||
|
- preview: preview
|
||||||
|
- exist: existence check
|
||||||
|
- downloaddir: ZIP directory download
|
||||||
|
- webdav: WebDAV
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Known legacy configuration
|
||||||
|
|
||||||
|
path=/data
|
||||||
|
image.preview=true
|
||||||
|
file.remove=3
|
||||||
|
|
||||||
|
Known additional keys from binary/config ecosystem:
|
||||||
|
session.timeout
|
||||||
|
folder.download
|
||||||
|
folder.leaf.download
|
||||||
|
rule.default
|
||||||
|
rule.r
|
||||||
|
rule.w
|
||||||
|
rule.d
|
||||||
|
html.title
|
||||||
|
html.notice
|
||||||
|
ssl.cert
|
||||||
|
ssl.key
|
||||||
Submodule
+1
Submodule luguo added at 75ea2d59d6
Executable
BIN
Binary file not shown.
@@ -0,0 +1,3 @@
|
|||||||
|
path=/data
|
||||||
|
image.preview=true
|
||||||
|
file.remove=3
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# CHFS v4 reverse engineering notes
|
||||||
|
|
||||||
|
Base image: docblue/chfs:v4.0beta.min
|
||||||
|
Go: 1.18.1
|
||||||
|
Build revision: c430c39551e5e2e5c18aa57cdcc734814f795e4e
|
||||||
|
Build time: 2024-11-14T13:41:08Z
|
||||||
|
vcs.modified=true
|
||||||
|
|
||||||
|
Recovered modules:
|
||||||
|
- chfs/account: account, permission, token
|
||||||
|
- chfs/homedir
|
||||||
|
- chfs/mylog/ops
|
||||||
|
- chfs/util/pajfile
|
||||||
|
- main: HTTP handlers, configuration, MulPathMgr, WebDAV, ignore filtering
|
||||||
|
- webdav: embedded WebDAV implementation
|
||||||
|
|
||||||
|
Recovered HTTP endpoints include:
|
||||||
|
/chfs/session /chfs/files /chfs/newdir /chfs/rename /chfs/search /chfs/shared
|
||||||
|
/chfs/upload /chfs/upload2 /chfs/newtext /chfs/preview /chfs/rmfiles
|
||||||
|
/chfs/updatetext /chfs/exist /chfs/downloaddir/ /webdav
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
main
|
||||||
|
chfs/account
|
||||||
|
chfs/account.init.0
|
||||||
|
chfs/account.HasAccount
|
||||||
|
chfs/account.HasAccount.func1
|
||||||
|
chfs/account.AddAccount
|
||||||
|
chfs/account.ValidateAccount
|
||||||
|
chfs/account.ValidateAccount.func1
|
||||||
|
chfs/account.ValidatePermMask
|
||||||
|
chfs/account.PermMask.HasNonePermission
|
||||||
|
chfs/account.PermMask.HasReadPermission
|
||||||
|
chfs/account.PermMask.HasWritePermission
|
||||||
|
chfs/account.PermMask.HasDeletePermission
|
||||||
|
chfs/account.AccessMask
|
||||||
|
chfs/account.AccessMask.func1
|
||||||
|
chfs/account.CreateToken
|
||||||
|
chfs/account.GetAccFromToken.func1
|
||||||
|
chfs/account.GetAccFromToken
|
||||||
|
chfs/account.GetAccFromToken.func2
|
||||||
|
chfs/account.(*PermMask).HasDeletePermission
|
||||||
|
chfs/account.(*PermMask).HasNonePermission
|
||||||
|
chfs/account.(*PermMask).HasReadPermission
|
||||||
|
chfs/account.(*PermMask).HasWritePermission
|
||||||
|
chfs/homedir.Dir
|
||||||
|
chfs/homedir.dirUnix
|
||||||
|
chfs/icons.GetFileIcon
|
||||||
|
chfs/mylog/ops.InitOpsLog
|
||||||
|
chfs/mylog/ops.Output
|
||||||
|
chfs/mylog/ops.Output.func1
|
||||||
|
chfs/util/pajfile.IsFilePathExist
|
||||||
|
main.parseAllowAddresses
|
||||||
|
main.addIP
|
||||||
|
main.checkIPisAllow
|
||||||
|
main.login
|
||||||
|
main.getTokenFromCookies
|
||||||
|
main.logout
|
||||||
|
main.createZipImpl
|
||||||
|
main.createZipImpl.func1
|
||||||
|
main.(*GitIgnore).MatchesPath
|
||||||
|
main.downloadDir
|
||||||
|
main.listfile
|
||||||
|
main.listfile.func2
|
||||||
|
main.listfile.func1
|
||||||
|
main.deletefile
|
||||||
|
main.deletefile.func1
|
||||||
|
main.rename
|
||||||
|
main.createDir
|
||||||
|
main.newtext
|
||||||
|
main.updatetext
|
||||||
|
main.upload2
|
||||||
|
main.upload2.func4
|
||||||
|
main.upload2.func3
|
||||||
|
main.upload2.func2
|
||||||
|
main.upload2.func1
|
||||||
|
main.upload
|
||||||
|
main.upload.func4
|
||||||
|
main.upload.func3
|
||||||
|
main.upload.func2
|
||||||
|
main.upload.func1
|
||||||
|
main.isexist
|
||||||
|
main.responseError
|
||||||
|
main.previewHandler.func1
|
||||||
|
main.previewHandler
|
||||||
|
main.previewHandler.func2
|
||||||
|
main.search
|
||||||
|
main.search.func2
|
||||||
|
main.search.func1
|
||||||
|
main.parseConfigurationFile
|
||||||
|
main.report
|
||||||
|
main.report.func1
|
||||||
|
main.init.0
|
||||||
|
main.CompileIgnoreLines
|
||||||
|
main.getPatternFromLine
|
||||||
|
main.(*GitIgnore).matchesPathHow
|
||||||
|
main.main.func1
|
||||||
|
main.main
|
||||||
|
main.main.func3
|
||||||
|
main.main.func2
|
||||||
|
main.(*filterRouter).ServeHTTP
|
||||||
|
main.checkIPv4
|
||||||
|
main.compareVer
|
||||||
|
main.splitArray2Rows
|
||||||
|
main.myRender
|
||||||
|
main.myRender.func1
|
||||||
|
main.getLocalIPs
|
||||||
|
main.makeSites
|
||||||
|
main.getLatestVerFromServer
|
||||||
|
main.clientIP
|
||||||
|
main.whoami
|
||||||
|
main.parseCLI
|
||||||
|
main.initMulPathMgr
|
||||||
|
main.(*MulPathMgr).Find
|
||||||
|
main.(*MulPathMgr).extractFileName
|
||||||
|
main.(*MulPathMgr).realPath
|
||||||
|
main.(*MulPathMgr).matched
|
||||||
|
main.(*MulPathMgr).realPathForFile
|
||||||
|
main.(*MulPathMgr).peelRealRootPath
|
||||||
|
main.(*MulPathMgr).subRealRootPath
|
||||||
|
main.webdavHandler
|
||||||
|
main.init
|
||||||
Submodule
+1
Submodule vlianx added at abe33d893c
Reference in New Issue
Block a user