经过大量研究,我发现以下似乎有效。
配置
在AppHost
构造函数中:
CatchAllHandlers.Add(
(httpMethod, pathInfo, filePath) =>
Tims.Support.StaticFileHandler.Factory(
Params.Instance.HttpDataDir,
"/",
pathInfo
)
);
工厂
检查文件是否存在,并返回适当的处理程序,如果不处理文件(因为它不存在),则返回 null。这很重要,这样其他 url(例如/metadata
继续工作。
处理程序
实际处理程序的核心方法非常简单。ProcessRequest
通过使用适当的资源类型覆盖和返回文件的字节,工作就完成了。为简单起见,此版本不包括任何用于缓存目的的日期处理。
示例代码
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;
}
}