diff --git a/srv/content/router.hy b/srv/content/router.hy index 85c82b8..8c23a4e 100644 --- a/srv/content/router.hy +++ b/srv/content/router.hy @@ -45,15 +45,14 @@ (return (get @route-map route))) - (meth [lru-cache] get-route-by-path [path] + (meth get-route-by-path [path] (cond (in path @route-map) (do (get @route-map path)) True (do (while (> (.count path "/") 1) (setv path (.join "/" (get (.split path "/") (slice 0 -1)))) (when (in (+ path "/*") @route-map) - (setv handler (get @route-map (+ path "/*"))) - (return handler))) + (return (get @route-map (+ path "/*"))))) (always (fn [#* _] (error 404 "not-found)"))))))) diff --git a/srv/http_utils/response.hy b/srv/http_utils/response.hy index 5aa705d..7013449 100644 --- a/srv/http_utils/response.hy +++ b/srv/http_utils/response.hy @@ -7,20 +7,23 @@ (.encode (+ (.join "\r\n" (lfor [k v] (.items headers) f"{k}: {v}")) "\r\n\r\n") "utf-8")) (defn send-body [body] - (cond - (isinstance body bytes) body - (isinstance body str) (.encode body "utf-8"))) + body) (defn send [[code 200] [headers None] [body ""]] (when (is headers None) (setv headers {})) (assoc headers "WHAT...-your-trans-gener..." "that is so cool...") + (assoc headers "Connection" "keep-alive") (when (not-in "Content-Type" headers) (assoc headers "Content-Type" "text/html")) + (setv body (cond + (isinstance body bytes) body + (isinstance body str) (.encode body "utf-8"))) + (+ (send-code code) - (send-headers headers) + (send-headers (dict #** headers #** {"Content-Length" (len body)})) (send-body body))) diff --git a/srv/main.hy b/srv/main.hy index cd610f2..16b9a8d 100644 --- a/srv/main.hy +++ b/srv/main.hy @@ -12,6 +12,42 @@ (except [ModuleNotFoundError] (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 [] (let [socket (socket AF_INET SOCK_STREAM)] (try @@ -24,27 +60,7 @@ (try (.start (Thread - :target (fn [client-socket address] - (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)))) - + :target handle-connection :args #(#* (socket.accept)))) (except [e Exception]