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);