Skip to content

Instantly share code, notes, and snippets.

Created October 6, 2009 19:01

Revisions

  1. @invalid-email-address Anonymous created this gist Oct 6, 2009.
    51 changes: 51 additions & 0 deletions qbert.clj
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,51 @@
    (ns alandipert.qbert
    (:use [clojure.contrib.duck-streams :only (reader writer read-lines spit)]
    [clojure.contrib.str-utils :only (re-split str-join)])
    (:import (java.net ServerSocket Socket InetAddress URLDecoder)
    (java.io File)))

    (def status {200 "HTTP/1.0 200 OK" 404 "HTTP/1.0 404 Not Found" })
    (def content {"css" "Content-type: text/css" "jpg" "Content-type: image/jpeg" "html" "Content-type: text/html" "txt" "Content-type: text/plain" })
    (def error {404 "The file was not found."})
    (def doc-root "/Users/alan/Sites")

    (defn build-headers [& headers]
    "Build a header string and end it with two spaces"
    (str (str-join "\r\n" headers) "\r\n\r\n"))

    (defn get-ext [abspath]
    (last (re-split #"\." abspath)))

    (defn deliver-resource [sock uri]
    "Figure out if the resource exists, and send it back"
    (let [os (.. sock getOutputStream)
    file (File. (str doc-root (URLDecoder/decode uri)))
    path (.. file getAbsolutePath)
    ext (get-ext path)]
    (with-open [wrt (writer os)]
    (if (.. file exists)
    (do
    (spit wrt (str (build-headers (status 200) (content ext "txt"))))
    (.. os write (to-byte-array file) 0 (.. file length)))
    (spit wrt (str (build-headers (status 404) (content "txt")) "File not found."))))
    (.. sock close)))

    (defn handle-request [sock]
    "Parse out the URI from the request pass it on"
    (let [is (.. sock getInputStream)]
    (with-open [rdr (reader is)]
    (deliver-resource sock (second (re-split #"\s+" (first (line-seq rdr))))))))

    (defmulti http-listen class)

    (defmethod http-listen ServerSocket [socket]
    "Bind to a socket and keep listening"
    (let [client-socket (.. socket accept)]
    (handle-request client-socket))
    (recur socket))

    (defmethod http-listen Integer [port]
    "Takes a port number to listen on"
    (http-listen (ServerSocket. port)))

    (http-listen 8081)