aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoni Sawicki <tenox@google.com>2022-05-25 02:27:00 -0700
committerAntoni Sawicki <tenox@google.com>2022-05-25 02:27:00 -0700
commit31a4d39d896040f691a42a0032cb6234edd6fe31 (patch)
treecc63ab939149aaa716618f4ee610c3fb05e4aae0
parent27ee2d582eb2551c2799f631819d3ceaecc696a2 (diff)
downloadwfm-31a4d39d896040f691a42a0032cb6234edd6fe31.tar.gz
remove full filepath standardise on dir+file
-rw-r--r--TODO.md3
-rw-r--r--dialogs.go23
-rw-r--r--dir.go12
-rw-r--r--fileio.go69
-rw-r--r--handlers.go33
5 files changed, 66 insertions, 74 deletions
diff --git a/TODO.md b/TODO.md
index 4b87936..d0f2b2e 100644
--- a/TODO.md
+++ b/TODO.md
@@ -29,9 +29,8 @@ https://github.com/crazcalm/go/commit/8b0b644cd02c59fe2461908304c44d64e8be431e
* html as template
## File IO
-* basename/clean paths in mulf, dst
-* remove uFp, there should be always uDir and uBn
* deniedPfx should be fired in handlers not in fileio???
+ this may be superseded by docker virtual path
* file search function
* path prefix, required for docker
* path prefix per user
diff --git a/dialogs.go b/dialogs.go
index 8b435f9..265c0f8 100644
--- a/dialogs.go
+++ b/dialogs.go
@@ -5,7 +5,6 @@ import (
"html"
"io/ioutil"
"os"
- "path/filepath"
"runtime"
"github.com/dustin/go-humanize"
@@ -41,14 +40,14 @@ func (r wfmRequest) prompt(action string, mul []string) {
<INPUT TYPE="TEXT" NAME="url" SIZE="40" VALUE="">
`))
case "rename":
- eBn := html.EscapeString(r.uBn)
+ eBn := html.EscapeString(r.uFbn)
r.w.Write([]byte(`
&nbsp;<BR>Enter new name for the file <B>` + eBn + `</B>:<P>
<INPUT TYPE="TEXT" NAME="dst" SIZE="40" VALUE="` + eBn + `">
<INPUT TYPE="HIDDEN" NAME="file" VALUE="` + eBn + `">
`))
case "move":
- eBn := html.EscapeString(r.uBn)
+ eBn := html.EscapeString(r.uFbn)
r.w.Write([]byte(`
&nbsp;<BR>Select destination folder for <B>` + eBn + `</B>:<P>
<SELECT NAME="dst">
@@ -57,13 +56,13 @@ func (r wfmRequest) prompt(action string, mul []string) {
`))
case "delete":
var a string
- fi, _ := os.Stat(r.uDir + "/" + r.uBn)
+ fi, _ := os.Stat(r.uDir + "/" + r.uFbn)
if fi.IsDir() {
a = "directory - recursively"
} else {
a = "file, size " + humanize.Bytes(uint64(fi.Size()))
}
- eBn := html.EscapeString(r.uBn)
+ eBn := html.EscapeString(r.uFbn)
r.w.Write([]byte(`
&nbsp;<BR>Are you sure you want to delete:<BR><B>` + eBn + `</B>
(` + a + `)<P>
@@ -81,7 +80,7 @@ func (r wfmRequest) prompt(action string, mul []string) {
fmt.Fprintf(r.w, "&nbsp;<BR>Move from: <B>%v</B><P>\n"+
"To: <SELECT NAME=\"dst\">%v</SELECT><P>\n<UL>Items:<P>\n",
html.EscapeString(r.uDir),
- upDnDir(r.uDir, r.uBn),
+ upDnDir(r.uDir, r.uFbn),
)
for _, f := range mul {
fE := html.EscapeString(f)
@@ -108,8 +107,7 @@ func (r wfmRequest) prompt(action string, mul []string) {
}
func (r wfmRequest) editText() {
- uFilePath := r.uFp // TODO(tenox): uDir + uBn
- fi, err := os.Stat(uFilePath)
+ fi, err := os.Stat(r.uDir + "/" + r.uFbn)
if err != nil {
htErr(r.w, "Unable to get file attributes", err)
return
@@ -118,16 +116,16 @@ func (r wfmRequest) editText() {
htErr(r.w, "edit", fmt.Errorf("the file is too large for editing"))
return
}
- f, err := ioutil.ReadFile(uFilePath)
+ f, err := ioutil.ReadFile(r.uDir + "/" + r.uFbn)
if err != nil {
htErr(r.w, "Unable to read file", err)
return
}
- header(r.w, filepath.Dir(uFilePath), r.eSort, `html, body, table, textarea, form { box-sizing: border-box; height:98%; }`)
+ header(r.w, r.uDir, r.eSort, `html, body, table, textarea, form { box-sizing: border-box; height:98%; }`)
r.w.Write([]byte(`
<TABLE BGCOLOR="#EEEEEE" BORDER="0" CELLSPACING="0" CELLPADDING="5" STYLE="width: 100%; height: 100%;">
<TR STYLE="height:1%;">
- <TD ALIGN="LEFT" VALIGN="MIDDLE" BGCOLOR="#CCCCCC">File Editor: ` + html.EscapeString(filepath.Base(uFilePath)) + `</TD>
+ <TD ALIGN="LEFT" VALIGN="MIDDLE" BGCOLOR="#CCCCCC">File Editor: ` + html.EscapeString(r.uFbn) + `</TD>
<TD BGCOLOR="#CCCCCC" ALIGN="RIGHT">&nbsp;</TD>
</TR>
<TR STYLE="height:99%;">
@@ -135,7 +133,8 @@ func (r wfmRequest) editText() {
<TEXTAREA NAME="text" SPELLCHECK="false" COLS="80" ROWS="24" STYLE="width: 99%; height: 99%;">` + html.EscapeString(string(f)) + `</TEXTAREA><P>
<INPUT TYPE="SUBMIT" NAME="save" VALUE="Save" STYLE="float: left;">
<INPUT TYPE="SUBMIT" NAME="cancel" VALUE="Cancel" STYLE="float: left; margin-left: 10px">
- <INPUT TYPE="HIDDEN" NAME="fp" VALUE="` + html.EscapeString(uFilePath) + `">
+ <INPUT TYPE="HIDDEN" NAME="dir" VALUE="` + html.EscapeString(r.uDir) + `">
+ <INPUT TYPE="HIDDEN" NAME="file" VALUE="` + html.EscapeString(r.uFbn) + `">
</TD></TR></TABLE>
`))
footer(r.w)
diff --git a/dir.go b/dir.go
index 7975590..bc5fd5c 100644
--- a/dir.go
+++ b/dir.go
@@ -29,7 +29,7 @@ func (r wfmRequest) listFiles(hi string) {
sortFiles(d, &sl, r.eSort)
header(r.w, r.uDir, r.eSort, "")
- toolbars(r.w, r.uDir, r.user, sl, i)
+ toolbars(r.w, r.uDir, r.userName, sl, i)
qeDir := url.QueryEscape(r.uDir)
z := 0
@@ -74,7 +74,7 @@ func (r wfmRequest) listFiles(hi string) {
<TD NOWRAP>&nbsp;</TD>
<TD NOWRAP ALIGN="right">(` + humanize.Time(f.ModTime()) + `) ` + f.ModTime().Format(time.Stamp) + `</TD>
<TD NOWRAP ALIGN="right">
- <A HREF="` + *wfmPfx + `?fn=renp&amp;dir=` + qeDir + `&amp;oldf=` + qeFile + `&amp;sort=` + r.eSort + `">` + i["re"] + `</A>&nbsp;
+ <A HREF="` + *wfmPfx + `?fn=renp&amp;dir=` + qeDir + `&amp;file=` + qeFile + `&amp;sort=` + r.eSort + `">` + i["re"] + `</A>&nbsp;
<A HREF="` + *wfmPfx + `?fn=movp&amp;dir=` + qeDir + `&amp;file=` + qeFile + `&amp;sort=` + r.eSort + `">` + i["mv"] + `</A>&nbsp;
<A HREF="` + *wfmPfx + `?fn=delp&amp;dir=` + qeDir + `&amp;file=` + qeFile + `&amp;sort=` + r.eSort + `">` + i["rm"] + `</A>&nbsp;
</TD>
@@ -116,14 +116,14 @@ func (r wfmRequest) listFiles(hi string) {
r.w.Write([]byte(`
<TD NOWRAP ALIGN="LEFT">
<INPUT TYPE="CHECKBOX" NAME="mulf" VALUE="` + heFile + `">
- <A HREF="` + *wfmPfx + `?fn=disp&amp;fp=` + qeDir + "/" + qeFile + `">` + fileIcon(qeFile, r.modern) + ` ` + heFile + `</A>` + li + `
+ <A HREF="` + *wfmPfx + `?fn=disp&amp;dir=` + qeDir + `&amp;file=` + qeFile + `">` + fileIcon(qeFile, r.modern) + ` ` + heFile + `</A>` + li + `
</TD>
<TD NOWRAP ALIGN="right">` + humanize.Bytes(uint64(f.Size())) + `</TD>
<TD NOWRAP ALIGN="right">(` + humanize.Time(f.ModTime()) + `) ` + f.ModTime().Format(time.Stamp) + `</TD>
<TD NOWRAP ALIGN="right">
- <A HREF="` + *wfmPfx + `?fn=down&amp;fp=` + qeDir + "/" + qeFile + `">` + i["dn"] + `</A>&nbsp;
- <A HREF="` + *wfmPfx + `?fn=edit&amp;fp=` + qeDir + "/" + qeFile + `&amp;sort=` + r.eSort + `">` + i["ed"] + `</A>&nbsp;
- <A HREF="` + *wfmPfx + `?fn=renp&amp;dir=` + qeDir + `&amp;oldf=` + qeFile + `&amp;sort=` + r.eSort + `">` + i["re"] + `</A>&nbsp;
+ <A HREF="` + *wfmPfx + `?fn=down&amp;dir=` + qeDir + `&amp;file=` + qeFile + `">` + i["dn"] + `</A>&nbsp;
+ <A HREF="` + *wfmPfx + `?fn=edit&amp;dir=` + qeDir + `&amp;file=` + qeFile + `&amp;sort=` + r.eSort + `">` + i["ed"] + `</A>&nbsp;
+ <A HREF="` + *wfmPfx + `?fn=renp&amp;dir=` + qeDir + `&amp;file=` + qeFile + `&amp;sort=` + r.eSort + `">` + i["re"] + `</A>&nbsp;
<A HREF="` + *wfmPfx + `?fn=movp&amp;dir=` + qeDir + `&amp;file=` + qeFile + `&amp;sort=` + r.eSort + `">` + i["mv"] + `</A>&nbsp;
<A HREF="` + *wfmPfx + `?fn=delp&amp;dir=` + qeDir + `&amp;file=` + qeFile + `&amp;sort=` + r.eSort + `">` + i["rm"] + `</A>&nbsp;
</TD>
diff --git a/fileio.go b/fileio.go
index 3e03a68..9b7aaf8 100644
--- a/fileio.go
+++ b/fileio.go
@@ -27,7 +27,7 @@ func deniedPfx(pfx string) bool {
}
func (r wfmRequest) dispFile() {
- fp := r.uFp // TODO(tenox): uDir + uBn
+ fp := r.uDir + "/" + r.uFbn
// TODO(tenox): deniedpfx should be in handlers???
if deniedPfx(fp) {
htErr(r.w, "access", fmt.Errorf("forbidden"))
@@ -54,7 +54,7 @@ func (r wfmRequest) dispFile() {
}
func (r wfmRequest) downFile() {
- fp := r.uFp // TODO(tenox): uDir + uBn
+ fp := r.uDir + "/" + r.uFbn
if deniedPfx(fp) {
htErr(r.w, "access", fmt.Errorf("forbidden"))
return
@@ -65,7 +65,7 @@ func (r wfmRequest) downFile() {
return
}
r.w.Header().Set("Content-Type", "application/octet-stream")
- r.w.Header().Set("Content-Disposition", "attachment; filename=\""+filepath.Base(fp)+"\";")
+ r.w.Header().Set("Content-Disposition", "attachment; filename=\""+url.QueryEscape(r.uFbn)+"\";")
r.w.Header().Set("Content-Length", fmt.Sprint(f.Size()))
r.w.Header().Set("Cache-Control", *cacheCtl)
streamFile(r.w, fp)
@@ -134,7 +134,7 @@ func streamFile(w http.ResponseWriter, uFilePath string) {
}
func (r wfmRequest) uploadFile(h *multipart.FileHeader, f multipart.File) {
- if !r.rw {
+ if !r.rwAccess {
htErr(r.w, "permission", fmt.Errorf("read only"))
return
}
@@ -171,7 +171,7 @@ func (r wfmRequest) uploadFile(h *multipart.FileHeader, f multipart.File) {
}
func (r wfmRequest) saveText(uData string) {
- if !r.rw {
+ if !r.rwAccess {
htErr(r.w, "permission", fmt.Errorf("read only"))
return
}
@@ -183,7 +183,7 @@ func (r wfmRequest) saveText(uData string) {
htErr(r.w, "text save", fmt.Errorf("zero lenght data"))
return
}
- fp := r.uFp // TODO(tenox): uDir + uBn
+ fp := r.uDir + "/" + r.uFbn
tmpName := fp + ".tmp"
err := ioutil.WriteFile(tmpName, []byte(uData), 0644)
if err != nil {
@@ -199,17 +199,17 @@ func (r wfmRequest) saveText(uData string) {
htErr(r.w, "text save", fmt.Errorf("temp file size != input size"))
return
}
- err = os.Rename(tmpName, r.uFp)
+ err = os.Rename(tmpName, fp)
if err != nil {
htErr(r.w, "text save", err)
return
}
- log.Printf("Saved Text Dir=%v File=%v Size=%v", r.uDir, r.uFp, len(uData))
- redirect(r.w, *wfmPfx+"?dir="+url.QueryEscape(r.uDir)+"&sort="+r.eSort+"&hi="+url.QueryEscape(filepath.Base(r.uFp)))
+ log.Printf("Saved Text Dir=%v File=%v Size=%v", r.uDir, fp, len(uData))
+ redirect(r.w, *wfmPfx+"?dir="+url.QueryEscape(r.uDir)+"&sort="+r.eSort+"&hi="+url.QueryEscape(r.uFbn))
}
func (r wfmRequest) mkdir() {
- if !r.rw {
+ if !r.rwAccess {
htErr(r.w, "permission", fmt.Errorf("read only"))
return
}
@@ -218,22 +218,21 @@ func (r wfmRequest) mkdir() {
return
}
- if r.uBn == "" {
+ if r.uFbn == "" {
htErr(r.w, "mkdir", fmt.Errorf("directory name is empty"))
return
}
- uB := filepath.Base(r.uBn)
- err := os.Mkdir(r.uDir+"/"+uB, 0755)
+ err := os.Mkdir(r.uDir+"/"+r.uFbn, 0755)
if err != nil {
htErr(r.w, "mkdir", err)
log.Printf("mkdir error: %v", err)
return
}
- redirect(r.w, *wfmPfx+"?dir="+url.QueryEscape(r.uDir)+"&sort="+r.eSort+"&hi="+url.QueryEscape(uB))
+ redirect(r.w, *wfmPfx+"?dir="+url.QueryEscape(r.uDir)+"&sort="+r.eSort+"&hi="+url.QueryEscape(r.uFbn))
}
func (r wfmRequest) mkfile() {
- if !r.rw {
+ if !r.rwAccess {
htErr(r.w, "permission", fmt.Errorf("read only"))
return
}
@@ -242,22 +241,21 @@ func (r wfmRequest) mkfile() {
return
}
- if r.uBn == "" {
+ if r.uFbn == "" {
htErr(r.w, "mkfile", fmt.Errorf("file name is empty"))
return
}
- fB := filepath.Base(r.uBn)
- f, err := os.OpenFile(r.uDir+"/"+fB, os.O_RDWR|os.O_EXCL|os.O_CREATE, 0644)
+ f, err := os.OpenFile(r.uDir+"/"+r.uFbn, os.O_RDWR|os.O_EXCL|os.O_CREATE, 0644)
if err != nil {
htErr(r.w, "mkfile", err)
return
}
f.Close()
- redirect(r.w, *wfmPfx+"?dir="+url.QueryEscape(r.uDir)+"&sort="+r.eSort+"&hi="+url.QueryEscape(fB))
+ redirect(r.w, *wfmPfx+"?dir="+url.QueryEscape(r.uDir)+"&sort="+r.eSort+"&hi="+url.QueryEscape(r.uFbn))
}
func (r wfmRequest) mkurl(eUrl string) {
- if !r.rw {
+ if !r.rwAccess {
htErr(r.w, "permission", fmt.Errorf("read only"))
return
}
@@ -265,15 +263,14 @@ func (r wfmRequest) mkurl(eUrl string) {
htErr(r.w, "access", fmt.Errorf("forbidden"))
return
}
- if r.uBn == "" {
+ if r.uFbn == "" {
htErr(r.w, "mkurl", fmt.Errorf("url file name is empty"))
return
}
- fB := filepath.Base(r.uBn)
- if !strings.HasSuffix(fB, ".url") {
- fB = fB + ".url"
+ if !strings.HasSuffix(r.uFbn, ".url") {
+ r.uFbn = r.uFbn + ".url"
}
- f, err := os.OpenFile(r.uDir+"/"+fB, os.O_RDWR|os.O_EXCL|os.O_CREATE, 0644)
+ f, err := os.OpenFile(r.uDir+"/"+r.uFbn, os.O_RDWR|os.O_EXCL|os.O_CREATE, 0644)
if err != nil {
htErr(r.w, "mkfile", err)
return
@@ -281,11 +278,11 @@ func (r wfmRequest) mkurl(eUrl string) {
// TODO(tenox): add upport for creating webloc, desktop and other formats
fmt.Fprintf(f, "[InternetShortcut]\r\nURL=%s\r\n", eUrl)
f.Close()
- redirect(r.w, *wfmPfx+"?dir="+url.QueryEscape(r.uDir)+"&sort="+r.eSort+"&hi="+url.QueryEscape(fB))
+ redirect(r.w, *wfmPfx+"?dir="+url.QueryEscape(r.uDir)+"&sort="+r.eSort+"&hi="+url.QueryEscape(r.uFbn))
}
func (r wfmRequest) renFile(uNewf string) {
- if !r.rw {
+ if !r.rwAccess {
htErr(r.w, "permission", fmt.Errorf("read only"))
return
}
@@ -294,24 +291,24 @@ func (r wfmRequest) renFile(uNewf string) {
return
}
- if r.uBn == "" || uNewf == "" {
+ if r.uFbn == "" || uNewf == "" {
htErr(r.w, "rename", fmt.Errorf("filename is empty"))
return
}
- fB := filepath.Base(uNewf)
+ newB := filepath.Base(uNewf)
err := os.Rename(
- r.uDir+"/"+r.uBn,
- r.uDir+"/"+fB,
+ r.uDir+"/"+r.uFbn,
+ r.uDir+"/"+newB,
)
if err != nil {
htErr(r.w, "rename", err)
return
}
- redirect(r.w, *wfmPfx+"?dir="+url.QueryEscape(r.uDir)+"&sort="+r.eSort+"&hi="+url.QueryEscape(fB))
+ redirect(r.w, *wfmPfx+"?dir="+url.QueryEscape(r.uDir)+"&sort="+r.eSort+"&hi="+url.QueryEscape(newB))
}
func (r wfmRequest) moveFiles(uFilePaths []string, uDst string) {
- if !r.rw {
+ if !r.rwAccess {
htErr(r.w, "permission", fmt.Errorf("read only"))
return
}
@@ -320,7 +317,7 @@ func (r wfmRequest) moveFiles(uFilePaths []string, uDst string) {
htErr(r.w, "access", fmt.Errorf("forbidden"))
return
}
- log.Printf("move dir=%v files=%+v dst=%v user=%v@%v", r.uDir, uFilePaths, uDst, r.user, r.remAddr)
+ log.Printf("move dir=%v files=%+v dst=%v user=%v@%v", r.uDir, uFilePaths, uDst, r.userName, r.remAddr)
lF := ""
for _, f := range uFilePaths {
@@ -339,7 +336,7 @@ func (r wfmRequest) moveFiles(uFilePaths []string, uDst string) {
}
func (r wfmRequest) deleteFiles(uFilePaths []string) {
- if !r.rw {
+ if !r.rwAccess {
htErr(r.w, "permission", fmt.Errorf("read only"))
return
}
@@ -347,7 +344,7 @@ func (r wfmRequest) deleteFiles(uFilePaths []string) {
htErr(r.w, "access", fmt.Errorf("forbidden"))
return
}
- log.Printf("delete dir=%v files=%+v user=%v@%v", r.uDir, uFilePaths, r.user, r.remAddr)
+ log.Printf("delete dir=%v files=%+v user=%v@%v", r.uDir, uFilePaths, r.userName, r.remAddr)
for _, f := range uFilePaths {
err := os.RemoveAll(r.uDir + "/" + filepath.Base(f))
diff --git a/handlers.go b/handlers.go
index 30c95ad..47e5486 100644
--- a/handlers.go
+++ b/handlers.go
@@ -9,38 +9,36 @@ import (
)
type wfmRequest struct {
- w http.ResponseWriter
- user string
- remAddr string
- rw bool
- modern bool
- eSort string // escaped sort order
- uDir string // unescaped directory name
- uFp string // unescaped (full) file path TODO(tenox): to be removed
- uBn string // unescaped base name
+ w http.ResponseWriter
+ userName string
+ remAddr string
+ rwAccess bool
+ modern bool
+ eSort string // escaped sort order
+ uDir string // unescaped directory name
+ uFbn string // unescaped file base name
}
func wfmMain(w http.ResponseWriter, r *http.Request) {
wfm := new(wfmRequest)
r.ParseMultipartForm(10 << 20)
- wfm.user, wfm.rw = auth(w, r)
- if wfm.user == "" {
+ wfm.userName, wfm.rwAccess = auth(w, r)
+ if wfm.userName == "" {
return
}
- go log.Printf("req from=%q user=%q uri=%q form=%v", r.RemoteAddr, wfm.user, r.RequestURI, noText(r.Form))
+ go log.Printf("req from=%q user=%q uri=%q form=%v", r.RemoteAddr, wfm.userName, r.RequestURI, noText(r.Form))
wfm.w = w
wfm.remAddr = r.RemoteAddr
+ wfm.eSort = url.QueryEscape(r.FormValue("sort"))
if strings.HasPrefix(r.UserAgent(), "Mozilla/5") {
wfm.modern = true
}
+ wfm.uFbn = filepath.Base(r.FormValue("file"))
wfm.uDir = filepath.Clean(r.FormValue("dir"))
if wfm.uDir == "" || wfm.uDir == "." {
wfm.uDir = "/"
}
- wfm.eSort = url.QueryEscape(r.FormValue("sort"))
- wfm.uFp = filepath.Clean(r.FormValue("fp"))
- wfm.uBn = filepath.Base(r.FormValue("file"))
// button clicked
switch {
@@ -100,16 +98,15 @@ func wfmMain(w http.ResponseWriter, r *http.Request) {
case "rename":
wfm.renFile(r.FormValue("dst"))
case "renp":
- wfm.uBn = r.FormValue("oldf")
wfm.prompt("rename", nil)
case "movp":
wfm.prompt("move", nil)
case "delp":
wfm.prompt("delete", nil)
case "move":
- wfm.moveFiles([]string{wfm.uBn}, r.FormValue("dst"))
+ wfm.moveFiles([]string{wfm.uFbn}, r.FormValue("dst"))
case "delete":
- wfm.deleteFiles([]string{wfm.uBn})
+ wfm.deleteFiles([]string{wfm.uFbn})
case "multi_delete":
wfm.deleteFiles(r.Form["mulf"])
case "multi_move":