Created
April 1, 2016 07:03
-
-
Save ykomatsu/6f6390d9269b29689a260a3ba3af65ac to your computer and use it in GitHub Desktop.
Node.js + ClojureScript Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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