Diseño previsto; aún no implementado.
En la 2.0 se distinguía "servir una web" y "compartir una carpeta". En la 3 son lo mismo: un share publica una carpeta del disco en una location (ruta URL) y se ofrece a la vez por web, FTP y, si se activa, WebDAV.
index.html por defecto), la web lo sirve.Cada share tiene una Location (/, /fotos, /fotos/viaje…). Se resuelve como las locations de prefijo de nginx: gana el prefijo más largo.
/foto no captura /fotos./fotos sin barra final redirige a /fotos/.Ejemplo:
| Share | Location | Carpeta |
|---|---|---|
| web | / |
C:\www |
| fotos | /fotos |
D:\Fotos |
| viaje | /fotos/2026/viaje |
E:\Viaje |
| Petición | Share | Ruta real |
|---|---|---|
/index.html |
web | C:\www\index.html |
/fotos/a.jpg |
fotos | D:\Fotos\a.jpg |
/fotos/2026/b.jpg |
fotos | D:\Fotos\2026\b.jpg |
/fotos/2026/viaje/c.jpg |
viaje | E:\Viaje\c.jpg |
/fotos/ aparece 2026/ aunque D:\Fotos\2026 no exista, y dentro viaje/.| Situación | / muestra |
|---|---|
Hay un share en / |
Ese share (con los demás como directorios virtuales) |
No hay share en / y RootMenu = true |
El menú de shares |
No hay share en / y RootMenu = false |
404 (la web) / carpeta vacía (FTP) |
/$sunfish/ está reservado para los recursos internos (iconos, CSS, JS), el panel de administración (/$sunfish/admin/) y la autodescarga del ejecutable (/$sunfish/download). Ninguna location puede empezar por /$sunfish.
Toda ruta de web, FTP o WebDAV pasa por la misma validación antes de tocar el disco:
%XX) una sola vez y se normaliza el separador a /... y . como componentes, \, : (flujos alternativos de NTFS), NUL y caracteres de control, y rutas absolutas incrustadas.CON, PRN, AUX, NUL, COM1–COM9, LPT1–LPT9) y los nombres acabados en punto o espacio.(La 2.0 hacía Path.Combine sin validar: este es el cambio de seguridad más importante.)
Por share, todos desactivados por defecto salvo la lectura:
| Opción | Permite |
|---|---|
Listing |
Ver el navegador de directorios cuando no hay índice (y listar por FTP/WebDAV) |
Upload |
Subir ficheros nuevos y crear carpetas |
Overwrite |
Subir sobre un fichero existente |
Rename |
Renombrar y mover dentro del share |
Delete |
Borrar ficheros y carpetas |
Zip |
Descargar una carpeta como ZIP |
Usuarios: si un share tiene Users, todo acceso (web, FTP, WebDAV) requiere usuario y contraseña de esa lista; si no, es público. Pendiente: permisos distintos por usuario dentro de un mismo share (p. ej. lectura pública y escritura con usuario).
INI editable a mano, con claves en inglés (los mensajes al usuario van en español o inglés).
# sunfish.conf [Server] Name = Sunfish HttpPort = 8080 FtpPort = 2121 FtpPassivePorts = 50000-50050 Bind = 0.0.0.0, :: RootMenu = true SelfDownload = true [Admin] Enabled = false PasswordHash = <PBKDF2> AllowFrom = 127.0.0.1, ::1 [User ana] PasswordHash = <PBKDF2> [Share web] Location = / Path = C:\www Index = index.html Listing = false [Share fotos] Location = /fotos Path = D:\Fotos Listing = true Upload = true Zip = true Users = ana Mac = true WebDav = true Enabled = true
Index = index.html (vacío = sin índice), Listing = true, Ftp = true, WebDav = false, Mac = false, Enabled = true, el resto de permisos false.La primera que exista:
-c FICHERO (o --config).sunfish.conf junto al ejecutable (modo portable).%APPDATA%\Sunfish\sunfish.conf, ~/.config/sunfish/sunfish.conf (o $XDG_CONFIG_HOME), ~/Library/Application Support/Sunfish/sunfish.conf.Si no existe ninguna, la aplicación ofrece crearla junto al ejecutable o en la carpeta del usuario. Sunfish.exe y sunfish-cli usan el mismo formato y las mismas rutas, así que pueden compartir configuración (no a la vez: competirían por los puertos).
La 2.0 guardaba un JSON llamado sunfish2 en el directorio de trabajo. Si no hay configuración nueva y existe sunfish2 junto al ejecutable, se ofrece importarlo:
| 2.0 | 3 |
|---|---|
Port |
HttpPort |
SunfishRoot |
RootMenu |
servicio WebService: Name, Location, Enabled |
[Share <Name>], Location, Enabled |
path |
Path |
defaultFile |
Index |
folderShare |
Listing |
readOnly = false |
Upload = true, Overwrite = true, Rename = true |
allowDeletion |
Delete (solo si no era de solo lectura) |
allowServerExecution |
se ignora (la función ya no existe) |
AdminPanel, AdminPwd |
se ignoran: se pide una contraseña nueva (la 2.0 la guardaba en claro) |