now | writings | rss | github | twitter | contact

no, you failed because you had the wrong dream

posted to writings on aug 5th, 2007 with tags apache, mac, nerd, and ruby and commented on four times

the data for my events section on this site comes from ical on my imac, which ultimately comes from the calendar on my blackberry which synchronizes to the imac once in a while. ical automates this upload to my server by utilizing webdav and issuing an http "put" with the ical data in ics format whenever it gets changed. the webdav apache module on my server writes that data to a file, and then a process run from cron every once in a while scrapes it up, parses it, and merges it with the sqlite data to be shown here.

it worked ok with my old php site, but now that it's in ruby, i never got around to writing the new version to parse the ics file and merge it with the existing activerecord objects. as i was about to yesterday, i thought, "why bother with that when ical can just talk directly to the ruby app?"

so rather than using the apache webdav module to handle the authentication and write the file to disk, the request just gets passed through to my camping app which receives the data directly from ical and does its magic. no more webdav module, no more temporary file, and no more cron job to routinely parse the same file over and over.

the webdav code ended up being fairly short. it just hooks up a route to handle requests to /dav/* and then reads the ics file input from ical after performing basic http authentication. of course, it's not a complete webdav implementation, but it works enough to satisfy ical.

module Platonic::Controllers 
  [...]
  class Dav < R '/dav/(.+)'
    DAV_USER = "example"
    DAV_PASS = "secret"
    DAV_REALM = "protected area"

    def delete(file)
      return if !authorized?

      # don't actually delete anything

      @status = "204" # no content
    end

    def put(file)
      return if !authorized?

      Event.sync_from_ics(@in.read)

      @status = "201" # created
    end

  private
    def authorized?
      %w(
        REDIRECT_REDIRECT_X_HTTP_AUTHORIZATION
        REDIRECT_X_HTTP_AUTHORIZATION
        X-HTTP_AUTHORIZATION
        HTTP_AUTHORIZATION
        Authorization
      ).each do |h|
        if m = Regexp.new(/^Basic (.+)/).match(@env[h].to_s)
          user, pass = Base64.decode64(m[1]).split(":")
          return true if user == DAV_USER && pass == DAV_PASS
        end
      end

      @status = "401"
      @headers["WWW-Authenticate"] = "Basic realm=\"#{DAV_REALM}\""
      return false
    end
  end
  [...]
end

ical is then setup to publish a calendar to https://.../dav/ with the corresponding username and password.

Comments? Contact me via Twitter or e-mail.

4 Comments

dentarg (authentic) on august 6th, 2007 at 13:14:53:

cool!

benoitc (authentic) on august 7th, 2007 at 01:32:40:

I have a question in my head since I saw your website. Do you developp web application under openbsd ? What about design ? Just a question since I hesitate myself between both for all my work.

joshua (authentic) on august 7th, 2007 at 17:26:30:

yes, i do all of my development on an openbsd laptop and have for the past 7 years or so.

i do all of my php, perl, ruby, rails, html, css, and javascript development by hand in vim. i usually use screen in an 80x40 xterm to manage a few different vim sessions while editing multiple files (i never got the hang of managing multiple buffers at the same time in vim). i write some code, alt+tab to firefox, reload, alt+tab back to vim, change it, repeat.

i have an imac on my desk that runs mac os that i use to verify layouts in safari and firefox. when i have to, i start parallels on it and check it in ie6/7 under winxp.

though i did just order one of the new imacs that came out today which will be my new mac machine, and my current intel imac will become an openbsd workstation. since i mostly work from home now i rarely have to take my laptop anywhere so i'm going to switch back to a desktop.

rob (authentic) on august 17th, 2007 at 03:38:16:

how much for old imac