Web: motor HTTP, interfaz y panel de administración
Diseño previsto; aún no implementado.
Por qué un motor HTTP propio
- Sin administrador. La 2.0 usaba
HttpListener, que en Windows va sobre http.sys: escuchar fuera de localhost exige ser administrador o reservar la URL con netsh (que también lo exige). Cambiar la ruta (un "directorio virtual") no lo evita. Un Socket propio no necesita permisos en Windows con ningún puerto; en Linux y macOS los puertos por debajo de 1024 siguen requiriendo privilegios, por eso los puertos por defecto son altos.
- Tolerancia con clientes antiguos. Los navegadores de los 90 envían peticiones que los servidores modernos rechazan (saltos de línea solo
LF, HTTP/1.0 sin Host, cabeceras poco normales). Con un motor propio se aceptan.
- Native AOT. Sin ASP.NET Core,
sunfish-cli puede ser un binario nativo pequeño.
Alcance del motor
- Versiones: HTTP/0.9 (
GET /ruta sin versión: solo el cuerpo), HTTP/1.0 y HTTP/1.1.
- Métodos:
GET, HEAD, POST (formularios y subidas), PUT (subidas modernas) y los de WebDAV (FTP-Y-WEBDAV.md).
- Analizador tolerante: acepta
CRLF o LF; nombres de cabecera sin distinguir mayúsculas; Host opcional en 1.0.
- Conexiones: keep-alive en 1.1 y en 1.0 si se pide
Connection: keep-alive; si no, se cierra al terminar.
- Respuestas:
- Los ficheros llevan siempre
Content-Length: los clientes antiguos no conocen chunked, y así muestran el progreso.
- Las páginas generadas se envían con
chunked a clientes 1.1 y cerrando la conexión a los 1.0.
- Rangos (
Range: bytes=, uno solo) para reanudar descargas; If-Modified-Since → 304.
- Cuerpos:
Content-Length o chunked; Expect: 100-continue.
- Autenticación: HTTP Basic (la soportan hasta Mosaic y los primeros Netscape).
- Límites:
- Tamaño de la línea de petición y de las cabeceras (8 KB).
- Plazos de inactividad (contra conexiones lentas a propósito).
- Conexiones por IP.
- Tamaño máximo de subida, opcional.
- Puerto por defecto: 8080, configurable; IPv4 e IPv6.
- Sin TLS (fuera de alcance; para eso existe Arrejollal).
Interfaz web
Dos modos con la misma página
| Modo |
Para quién |
Qué cambia |
| Clásico |
Navegadores antiguos (por defecto si el User-Agent no es moderno) |
HTML 3.2/4.01 Transitional, maquetado con tablas, sin JavaScript, ISO-8859-1 |
| Moderno |
Navegadores actuales |
La misma estructura, UTF-8, un CSS sencillo y un JS pequeño para arrastrar y soltar y para subir por trozos con progreso |
- El servidor decide por el User-Agent. El usuario puede forzar el modo con un enlace (
?ui=classic / ?ui=modern), que se recuerda en una cookie si el navegador las admite.
- El modo clásico no incluye ningún
<script>: algunos navegadores antiguos muestran un diálogo de error por cada script que no entienden.
- Todo funciona sin JS: el JS del modo moderno solo mejora lo que ya hacen los formularios.
- Sin recursos externos (la 2.0 cargaba fuentes e iconos de Internet; en una LAN sin salida se veía rota). Iconos en GIF incrustados: IE3, Netscape 1–3 y Mosaic no muestran PNG.
Juego de caracteres
- Modo clásico: la página se declara ISO-8859-1.
- Los caracteres Latin-1 se escriben como entidades HTML (
á), que entienden incluso los navegadores de HTML 2.0.
- Los demás caracteres se muestran como
? (o transliterados cuando haya equivalente).
- Modo moderno: UTF-8.
- Los enlaces llevan siempre los bytes UTF-8 reales en
%XX, así que funcionan aunque el texto se vea transliterado: el navegador devuelve los mismos bytes al pedir.
- Lo que envía un navegador antiguo (nombres de carpeta nueva, nombres en subidas) llega en el juego de caracteres de la página o en el del sistema.
- El servidor intenta UTF-8 y, si no es válido, usa el juego configurado para clientes antiguos (ISO-8859-1 por defecto; MacRoman para Mac clásico).
- Pendiente de probar con clientes reales.
Navegador de directorios
- Tabla con icono, nombre (enlace), tamaño, fecha y acciones. Se ordena por nombre, tamaño o fecha con un enlace en la cabecera (
?sort=), sin JS.
- Migas de pan con la ruta y enlace a la raíz.
- Formularios, según los permisos del share:
- subir fichero (
multipart/form-data, RFC 1867, desde Netscape 2 e IE3/IE4);
- crear carpeta;
- descargar en ZIP.
- Renombrar y borrar llevan a una página de confirmación con un formulario POST. Nunca hay cambios por GET (la 2.0 borraba con
?action=delete).
- Mac clásico: con
Mac = true, enlaces [.bin] y [.hqx] junto a cada fichero (ver MAC-CLASICO.md).
- Escapado: todo nombre que se escribe en el HTML se escapa (la 2.0 no lo hacía).
Subidas
- Multipart: el analizador trabaja en flujo y escribe directamente a disco; los límites pueden quedar partidos entre búferes. La 2.0 leía byte a byte y lo guardaba todo en memoria.
- Nombre del fichero: se queda solo el nombre. IE antiguo envía la ruta completa (
C:\WINDOWS\fichero.txt) y Mac clásico puede usar : como separador.
- Escritura segura: se escribe a un temporal en la misma carpeta y se renombra al terminar. Una subida cortada no deja un fichero a medias ni pisa el existente.
- Modo moderno:
PUT por trozos con desplazamiento (como hacía la 2.0) para ficheros grandes y progreso. El trozo final confirma y renombra.
- Respeta
Upload y Overwrite; comprueba el espacio libre si el tamaño se conoce de antemano.
Descargar carpetas en ZIP
- Se genera en flujo, sin fichero temporal (la 2.0 creaba un ZIP temporal completo).
- Compatible con descompresores antiguos (PKZIP 2.x, StuffIt):
- Por defecto, método Stored con el CRC calculado antes de enviar. No necesita data descriptors y permite enviar
Content-Length, a costa de leer dos veces cada fichero.
- Opcionalmente Deflate con data descriptors; el tamaño final no se conoce de antemano.
- Nombres en CP437 si son representables; si no, UTF-8 con su indicador.
- ZIP64 solo si se superan los 4 GiB.
Autodescarga del servidor
/$sunfish/download entrega el propio ejecutable que está sirviendo (como hacía la 2.0), para repartirlo por la LAN. Se desactiva con SelfDownload = false.
Panel de administración
En /$sunfish/admin/, desactivado por defecto.
- Acceso: usuario
admin con contraseña (HTTP Basic); hash PBKDF2 en [Admin].
AllowFrom: lista de direcciones o redes desde las que se permite. Por defecto, solo el propio equipo.
- Funciones, las mismas que la GUI:
- estado y conexiones;
- activar o desactivar HTTP y FTP;
- shares (alta, baja, edición);
- usuarios y contraseñas;
- registro.
- HTML clásico también, para poder administrar desde cualquier navegador.
- Formularios POST con token anti-CSRF (ver SEGURIDAD.md).
- Los cambios se guardan en el fichero de configuración al momento.
- Aviso visible: la contraseña viaja en claro por la red.