ASHX continues to be cool
2008-04-07 @ 10:45#
i really like working with ASHX files. and i especially like 'scripting' them (no compiled code). using ASHX files lets me write 'ground-level' HTTP code without all the muss and fuss of pages, etc. and since it's scripted, i can make changes with only minor 'costs.'
below is a quick high-level view of a recent script to serve up summarized server logs. note the use of the SetCompression()
call and support for ETags
. also, though it's not shown in this code, i have support for local caching, too (using ASP.NET's Cache
class. this reduces CPU load.
public class LogData : IHttpHandler { HttpContext ctx = null; string etag = string.Empty; string data_folder = "~/log-data/"; public void ProcessRequest(HttpContext context) { ctx = context; SetCompression(ctx); switch (ctx.Request.HttpMethod.ToLower()) { case "get": Get(); break; case "head": Head(); break; default: throw new HttpException(405, "Method Not Allowed"); } } public bool IsReusable { get { return false; } } private void Head() { Get(true); } private void Get() { Get(false); } private void Get(bool headCall) { string out_text = string.Empty; string ifnonematch = string.Empty; string file = string.Empty; // get the file arg file = (ctx.Request["file"] != null ? ctx.Request["file"] : string.Empty); // get data to send if (file != string.Empty) { out_text = HandleFile(file); } else { out_text = HandleFileList(); } // check for not-modified ifnonematch = (ctx.Request.Headers["if-none-match"] != null ? ctx.Request.Headers["if-none-match"] : string.Empty); if (ifnonematch == etag) { ctx.Response.StatusCode = 304; ctx.Response.StatusDescription = "Not Modified"; } else { // ok, send the response ctx.Response.AddHeader("etag", etag); ctx.Response.ContentType = "text/html"; ctx.Response.StatusCode = 200; // only send body if this is not "head" call if (!headCall) { ctx.Response.Write(out_text); } } } // lots of important stuff goes here... }