Mercurial Hosting > d2o
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
