Sunday, July 22, 2007

next steps for exyus

now that things are pretty stable (codebase-wise), i'm putting together a list of 'next step's for the framework. here's what i have so far:

  • add support for feeds
    this will include publishing a feed from the blog (or other data source) as well as the ability to consume feeds from other sources. consuming feeds will also mean support for caching the feed locally and transforming it as a standard data source. 
  • add support for external editors
    most likely this will be in the form of the metaWeblog API. i figure the ATOM format is really more 'geek-friendly' but the metaWeblog API has been around for several years and there's lots of support for it 'in the wild.' I'm thinking of using MSFT's Live Writer as a test-bed for my implementation, too.
  • add support for handheld posting
    this would allow me to post from my moto-q phone or any other html-aware small form-factor device. i think this means a pure html approach (no javascript). shouldn't be too much of a problem. the authentication might take some thinking (a simple user/password screen that does the real basic auth on the server?), tho. also, it will be a post-only pattern (no editing existing posts, deleting, etc.) that does not support markup (no p-tags, et al).
  • add support for DIGEST auth
    this has been on my list for a while. it'll be a bit gnarly (my BASIC auth pattern is kinda buried into the code now) so i've put it off for a while. but i have a working example of DIGEST support for C#/ASP.NET already. so it'll be a relatively boring (i hope) day or two of hacking up the code and getting all the bugs out.
  • move users and auth to db
    current the user list (small) and permissions list (kinda growing) is stored in two XML files. this works well for now and is easy to work with (and cached, too). eventually, this should be moved to the SQL-DB, tho. not a big rush on this one. it's another example of something that will happen behind the scenes.
  • add SSL support
    first, i need to post the code to a public server. second, i need to get a simple SSL cert installed. finally, i need to make sure my existing code works well with SSL. should be no big deal. the only 'magic' might be getting the exyus framework to force SSL for certain URLs. not sure if that's needed, but i can see benefits. 

well, that should keep me busy for a while!

sweetening exyus

i did more work this week to sweeten the exyus framework.

304 fixed

first, i fixed my broken 304 handling. when i was storing all cached data on disk, the 304 handler would compare the file timestamps against the if-modified-since and etag headers (serialized) to determine if 304 was the proper response. when i moved the cache into memory, my 304 checking was broken. i would return data from the cache, but always return false for 304 checking (no file data anymore!). to fix this, i resurrected a simple cache object that has timestamp, etag, and payload properties. now all resource entries in the memory cache are cache objects and my 304 checking is working again. sweet!

support for HTTP HEAD

second, i added support for the HTTP HEAD method. actually, it was embarrassingly easy. i just call the GET method and then toss out the response content. this allows for all the usual good stuff (304 checking, marking the item w/ last-modified, and etag, etc.), but doesn't return a body. now i have solid HEAD support!

cache invalidation implemented

my other big task was to implement a simple cache invalidation pattern. i did thsi by implementing support for the cache-control:no-cache header in my GET requests. that means anyone can issue a GET request to a URI with the cache-control:no-cache header and that will force the system to invalidate any existing cached version of that resource and return a fresh one. of course, along the way, this fresh version will get placed in the cache for future calls! *and* (to make it all really nice), you can even use HEAD instead of GET!

simplify data object declaration

finally, i tightened up the initial declaration for data object. no longer do you need to declare each verb XSD/XLST set. you just supply a single directory location that holds the [verb].xsd and/or [verb].xsl files. this emphasizes the standard interface concept for HTTP/REST and simplifies/shortens the declaration code. now, a data object declaration looks like this:


[UrlPattern("/data/websites/(.*).xcs")]
public class websiteData : SqlXmlHandler
{
public websiteData()
{
this.ConnectionString = "mamund_personal_db";
this.UrlPattern = @"/websites/(.*).xcs\??(.*)$";
this.DocumentsFolder = "~/documents/websites/";
this.XHtmlNodes = new string[] { "//description" };
this.ClearCacheUri = new string[]
{ "/blogging/",
"/blogging/websites/",
"/blogging/websites/{@id}"
};
}

Saturday, July 14, 2007

getting to the next level

it's been a while since i posted here, but that's just 'cuz i been bizzy!

finally getting the exyus framework distilled to the important bits. i now have a single pageHandler class that handles standard HTML GET activity. it can be sub-classed and declaring a new page in the site looks like this (C#):

[UrlPattern(@"/blogging/.xcs\??(.*)$")]
public class home : pageHandler
{
public home()
{
this.TemplateXml = "/blogging/index.xml";
this.TemplateXsl = "/blogging/index.xsl";
this.MaxAge = 600;
}
}

note i only need an xml document (that supports x:include, btw) and a transform (that supports exslt, etc.) and i'm rockin'

i also added a dataHandler class today. this can be used to produce XML resources that respond to the standard GET POST PUT DELETE interface. again, i distilled it down to a small bit of code that leverages XML,XSD, XSLT and a dash of TSQL. here's a typical class:


[UrlPattern("/data/weblogs/(.*).xcs")]
public class weblogData : dataHandler
{
public weblogData()
{
this.ConnectionString = "mamund_personal_db";
this.UrlPattern = @"/data/weblogs/(.*).xcs\??(.*)$";
this.XHtmlNodes = "//body";

this.PostXsdFile = "~/documents/weblog/weblog-post.xsd";
this.PostXslFile = "~/documents/weblog/weblog-post.xsl";
this.PutXsdFile = "~/documents/weblog/weblog-put.xsd";
this.PutXslFile = "~/documents/weblog/weblog-put.xsl";
this.DeleteXslFile = "~/documents/weblog/weblog-delete.xsl";
this.GetXslFile = "~/documents/weblog/weblog-get.xsl";
}
}

again, it's all about creating the proper schema and transform files. of course, there' some T-SQL in the background, but that's another story.

the point here is that it's now pretty simple to create a web site that supports all the standard (X)HTML stuff as well as acts as a good HTTP netizen. most of this is following the REST model (with liberties along the way).

finally, i implemented a no-cache pattern last week. now, if you do a GET using the cache-control:no-cache header, exyus will ignore any cached value and rebuild the request (caching it along the way, if called for).  using the header is a bit cumbersome for html clieints, but works fine for scripting and ajax work.

i need to exercise the new upper-level classes (dataHandler mostly) but they should be solid. next, i want to work more on the requestor class (to make internal http requests) and then look at wrapping things up for the first post to a public server!