server.fnl (2121B)
1 (local new-headers (. (require :http.headers) :new)) 2 (local http-server (require :http.server)) 3 (local http-util (require :http.util)) 4 (local http-version (require :http.version)) 5 (local ce (require :cqueues.errno)) 6 7 (local { : view } (require :fennel)) 8 9 (fn headers [stream more-headers finished?] 10 (let [headers 11 (doto (new-headers) 12 (: :append ":status" "200") 13 (: :append :content-type "text/html; charset=utf8") 14 (: :append :server (string.format "%s/%s" http-version.name http-version.version)) 15 (: :append :date (http-util.imf_date)))] 16 (each [name value (pairs more-headers)] 17 (headers:upsert name value)) 18 (stream:write_headers headers (not (not finished?))))) 19 20 (fn new [options] 21 (let [defaults 22 {:host :localhost 23 :max_concurrent 100 24 :onerror (fn [myserver context op err errno] 25 (let [msg 26 (.. op " on " 27 (tostring context) 28 " failed" 29 (and err 30 (.. ": " 31 (tostring err))))] 32 (assert (io.stderr:write msg "\n")))) 33 :port 3003} 34 params (collect [k v (pairs options) &into defaults] 35 (values k v)) 36 server 37 (doto 38 (http-server.listen params) 39 (: :listen)) 40 (_family address port) (server:localname)] 41 (print :listening-on address port) 42 (values server address port))) 43 44 (fn log-request [req-headers stream] 45 (assert (io.stdout:write 46 (string.format "[%s] \"%s %s HTTP/%g\" \"%s\" \"%s\"\n" 47 (os.date "%d/%b/%Y:%H:%M:%S %z") 48 (or (req-headers:get ":method") "") 49 (or (req-headers:get ":path") "") 50 stream.connection.version 51 (or (req-headers:get :referer) "-") 52 (or (req-headers:get :user-agent) 53 "-"))))) 54 { : new : headers : log-request }