Resources

GenHTTP provides a thin abstraction layer to control access of binary resources (such as files or blobs). This allows to re-use file-dependent handlers, independent from whether the data comes from the file system, a database or somewhere else.

Resources

Resources provide a unified way to load and access binary data used by handlers to achieve their functionality. For example, the Download handler serves a single file on request - where the content of the file originates from is not important for the handler to achieve its functionality.

var resource = Resource.FromFile("/var/www/downloads/myvideo.mp4"); // or FromString, FromAssembly, ...

var download = Download.From(resource);

await Host.Create()
          .Handler(download)
          .RunAsync();

By implementing the IResource interface, a custom data source can be used to provide resources, for example a database or a cloud blob storage.

Built-in Providers

The following resource implementations are provided by the IO module:

Example Description
Resource.FromString("Hello World") Creates a resource from a string constant.
Resource.FromFile("binary.blob") Creates a resource from the given file.
Resource.FromAssembly("binary.blob") Loads the resource from the currently executed assembly.
Resource.FromWeb("https://...") Creates a resource to be fetched from a web server.

Change Tracking

For some use cases it might be important to determine, whether a given resource has changed since it has been accessed the last time. For example, the page handler will re-compile its template whenever the underlying resource has changed.

var resource = Resource.FromFile("...")
                       .Build()
                       .Track();

await using var content = await resource.GetContentAsync();

var changed = await content.CheckChangedAsync();

Resource Trees

Similar to the resources, resource trees provide an abstraction for a directory structure that can be consumed by handlers such as the Directory Browsing or the Single Page Application.

var tree = ResourceTree.FromDirectory("/var/www/downloads/"); // or FromAssembly, ...

var listing = Listing.From(tree);

await Host.Create()
          .Handler(listing)
          .RunAsync();

Archives

This module allows you to create resource trees from archive files such as zip, tar, 7z or rar. Typical use cases include reducing the number of files that need to be checked into your source repository, or directly hosting files from a release package without extracting it first. The following example hosts an application that allows browsing the contents of the given archive file:

using GenHTTP.Engine.Internal;

using GenHTTP.Modules.Archives;
using GenHTTP.Modules.DirectoryBrowsing;
using GenHTTP.Modules.IO;
using GenHTTP.Modules.Practices;

// http://localhost:8080

var archive = Resource.FromFile("./sample.zip");

var tree = ArchiveTree.From(archive);

var app = Listing.From(tree);

await Host.Create()
          .Handler(app)
          .Defaults()
          .Console()
          .RunAsync();

Virtual Trees

Virtual trees allow to combine different sources of resources into an unified tree:

var tree = VirtualTree.Create()
                      .Add("index.html", Resource.FromFile(...))
                      .Add("config.js", Resource.FromAssembly(...))
                      .Add("dist", ResourceTree.FromDirectory(...));

var app = SinglePageApplication.From(tree);

Resolving Files

When using resource trees within a handler, you might want to search for files based on the remaining path of the request to be routed. The Find() extension provided by the IO module will attempt to find the requested resource or resource node from the current routing context and automatically advance the target.

// either folder or file will be set
// if both are null, routing did not succeed
var (folder, file) = await Tree.Find(request.Target);