Migrate from Ring Jetty adapter

HTTP Kit is an almost drop-in replacement for the standard Ring Jetty adapter, just replace run-jetty with run-server.

Few differences:

Stop server programmatically

(let [jetty (run-jetty app options)]
  (.stop jetty))

(let [server (run-server app options)]
  ;; run-server returns a function that stops the server
  (server))
  

Configuring HTTPS

http-kit relies on reverse proxy (like Nginx, Lighthttpd) to support HTTPS. They also can be used as a reverse proxy to serve static files and compress content.

Stud is another option. It works well with websockets and long polling.

Sample configration for Nginx:

server {
    listen 443 ssl;

    ssl on;
    ssl_certificate /etc/nginx/ssl/xxxxx_ssl.crt;
    ssl_certificate_key /etc/nginx/ssl/xxxx_ssl.key.nopasswd;

     location / {
        # http-kit listens on port 9090
        proxy_pass  http://127.0.0.1:9090/;
        proxy_set_header Host $http_host;
    }
}
  

Hot code reload (lein ring server)

Hot code reload is very handy, with the Jetty one you can do something like:

lein ring server  # https://github.com/weavejester/lein-ring
    

lein-ring does not yet support http-kit, but ring.middleware.reload can be used as a workaround.

lein run # start a server in :8080, hot code reload
;; project.clj
(defproject xxxx "1.0.1"
  :dependencies [[org.clojure/clojure "1.4.0"]
                 [compojure "1.1.5"]
                 [ring/ring-devel "1.1.8"]
                 [ring/ring-core "1.1.8"]
                 [http-kit "2.0.0"]]
  ; allow lein run to find a place to start
  :main clj_web.main)

;; src/clj_web/main.clj
(ns clj_web.main
  (:use [org.httpkit.server :only [run-server]])
  (:require [ring.middleware.reload :as reload]
            [compojure.handler :refer [site]]
            [compojure.core :refer [defroutes GET POST]]))

(defroutes all-routes
  (GET "/" [] "handling-page")
  (GET "/save" [] handler)     ;; websocket
  (route/not-found "<p>Page not found.</p>")) ;; all other, return 404

(defn in-dev? true) ;; TODO read a config variable from command line, env, or file?

(defn -main [& args] ;; entry point, lein run will pick up and start from here
  (let [handler (if (in-dev? args)
                  (reload/wrap-reload (site #'all-routes)) ;; only reload when dev
                  (site all-routes))]
    (run-server handler {:port 8080})))