http-kit/http-kit — pull request #21 by ptaoussanis (2013-03-04 12:36:54+00:00)
Title: Work in progress: new response API

* Current status: merge-able, HTTP responses seem to be working. Haven't run unit-tests.
* Introduces new `with-channel` macro.
* Includes 2.x backwards compatibility with `ws-response` and `async-response`.
* I'm quite happy with the API here - it's powerful and quite simple.

New API with doc-string and examples:

```clojure
(defmacro with-channel
"Evaluates body with `ch-name` bound to the request's underlying asynchronous
HTTP or WebSocket channel, and returns {:body AsyncChannel} as an
implementation detail.

;; Asynchronous HTTP response (with optional streaming)
(defn my-async-handler [request]
(with-channel request ch ; Request's channel
(future ; Respond from any thread
(send! ch {:status 200
:headers {\"Content-Type\" \"text/html\"}
:body \"This is an async response!\"}
;; false ; Uncomment to use chunk encoding for HTTP streaming
))))

;; WebSocket response
(defn my-chatroom-handler [request]
(if-not (:websocket? request)
{:status 200 :body \"Welcome to the chatroom! JS client connecting...\"}
(with-channel request ch
(println \"New WebSocket channel:\" ch)
(on-receive ch (fn [msg] (println \"on-receive:\" msg)))
(on-close ch (fn [status] (println \"on-close:\" status)))
(send! ch \"First chat message!\"))))

Channel API (see relevant docstrings for more info):
(open? [ch])
(close [ch])
(websocket? [ch])
(send! [ch data] [ch data close-after-send?])
(on-receieve [ch callback])
(on-close [ch callback])

See org.httpkit.timer ns for optional timeout facilities."
[request ch-name & body]
`(let [^AsyncChannel ~ch-name (:async-channel ~request)]
(if (:websocket? ~request)
(if-let [key# (get-in ~request [:headers "sec-websocket-key"])]
(do (.sendHandshake ~ch-name {"Upgrade" "websocket"
"Connection" "Upgrade"
"Sec-WebSocket-Accept" (accept key#)})
~@body
{:body ~ch-name})
{:status 400 :body "Bad Sec-WebSocket-Key header"}))
(do ~@body
{:body ~ch-name})))
```

-----

Could you please remind me what I need to do to get the unit tests to run? I can't find the instructions in my email now.