domingo, 18 de septiembre de 2016

Asp.Net Core: Sirviendo ficheros estáticos

Anteriormente en NoCompila hemos visto como se gestiona una petición web mediante middlewares encadenados en Asp.Net Core.
Si quisiésemos devolver el contenido de un fichero, tendríamos que escribir un middleware que analizase el httpRequest, viese qué fichero se está demandando, buscarlo en el sistema de ficheros local y servirlo.
Afortunadamente eso no hace falta programarlo, uno de los middlewares que trae de serie Asp.Net Core es UseStaticFiles que por defecto sirve los ficheros que están ubicados en el directorio wwwroot de la aplicación web.
Para que el Host de la aplicación sepa la ruta local que está manejando debemos indicárselo

public static void Main(string[] args)
{
	var host = new WebHostBuilder()
		.UseKestrel()
		.UseContentRoot(Directory.GetCurrentDirectory())
		.UseIISIntegration()
		.UseStartup<Startup>()
		.Build();

	host.Run();
}

En la línea 5 se establece el ContentRootPath en el webHost, que indica la dirección en el sistema de ficheros local donde se está la aplicación. Una vez establecido el ContentRootPath, otra propiedad se estable por defecto: el WebRootPath, que es el directorio local desde el que se van a servir los ficheros estáticos (por defecto el directorio wwwroot).
Una vez que nuestro Host conoce la ruta de los ficheros, configuramos el pipeline para que sirva ficheros estáticos.

public void Configure(IApplicationBuilder app)
{
	app.UseStaticFiles();
}

UseStaticFiles es el middleware para servir los ficheros estáticos. Pero importante, una de las carencias de Asp.Net Core es que no se puede securizar el contenido de el ContentWebRoot, es decir, de los ficheros estáticos del directorio wwwroot. Todo lo contenido en ese directorio es público sí o sí.

Sirviendo ficheros por defecto

Para servir ficheros por defecto, se utiliza otro middleware del framework: UseDefaultFiles. Este componente no sirve ficheros, lo que hace es un URL rewrite (cambia la ruta de la petición) buscando un fichero cuando solo se le indica un directorio. Si tenemos en cuenta el orden de ejecución de los middlewares importa debemos sabes que hay que usar UseDefaultFiles antes que UseStaticFiles.

public void Configure(IApplicationBuilder app)
{
	app.UseDefaultFiles();
	app.UseStaticFiles();
}

Por defecto los ficheros que busca son:

  1. default.htm
  2. default.html
  3. index.htm
  4. index.html

Habilitando la exploración de directorios

La exploración de directorios está deshabilitada por defecto por motivos de seguridad, pero si se quiere habilitar hay que hacer dos cosas:

  1. Usar el método AddDirectoryBrowser que registra los servicios de exploración de directorios en el contenedor IoC
  2. Añadir al pipeline de la aplicación el middelware UseDirectoryBrowser
public class Startup
{
	// This method gets called by the runtime. Use this method to add services to the container.
	// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
	public void ConfigureServices(IServiceCollection services)
	{
		services.AddDirectoryBrowser();
	}

	// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
	public void Configure(IApplicationBuilder app)
	{
		app.UseStaticFiles();
		app.UseDirectoryBrowser();
	}
}

Sirviendo ficheros estáticos con ficheros por defecto y habilitando la exploración de directorios a la vez

Alguien debió pensar que para configurar una aplicación web que únicamente sirve ficheros no se debería tener que escribir tanto, asi que tenemos un método extensor que nos permite delegar la configuración de todos los middlewares en una única línea: UseFileServer

public class Startup
{
	// This method gets called by the runtime. Use this method to add services to the container.
	// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
	public void ConfigureServices(IServiceCollection services)
	{
		services.AddDirectoryBrowser();
	}

	// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
	public void Configure(IApplicationBuilder app)
	{
		app.UseFileServer(enableDirectoryBrowsing: true);
	}
}

No hay comentarios:

Publicar un comentario