ServiceStack: service static files from a directory if available?

I am in the process of converting my standalone home web server using ServiceStack to serve all pages and resources.

I see on this subject

Serving a static file with a utility

You can easily serve one static file using Service Stack.

In my home implementation, after checking if the URL matches any particular handler (equivalent to ServiceStack routes), the default handler then checks the static file in its HttpData directory to match the URL.

If this file does not exist, it generates a 404 error.

What is the best template to use with ServiceStack to serve files from the file system if no other service maps? Please note that I use it offline without IIS.

These files can be HTML, PNG, JS and some other types of content.

Note. I see that the ServiceStack.Razor package can help my requirements, but I can not find the documentation on it. I will ask a separate question.

Edit: I found a link in this question

Create a route for the root path, '/', with ServiceStack

points to

Register a IAppHost.CatchAllHandlers - This is called for non-matching requests.

So far, I have not found any documentation or an example on how to register. Note. I work offline, so this needs to be done in C #, not XML.

+2
source share
1 answer

After much research, I found the following that seems effective.

Configuration

In the AppHost constructor:

  CatchAllHandlers.Add( (httpMethod, pathInfo, filePath) => Tims.Support.StaticFileHandler.Factory( Params.Instance.HttpDataDir, "/", pathInfo ) ); 

factory

Checks for a file and returns the appropriate handler or returns null if it does not process the file (because it does not exist). This is important, so other URLs (e.g. /metadata continue to work.

Handler

The basic method of the actual handler is very simple. ProcessRequest and returning the bytes of the file with the corresponding resource type, the task is executed. This version for simplicity does not include date processing for caching purposes.

Code example

 public class StaticFileHandler : EndpointHandlerBase { protected static readonly Dictionary<string, string> ExtensionContentType; protected FileInfo fi; static StaticFileHandler() { ExtensionContentType = new Dictionary<string, string> (StringComparer.InvariantCultureIgnoreCase) { { ".text", "text/plain" }, { ".js", "text/javascript" }, { ".css", "text/css" }, { ".html", "text/html" }, { ".htm", "text/html" }, { ".png", "image/png" }, { ".ico", "image/x-icon" }, { ".gif", "image/gif" }, { ".bmp", "image/bmp" }, { ".jpg", "image/jpeg" } }; } public string BaseDirectory { protected set; get; } public string Prefix { protected set; get; } public StaticFileHandler(string baseDirectory, string prefix) { BaseDirectory = baseDirectory; Prefix = prefix; } private StaticFileHandler(FileInfo fi) { this.fi = fi; } public static StaticFileHandler Factory(string baseDirectory, string prefix, string pathInfo) { if (!pathInfo.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase)) { return null; } var fn = baseDirectory + "/" + pathInfo.After(prefix.Length); var fi = new System.IO.FileInfo(fn); if (!fi.Exists) { return null; } return new StaticFileHandler(fi); } public override void ProcessRequest(IHttpRequest httpReq, IHttpResponse httpRes, string operationName) { using (var source = new System.IO.FileStream(fi.FullName, System.IO.FileMode.Open)) { var bytes = source.ReadAllBytes(); httpRes.OutputStream.Write(bytes, 0, bytes.Length); } // timeStamp = fi.LastWriteTime; httpRes.AddHeader("Date", DateTime.Now.ToString("R")); httpRes.AddHeader("Content-Type", ExtensionContentType.Safeget(fi.Extension) ?? "text/plain"); } public override object CreateRequest(IHttpRequest request, string operationName) { return null; } public override object GetResponse(IHttpRequest httpReq, IHttpResponse httpRes, object request) { return null; } } 
+7
source

All Articles