support Connection: keep-alive; misc performance improvements
This commit is contained in:
@ -45,15 +45,14 @@
|
|||||||
|
|
||||||
(return (get @route-map route)))
|
(return (get @route-map route)))
|
||||||
|
|
||||||
(meth [lru-cache] get-route-by-path [path]
|
(meth get-route-by-path [path]
|
||||||
(cond
|
(cond
|
||||||
(in path @route-map) (do (get @route-map path))
|
(in path @route-map) (do (get @route-map path))
|
||||||
True (do
|
True (do
|
||||||
(while (> (.count path "/") 1)
|
(while (> (.count path "/") 1)
|
||||||
(setv path (.join "/" (get (.split path "/") (slice 0 -1))))
|
(setv path (.join "/" (get (.split path "/") (slice 0 -1))))
|
||||||
(when (in (+ path "/*") @route-map)
|
(when (in (+ path "/*") @route-map)
|
||||||
(setv handler (get @route-map (+ path "/*")))
|
(return (get @route-map (+ path "/*")))))
|
||||||
(return handler)))
|
|
||||||
|
|
||||||
(always (fn [#* _] (error 404 "not-found)")))))))
|
(always (fn [#* _] (error 404 "not-found)")))))))
|
||||||
|
|
||||||
|
@ -7,20 +7,23 @@
|
|||||||
(.encode (+ (.join "\r\n" (lfor [k v] (.items headers) f"{k}: {v}")) "\r\n\r\n") "utf-8"))
|
(.encode (+ (.join "\r\n" (lfor [k v] (.items headers) f"{k}: {v}")) "\r\n\r\n") "utf-8"))
|
||||||
|
|
||||||
(defn send-body [body]
|
(defn send-body [body]
|
||||||
(cond
|
body)
|
||||||
(isinstance body bytes) body
|
|
||||||
(isinstance body str) (.encode body "utf-8")))
|
|
||||||
|
|
||||||
(defn send [[code 200] [headers None] [body ""]]
|
(defn send [[code 200] [headers None] [body ""]]
|
||||||
(when (is headers None)
|
(when (is headers None)
|
||||||
(setv headers {}))
|
(setv headers {}))
|
||||||
|
|
||||||
(assoc headers "WHAT...-your-trans-gener..." "that is so cool...")
|
(assoc headers "WHAT...-your-trans-gener..." "that is so cool...")
|
||||||
|
(assoc headers "Connection" "keep-alive")
|
||||||
|
|
||||||
(when (not-in "Content-Type" headers)
|
(when (not-in "Content-Type" headers)
|
||||||
(assoc headers "Content-Type" "text/html"))
|
(assoc headers "Content-Type" "text/html"))
|
||||||
|
|
||||||
|
(setv body (cond
|
||||||
|
(isinstance body bytes) body
|
||||||
|
(isinstance body str) (.encode body "utf-8")))
|
||||||
|
|
||||||
(+
|
(+
|
||||||
(send-code code)
|
(send-code code)
|
||||||
(send-headers headers)
|
(send-headers (dict #** headers #** {"Content-Length" (len body)}))
|
||||||
(send-body body)))
|
(send-body body)))
|
||||||
|
58
srv/main.hy
58
srv/main.hy
@ -12,6 +12,42 @@
|
|||||||
(except [ModuleNotFoundError]
|
(except [ModuleNotFoundError]
|
||||||
(setv [ADDRESS PORT] ["127.0.0.1" 5000])))
|
(setv [ADDRESS PORT] ["127.0.0.1" 5000])))
|
||||||
|
|
||||||
|
(defn handle-connection [client-socket address]
|
||||||
|
(try
|
||||||
|
(.settimeout client-socket 10)
|
||||||
|
|
||||||
|
(setv request-data (bytes))
|
||||||
|
(while (setx data (.recv client-socket 1024))
|
||||||
|
(+= request-data data)
|
||||||
|
(when (< (len data) 1024)
|
||||||
|
(break)))
|
||||||
|
|
||||||
|
(when request-data
|
||||||
|
(setv parsed-request (http.request.parse-data request-data))
|
||||||
|
(.debug log parsed-request)
|
||||||
|
(.info log (+ (str (cond
|
||||||
|
(in "X-Real-IP" (. parsed-request (get "headers"))) (. parsed-request (get "headers") (get "X-Real-IP"))
|
||||||
|
True (get address 0))) f": {(. parsed-request (get "method"))} {(. parsed-request (get "route") (get "path"))}"))
|
||||||
|
|
||||||
|
(when (!= (. parsed-request (get "headers") (get "Connection")) "close")
|
||||||
|
(.start (Thread
|
||||||
|
:target handle-connection
|
||||||
|
:args #((.dup client-socket) address))))
|
||||||
|
|
||||||
|
(setv response (match-request parsed-request))
|
||||||
|
(.sendall client-socket (http.response.send #** response)))
|
||||||
|
|
||||||
|
|
||||||
|
(except [e TimeoutError]
|
||||||
|
...)
|
||||||
|
|
||||||
|
(except [e Exception]
|
||||||
|
(.warn log (format-exc)))
|
||||||
|
|
||||||
|
(finally
|
||||||
|
(.close client-socket)
|
||||||
|
(return))))
|
||||||
|
|
||||||
(defmain []
|
(defmain []
|
||||||
(let [socket (socket AF_INET SOCK_STREAM)]
|
(let [socket (socket AF_INET SOCK_STREAM)]
|
||||||
(try
|
(try
|
||||||
@ -24,27 +60,7 @@
|
|||||||
(try
|
(try
|
||||||
(.start
|
(.start
|
||||||
(Thread
|
(Thread
|
||||||
:target (fn [client-socket address]
|
:target handle-connection
|
||||||
(try
|
|
||||||
(setv request-data (bytes))
|
|
||||||
(while (setx data (.recv client-socket 1024))
|
|
||||||
(+= request-data data)
|
|
||||||
(when (< (len data) 1024)
|
|
||||||
(break)))
|
|
||||||
|
|
||||||
(setv parsed-request (http.request.parse-data request-data))
|
|
||||||
(.debug log parsed-request)
|
|
||||||
(.info log (+ (str (cond
|
|
||||||
(in "X-Real-IP" (. parsed-request (get "headers"))) (. parsed-request (get "headers") (get "X-Real-IP"))
|
|
||||||
True (get address 0))) f": {(. parsed-request (get "method"))} {(. parsed-request (get "route") (get "path"))}"))
|
|
||||||
|
|
||||||
(setv response (match-request parsed-request))
|
|
||||||
(.sendall client-socket (http.response.send #** response))
|
|
||||||
|
|
||||||
(except [e Exception]
|
|
||||||
(.warn log (format-exc))
|
|
||||||
(.close client-socket))))
|
|
||||||
|
|
||||||
:args #(#* (socket.accept))))
|
:args #(#* (socket.accept))))
|
||||||
|
|
||||||
(except [e Exception]
|
(except [e Exception]
|
||||||
|
Reference in New Issue
Block a user