diff main.go @ 12:84384cccda0e default tip

bubfix subpaths and remove hardcode
author atarwn@g5
date Mon, 23 Mar 2026 12:05:05 +0500
parents 350589d762a0
children
line wrap: on
line diff
--- a/main.go	Thu Mar 19 20:00:49 2026 +0500
+++ b/main.go	Mon Mar 23 12:05:05 2026 +0500
@@ -192,9 +192,10 @@
 	host := stripPort(r.Host)
 	reqPath := path.Clean(r.URL.Path)
 
-	dirs, caps := h.cfg.Match(host + reqPath)
+	dirs, caps, subPath := h.cfg.Match(host + reqPath)
 	if dirs == nil {
-		dirs, caps = h.cfg.Match(host)
+		dirs, caps, _ = h.cfg.Match(host)
+		subPath = reqPath // host-only block: full path is the subpath
 	}
 	if dirs == nil {
 		http.Error(rr, "not found", http.StatusNotFound)
@@ -203,12 +204,12 @@
 		return
 	}
 
-	h.serve(rr, r, dirs, caps)
+	h.serve(rr, r, dirs, caps, subPath)
 	rr.ensureStatus(http.StatusOK)
 	accessPrintf("d2o: %s %s%s -> %d %dB (%s)", r.Method, r.Host, r.URL.RequestURI(), rr.status, rr.bytes, time.Since(start).Truncate(time.Millisecond))
 }
 
-func (h *handler) serve(w http.ResponseWriter, r *http.Request, dirs []icf.Directive, caps map[string]string) {
+func (h *handler) serve(w http.ResponseWriter, r *http.Request, dirs []icf.Directive, caps map[string]string, subPath string) {
 	var (
 		rootDir  string
 		rootShow bool
@@ -277,21 +278,12 @@
 		return
 	}
 	if rootDir != "" {
-		fsPath := path.Clean(r.URL.Path)
-		displayPath := fsPath
-		if user, ok := caps["user"]; ok && user != "" {
-			mount := "/~" + user
-			if fsPath == mount || strings.HasPrefix(fsPath, mount+"/") {
-				trimmed := strings.TrimPrefix(fsPath, mount)
-				if trimmed == "" {
-					trimmed = "/"
-				}
-				fsPath = trimmed
-			}
-		}
-
+		// subPath is the remainder after the matched path pattern, e.g. for
+		// block "host/~<user>" and request "/~alice/about.html", subPath="/about.html".
+		// For host-only blocks it equals the full request path.
+		displayPath := path.Clean(r.URL.Path)
 		verbosePrintf("d2o: static -> %s (%s)", rootDir, r.URL.Path)
-		serveStatic(w, r, rootDir, rootShow, ndex, fcgiAddr, fcgiPat, cgiExec, cgiPat, fsPath, displayPath)
+		serveStatic(w, r, rootDir, rootShow, ndex, fcgiAddr, fcgiPat, cgiExec, cgiPat, subPath, displayPath)
 		return
 	}
 
@@ -306,6 +298,11 @@
 func serveStatic(w http.ResponseWriter, r *http.Request, rootDir string, show bool, ndex []string, fcgiAddr, fcgiPat, cgiExec, cgiPat string, fsPath, displayPath string) {
 	fpath := filepath.Join(rootDir, filepath.FromSlash(path.Clean(fsPath)))
 
+	// Use a cloned request with fsPath as URL.Path so that http.ServeFile and
+	// fcgi/cgi handlers see a path relative to rootDir, not the original URL.
+	r2 := r.Clone(r.Context())
+	r2.URL.Path = fsPath
+
 	info, err := os.Stat(fpath)
 	if os.IsNotExist(err) {
 		http.Error(w, "not found", http.StatusNotFound)
@@ -321,21 +318,21 @@
 			idxPath := filepath.Join(fpath, idx)
 			if _, err := os.Stat(idxPath); err == nil {
 				if fcgiAddr != "" && matchGlob(fcgiPat, idx) {
-					r2 := r.Clone(r.Context())
-					r2.URL.Path = path.Join(r.URL.Path, idx)
-					if err := serveFCGI(w, r2, fcgiAddr, rootDir); err != nil {
+					r3 := r2.Clone(r2.Context())
+					r3.URL.Path = path.Join(fsPath, idx)
+					if err := serveFCGI(w, r3, fcgiAddr, rootDir); err != nil {
 						log.Printf("d2o: fcgi error: %v", err)
 						http.Error(w, "gateway error", http.StatusBadGateway)
 					}
 					return
 				}
 				if cgiExec != "" && matchGlob(cgiPat, idx) {
-					r2 := r.Clone(r.Context())
-					r2.URL.Path = path.Join(r.URL.Path, idx)
-					serveCGI(w, r2, cgiExec, rootDir)
+					r3 := r2.Clone(r2.Context())
+					r3.URL.Path = path.Join(fsPath, idx)
+					serveCGI(w, r3, cgiExec, rootDir)
 					return
 				}
-				http.ServeFile(w, r, idxPath)
+				http.ServeFile(w, r2, idxPath)
 				return
 			}
 		}
@@ -343,11 +340,11 @@
 			http.Error(w, "forbidden", http.StatusForbidden)
 			return
 		}
-		listDir(w, r, fpath, displayPath)
+		listDir(w, r2, fpath, displayPath)
 		return
 	}
 
-	http.ServeFile(w, r, fpath)
+	http.ServeFile(w, r2, fpath)
 }
 
 func listDir(w http.ResponseWriter, r *http.Request, dir, urlPath string) {
@@ -585,4 +582,4 @@
 	if rr.status == 0 {
 		rr.status = defaultCode
 	}
-}
+}
\ No newline at end of file