Skip to content

Instantly share code, notes, and snippets.

@ykomatsu
Created April 1, 2016 07:03
Show Gist options
  • Save ykomatsu/6f6390d9269b29689a260a3ba3af65ac to your computer and use it in GitHub Desktop.
Save ykomatsu/6f6390d9269b29689a260a3ba3af65ac to your computer and use it in GitHub Desktop.
Node.js + ClojureScript Example
(ns hello.core
(:require [cljs.nodejs :as nodejs]
[clojure.string :as string]
[cljs.core.async :refer [<! chan put!]])
(:require-macros [cljs.core.async.macros :refer [go]]))
(def http (nodejs/require "http"))
(def url (nodejs/require "url"))
(defn join-chunk
[a b]
(let [b (if (.isBuffer js/Buffer b)
b
(js/Buffer. b))]
(.concat js/Buffer #js [a b])))
(defn parse-host
[host]
(if-let [parsed-host (re-find #"^([^:]+):(\d+)$" host)]
[(parsed-host 1) (parsed-host 2)]
[host nil]))
(defn xlate-request
[req req-body]
(let [[sn sp] (parse-host (.. req -headers -host))
parsed-url (.parse url (.-url req))
xlated-req (atom {:server-port (if sp
(js/parseInt sp)
(.. req -socket -localPort))
:server-name sn
:remote-addr (.. req -socket -remoteAddress)
:uri (.-pathname parsed-url)
:scheme :http
:request-method (keyword (string/lower-case
(.-method req)))
:protocol (str "HTTP/" (.-httpVersion req))
:headers (js->clj (.-headers req)
:keywordize-keys true)})]
(when-let [qs (.-query parsed-url)]
(swap! xlated-req assoc :query-string qs))
(when (.. req -socket -getPeerCertificate)
(swap! xlated-req
assoc
:ssl-client-cert
(.. req -socket getPeerCertificate -raw)))
(when (not= (.-length req-body) 0)
(swap! xlated-req assoc :body req-body))
@xlated-req))
(defn xlate-handler
[handler]
(fn [req res]
(let [req-body (atom (js/Buffer. ""))
next-ch (chan)]
(.on req "data" #(swap! req-body join-chunk %))
(.on req "end" #(put! next-ch :end))
(go
(<! next-ch)
(let [{:keys [status headers body]} (handler
(xlate-request req @req-body))]
(.writeHead res status (clj->js headers))
(when body
(.write res body))
(.end res))))))
(defn hello
[req]
(.log js/console (str req))
{:status 200
:headers {:content-type "text/plain"}
:body "Hello, ClojureScript!\n"})
(defn -main
[]
(.listen (.createServer http (xlate-handler hello)) 8080))
(set! *main-cli-fn* -main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment