support Connection: keep-alive; misc performance improvements

This commit is contained in:
2025-06-29 04:41:24 -07:00
parent 842719b102
commit cf43fef106
3 changed files with 46 additions and 28 deletions

View File

@ -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)")))))))

View File

@ -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)))

View File

@ -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]