Mon, 26 Jun 2006

Blosxom Static Rending with Lighttpd

To get more familiar with lighttpd, I've switch over the web server on this machine from apache to lighty. The most difficult part has been replicating my apache setup to serve static blosxom files.

My goal is to serve a static html file if 1) a static version exists, 2) the query string is empty, and 3) the request is not a POST. Because I've switched from using the blosxom writeback plugin for comments to Haloscan, I don't have to worry about the third condition, but it would be nice to figure out a way to replicate RewriteCond %{REQUEST_METHOD} !^POST [NC] with lighty.

Here's what I've come up with in my lighttpd.conf:

$HTTP["host"] == "xn.pinkhamster.net" {
        server.document-root       = "/www/xn.pinkhamster.net"

        $HTTP["url"] =~ "^/blog" {
		cml.power-magnet = server.document-root + "/power-magnet.cml"
        }

	# There's no content at http://xn.pinkhamster.net/ so redirect to /blog/
        url.redirect = ("^/$" => "/blog/")

	# I'm not using the writeback plugin anymore so rewrite any
	# requests for writeback pages to the corresponding html page.
        url.rewrite-once = (
                "^/blog/(.+)\.writeback(\?.*|$)" => "/blog/$1.html$2",
        )

	# If there's not a static file served by the power-magnet, have blosxom
	# serve the page.
        alias.url = (
                "/blog" => "/usr/lib/cgi-bin/blosxom",
        )
        cgi.assign = ( "blosxom" => "" )

}

In order to serve the static pages, we have to use the power-magnet feature. The power-magnet is a CML (Cache Meta Language) script which runs for each request. In this case, we only run it for requests that start with "/blog". CML is designed to improve web serving performance by serving cached, static pages when possible.

CML scripts are written in Lua. My check for an empty query string doesn't work yet; I'm hoping to get some help on the lighty mailing list. Update: I've updated the check for an empty query string so it actually works. There was a logical error in my first attempt, but neither get.maxn ~= nil nor get.maxn ~= 0 works. So now I just loop through the query string values and update a counter if there are any. It's not very efficient, but it works. The rest of the script just checks for either a static index.html file if the request was for a directory or the static version of the requested page, and returns it if it exists. Update 2: I've updated the power magnet script to not have to loop through the get array.

-- if query string is empty and static file exists, serve static file
dr = request["DOCUMENT_ROOT"]
-- local f=assert(io.open(dr.."/debug.out","a"))

-- this doesn't work how i think it should
-- if get.maxn ~= nil then return 1 end

i = 0
for k,v in pairs(get) do
        i = i+1
end
-- f:write("i = ",i,"\n")
if i ~= 0 then return 1 end

sn = request["SCRIPT_NAME"]

static = string.gsub(sn, '^/blog/(.*)$', '/static/%1')

if (file_isdir(dr .. static) and file_isreg(dr .. static .. "/index.html")) then
--      f:write("cache hit on directory\n")
        output_include = { dr .. static .. "/index.html" }
        return 0
elseif file_isreg(dr .. static) then
--      f:write("cache hit on file\n")
        output_include = { dr .. static }
        return 0
end

-- f:write("no cache hit\n")
return 1

tech | Permanent Link

Tue, 20 Jun 2006

Debian Virtual Private Server

I got a new virtual private server (vps) from a company called TekTonic today. I've been meaning to replace the Pentium MMX 200 that hosted this blog and my email for a long time. The virtual server is running within Virtuozzo, a commercial virtualization product, though the underlying technology is also available as the open source OpenVZ.

For $8 per month, I've got a virtual server running on a Dual AMD Opteron 246 with 128MB of RAM, 5GB of disk space, and 512kbps out (with unmetered inbound traffic). Since I had been running on an old piece of crap, I've already got everything set up to run fine within a small amount of memory. Apache is server mostly static pages from blosxom; Postman is my lightweight webmail application for the rare occassion when I need it; visitors for web stats; uw-imapd and exim (though I am using the heavy build with exiscan-acl) for mail; and the good old jabberd in case I ever find someone who uses jabber/xmpp. If I were running a database or some java application server, I'd need more ram.

The bandwidth is capped by the virtualization software which means you can't spike, but it also means no overage charges. TekTonic charges $50/month for an additional megabit which is pretty good.

They offer CentOS 4, Fedora Core 4, Suse 10.0, and Debian 3.1, and they had my Debian server provisioned in about 10 minutes.

I've only been running on the new server for about 7 hours, but so far, I'm very impressed. If you're reading this, the server is still up, so that's good.

tech | Permanent Link

Sat, 17 Jun 2006

Left-Handed Pens

A couple months ago on Digg, there was a post about putting a Mont Blanc refill in a Pilot G2 case. Some of the comments indicated that the G2 itself was a very good pen. So the last time I went to Wal-Mart, I tried out the G2, which is a gel ink pen. Unfortunately, it was not designed for left-handed writers. The ink takes way too long to dry, and if you attempted to write with it, you would end up with a page full of smudged ink. If you're one of those lefties who gives us a bad name by turning the paper perpendicular or even upside-down, perhaps you could make it work, but I'm not familiar enough with the acrobatics of that method of writing.

I must recommend that the left-handed stick with Pilot's Extra Fine (0.5) VBall Grip, the ink of which dries quickly enough to cause only the occasional gentle smudge.

On a related note, Mead sells left-handed notebooks which are just regular notebooks with the front and back covers swapped so it opens on left and you write on the page on the left with the spiral on the right. Although I'm a bit ashamed that it took seeing one of these notebooks to come up with the solution to spiral hand, I now open all of my notebooks from the "back" and write on the left page.

misc | Permanent Link

Save the Date

My friend, Mike, is getting married later this year. I receive a "save the date" notice last week, followed by a second notice with a correction to the wedding's website.

I really don't understand the point of these notices. In order to send a save-the-date notificiation, you must already know when the wedding is, and if you know when the wedding is going to be, you almost certainly know where it's going to be held, especially if you're the type inclined to send out such notices. Furthermore, you know who you're going to be inviting because you wouldn't send a save-the-date notice to somebody who you aren't inviting. So, if you know all the critical details, why not just send out the invitations?

My hypothesis is that some couple actually had a legitimite need to send out such notices, such as an impending wedding date without a confirmed location. But some bachelorette received received one of these notices and decided her wedding had to have at least everything that her disorganized friend's did. And at some point, the stationer or wedding planner added save-the-dates to the checklist, and we'll be forever subject to such silliness until there is a cure to bridal irrationality syndrome.

culture | Permanent Link

The state is that great fiction by which everyone tries to live at the expense of everyone else. - Frederic Bastiat