       (.configureBlocking false)
       (.register selector SelectionKey/OP_READ))))
 
+
+(defn header-string-to-keyword [header-string]
+  (keyword (.trim (.toLowerCase header-string))))
+
 (defn parse-header [header]
-  (let [bits (seq (.split header "\\s+"))]
-    [(first bits) (second bits)])) ;; TODO: I want to use symbols for the header names...
+  (let [bits (seq (.split header "\\s*:\\s*"))]
+    [(header-string-to-keyword (first bits)) (second bits)])) ;; TODO: I want to use symbols for the header names...
 
 (defn parse-headers [header-lines]
+  "Returns a map of keyword -> string value"
   (if header-lines
-    (apply array-map (map parse-header header-lines))
+    (apply array-map (apply concat (map parse-header header-lines)))
     {}))
 
 (defn parse-request [request-string]

        head-lines (seq (.split (first parts) "\r?\n"))
        request-line (first head-lines)
        header-lines (rest head-lines)
        body (if (> (count parts) 1) (.join "\n" (rest parts)) nil)]
    (let [_ (seq (.split request-line "\\s+"))
          command (.trim (first _))
          path (.trim (second _))]
      [command path (parse-headers header-lines) body])))

(defn is-full-request? [content]
  (or (.endsWith content "\n\n") (.endsWith content "\r\n\r\n")))

(defn route [command path in-port out-port]
  (println "routing" command path)
  )

(defn route-request [request-string socket-channel]
  (apply
   (fn [command path headers body]
     (println command path headers body)
     (let [in-chan (chan 10) out-chan (chan)] ;; hm... should out-chan be unbuffered?

;; if/when I get more content, I dump that onto in-chan as well,
;; and I dump a :closed token onto in-chan when I get there.
;;
;;

(defn route [mappings]
  "TODO: add regex support, too, cuz we should."
  (let [route** (fn route* [mappings full-path path in-chan out-chan]
                  (loop [prefixes (keys mappings)]
                    (let [prefix (first prefixes)]
                      (println "prefix = " prefix)
                      (println "path is " path)
                      (if (.startsWith path prefix)
                        (let [next (mappings prefix)]
                          (if (instance? java.util.Map next)
                            (route* next full-path (.substring path (count prefix)) in-chan out-chan)
                            (do
                              (println "invoking" next)
                              (next path in-chan out-chan))
                            ))
                        (recur (rest prefixes))
                        )
                      )))]
    (fn [command path in-chan out-chan]
      (println "command = " command)
      (route** (mappings command) path path in-chan out-chan))))

(defn home [path in-port out-port]
  (println "HOME")
  (go (>! out-port 200)
      (>! out-port :headers)
      (>! out-port {:content-type "text"})
      (>! out-port :body)
      (>! out-port (str path " INDEX\n"))
      (>! out-port :end)))

(defn bing [path in-port out-port]
  (println "BING")
  (go (>! out-port 200)
      (>! out-port :headers)
      (>! out-port {:content-type "text"})
      (>! out-port :body)
      (>! out-port (str path " BING\n"))
      (>! out-port :end)))


(run (route {:get
             {"/foo" {"/bing" bing}
              "/" home}}))
