mirror of
https://github.com/pldubouilh/gossa
synced 2025-12-06 08:22:32 +01:00
refactor
This commit is contained in:
parent
cb4631c086
commit
5b55ab0a0a
3 changed files with 29 additions and 26 deletions
2
Makefile
2
Makefile
|
|
@ -26,10 +26,12 @@ test:
|
||||||
go test -run TestNormal
|
go test -run TestNormal
|
||||||
|
|
||||||
killall gossa
|
killall gossa
|
||||||
|
sleep 1
|
||||||
-make run-extra &
|
-make run-extra &
|
||||||
go test -run TestExtra
|
go test -run TestExtra
|
||||||
|
|
||||||
killall gossa
|
killall gossa
|
||||||
|
sleep 1
|
||||||
-make run-ro &
|
-make run-ro &
|
||||||
go test -run TestRo
|
go test -run TestRo
|
||||||
|
|
||||||
|
|
|
||||||
32
gossa.go
32
gossa.go
|
|
@ -31,7 +31,7 @@ var symlinks = flag.Bool("symlinks", false, "follow symlinks \033[4mWARNING\033[
|
||||||
var verb = flag.Bool("verb", false, "verbosity")
|
var verb = flag.Bool("verb", false, "verbosity")
|
||||||
var skipHidden = flag.Bool("k", true, "\nskip hidden files")
|
var skipHidden = flag.Bool("k", true, "\nskip hidden files")
|
||||||
var ro = flag.Bool("ro", false, "read only mode (no upload, rename, move, etc...)")
|
var ro = flag.Bool("ro", false, "read only mode (no upload, rename, move, etc...)")
|
||||||
var initPath = "."
|
var rootPath = ""
|
||||||
|
|
||||||
var handler http.Handler
|
var handler http.Handler
|
||||||
|
|
||||||
|
|
@ -196,10 +196,7 @@ func zipRPC(w http.ResponseWriter, r *http.Request) {
|
||||||
defer exitPath(w, "zip", zipPath)
|
defer exitPath(w, "zip", zipPath)
|
||||||
zipFullPath := enforcePath(zipPath)
|
zipFullPath := enforcePath(zipPath)
|
||||||
_, err := os.Lstat(zipFullPath)
|
_, err := os.Lstat(zipFullPath)
|
||||||
if err != nil {
|
check(err)
|
||||||
panic("zip path doesnt exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Add("Content-Disposition", "attachment; filename=\""+zipName+".zip\"")
|
w.Header().Add("Content-Disposition", "attachment; filename=\""+zipName+".zip\"")
|
||||||
zipWriter := zip.NewWriter(w)
|
zipWriter := zip.NewWriter(w)
|
||||||
defer zipWriter.Close()
|
defer zipWriter.Close()
|
||||||
|
|
@ -212,11 +209,9 @@ func zipRPC(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
rel, err := filepath.Rel(zipFullPath, path)
|
rel, err := filepath.Rel(zipFullPath, path)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
if *skipHidden && strings.HasPrefix(rel, ".") {
|
if *skipHidden && strings.HasPrefix(rel, ".") {
|
||||||
return nil // hidden files not allowed
|
return nil // hidden files not allowed
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Mode()&os.ModeSymlink != 0 {
|
if f.Mode()&os.ModeSymlink != 0 {
|
||||||
panic(errors.New("symlink not allowed in zip downloads")) // filepath.Walk doesnt support symlinks
|
panic(errors.New("symlink not allowed in zip downloads")) // filepath.Walk doesnt support symlinks
|
||||||
}
|
}
|
||||||
|
|
@ -259,7 +254,7 @@ func rpc(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func enforcePath(p string) string {
|
func enforcePath(p string) string {
|
||||||
joined := filepath.Join(initPath, strings.TrimPrefix(p, *extraPath))
|
joined := filepath.Join(rootPath, strings.TrimPrefix(p, *extraPath))
|
||||||
fp, err := filepath.Abs(joined)
|
fp, err := filepath.Abs(joined)
|
||||||
sl, _ := filepath.EvalSymlinks(fp) // err skipped as it would error for unexistent files (RPC check). The actual behaviour is tested below
|
sl, _ := filepath.EvalSymlinks(fp) // err skipped as it would error for unexistent files (RPC check). The actual behaviour is tested below
|
||||||
|
|
||||||
|
|
@ -267,7 +262,7 @@ func enforcePath(p string) string {
|
||||||
// ... or if path doesnt contain the prefix path we expect,
|
// ... or if path doesnt contain the prefix path we expect,
|
||||||
// ... or if we're skipping hidden folders, and one is requested,
|
// ... or if we're skipping hidden folders, and one is requested,
|
||||||
// ... or if we're skipping symlinks, path exists, and a symlink out of bound requested
|
// ... or if we're skipping symlinks, path exists, and a symlink out of bound requested
|
||||||
if err != nil || !strings.HasPrefix(fp, initPath) || *skipHidden && strings.Contains(p, "/.") || !*symlinks && len(sl) > 0 && !strings.HasPrefix(sl, initPath) {
|
if err != nil || !strings.HasPrefix(fp, rootPath) || *skipHidden && strings.Contains(p, "/.") || !*symlinks && len(sl) > 0 && !strings.HasPrefix(sl, rootPath) {
|
||||||
panic(errors.New("invalid path"))
|
panic(errors.New("invalid path"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -275,18 +270,16 @@ func enforcePath(p string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var err error
|
if flag.Parse(); len(flag.Args()) > 0 {
|
||||||
flag.Usage = func() {
|
rootPath = flag.Args()[0]
|
||||||
|
} else {
|
||||||
fmt.Printf("\nusage: ./gossa ~/directory-to-share\n\n")
|
fmt.Printf("\nusage: ./gossa ~/directory-to-share\n\n")
|
||||||
flag.PrintDefaults()
|
flag.PrintDefaults()
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
flag.Parse()
|
var err error
|
||||||
if len(flag.Args()) > 0 {
|
rootPath, err = filepath.Abs(rootPath)
|
||||||
initPath = flag.Args()[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
initPath, err = filepath.Abs(initPath)
|
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
templateStr = strings.Replace(templateStr, "css_will_be_here", styleCss, 1)
|
templateStr = strings.Replace(templateStr, "css_will_be_here", styleCss, 1)
|
||||||
|
|
@ -299,11 +292,10 @@ func main() {
|
||||||
http.HandleFunc(*extraPath+"rpc", rpc)
|
http.HandleFunc(*extraPath+"rpc", rpc)
|
||||||
http.HandleFunc(*extraPath+"post", upload)
|
http.HandleFunc(*extraPath+"post", upload)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.HandleFunc(*extraPath+"zip", zipRPC)
|
http.HandleFunc(*extraPath+"zip", zipRPC)
|
||||||
http.HandleFunc("/", doContent)
|
http.HandleFunc("/", doContent)
|
||||||
handler = http.StripPrefix(*extraPath, http.FileServer(http.Dir(initPath)))
|
handler = http.StripPrefix(*extraPath, http.FileServer(http.Dir(rootPath)))
|
||||||
fmt.Printf("Gossa starting on directory %s\nListening on http://%s:%s%s\n", initPath, *host, *port, *extraPath)
|
fmt.Printf("Gossa starting on directory %s\nListening on http://%s:%s%s\n", rootPath, *host, *port, *extraPath)
|
||||||
err = http.ListenAndServe(*host+":"+*port, nil)
|
err = http.ListenAndServe(*host+":"+*port, nil)
|
||||||
check(err)
|
check(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,7 @@ func doTestRegular(t *testing.T, url string, testExtra bool) {
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
fmt.Println("\r\n~~~~~~~~~~ test zip invalid path")
|
fmt.Println("\r\n~~~~~~~~~~ test zip invalid path")
|
||||||
body0 = get(t, url+"zip?zipPath=%2Ftmp&zipName=subdir")
|
body0 = get(t, url+"zip?zipPath=%2Ftmp&zipName=subdir")
|
||||||
|
println(body0)
|
||||||
if body0 != `error` {
|
if body0 != `error` {
|
||||||
t.Fatal("zip passed for invalid path")
|
t.Fatal("zip passed for invalid path")
|
||||||
}
|
}
|
||||||
|
|
@ -200,12 +201,20 @@ func doTestRegular(t *testing.T, url string, testExtra bool) {
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
fmt.Println("\r\n~~~~~~~~~~ test symlink, should succeed: ", testExtra)
|
fmt.Println("\r\n~~~~~~~~~~ test symlink, should succeed: ", testExtra)
|
||||||
body0 = get(t, url+"/support/readme.md")
|
body0 = get(t, url+"/support/")
|
||||||
hasReadme := strings.Contains(body0, `the master branch is automatically built and pushed`)
|
hasListing := strings.Contains(body0, `readme.md`)
|
||||||
|
body1 = get(t, url+"/support/readme.md")
|
||||||
|
hasReadme := strings.Contains(body1, `the master branch is automatically built and pushed`)
|
||||||
|
|
||||||
if !testExtra && hasReadme {
|
if !testExtra && hasReadme {
|
||||||
t.Fatal("error symlink reached where illegal")
|
t.Fatal("error symlink file reached where illegal")
|
||||||
} else if testExtra && !hasReadme {
|
} else if testExtra && !hasReadme {
|
||||||
t.Fatal("error symlink unreachable")
|
t.Fatal("error symlink file unreachable")
|
||||||
|
}
|
||||||
|
if !testExtra && hasListing {
|
||||||
|
t.Fatal("error symlink folder reached where illegal")
|
||||||
|
} else if testExtra && !hasListing {
|
||||||
|
t.Fatal("error symlink folder unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
if testExtra {
|
if testExtra {
|
||||||
|
|
@ -298,7 +307,7 @@ func doTestReadonly(t *testing.T, url string) {
|
||||||
path = "%2F%E1%84%92%E1%85%A1%20%E1%84%92%E1%85%A1" // "하 하" encoded
|
path = "%2F%E1%84%92%E1%85%A1%20%E1%84%92%E1%85%A1" // "하 하" encoded
|
||||||
payload = "123 하"
|
payload = "123 하"
|
||||||
body0 = postDummyFile(t, url, path, payload)
|
body0 = postDummyFile(t, url, path, payload)
|
||||||
body1 = get(t, url+path)
|
get(t, url+path)
|
||||||
if body0 == `ok` {
|
if body0 == `ok` {
|
||||||
t.Fatal("post file passed - should not be allowed")
|
t.Fatal("post file passed - should not be allowed")
|
||||||
}
|
}
|
||||||
|
|
@ -306,7 +315,7 @@ func doTestReadonly(t *testing.T, url string) {
|
||||||
// ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~
|
||||||
fmt.Println("\r\n~~~~~~~~~~ test mv rpc")
|
fmt.Println("\r\n~~~~~~~~~~ test mv rpc")
|
||||||
body0 = postJSON(t, url+"rpc", `{"call":"mv","args":["/AAA", "/hols/AAA"]}`)
|
body0 = postJSON(t, url+"rpc", `{"call":"mv","args":["/AAA", "/hols/AAA"]}`)
|
||||||
body1 = fetchAndTestDefault(t, url)
|
fetchAndTestDefault(t, url)
|
||||||
if body0 == `ok` {
|
if body0 == `ok` {
|
||||||
t.Fatal("mv rpc passed - should not be allowed")
|
t.Fatal("mv rpc passed - should not be allowed")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue