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...
}

code