package adapters import ( "errors" "mime" "path/filepath" "strings" ) func SafeRel(root, requested string) (string, error) { s := requested if after, ok := strings.CutPrefix(s, "/"); ok { s = after } full := filepath.Join(root, filepath.FromSlash(s)) rel, err := filepath.Rel(root, full) if err != nil { return "", err } if rel == "." { return "/", nil } sep := string(filepath.Separator) if strings.HasPrefix(rel, "..") || strings.Contains(rel, ".."+sep) { return "", errors.New("path escapes root") } return "/" + filepath.ToSlash(rel), nil } func ResponsePath(root, full string) string { rel, err := filepath.Rel(root, full) if err != nil || rel == "." { return "/" } return "/" + filepath.ToSlash(rel) } var textPlainExtensions = map[string]bool{ ".txt": true, ".log": true, ".json": true, ".yaml": true, ".yml": true, ".toml": true, ".xml": true, ".csv": true, } func contentTypeFor(name string) string { ext := strings.ToLower(filepath.Ext(name)) switch ext { case ".md", ".markdown", ".mdown": return "application/markdown" } if ct := mime.TypeByExtension(ext); ct != "" { return ct } if textPlainExtensions[ext] { return "text/plain; charset=utf-8" } return "application/octet-stream" }