Files
natalieee.net/srv/main.hy

75 lines
2.0 KiB
Hy

(import socket [socket AF_INET SOCK_STREAM SOL_SOCKET SO_REUSEADDR])
(import threading [Thread])
(import log [log])
(import traceback [format-exc])
(import http-utils :as http)
(import content.router [match-request])
(require hyrule.control [defmain])
(try
(import srv-config [ADDRESS PORT])
(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
(.setsockopt socket SOL_SOCKET SO_REUSEADDR 1)
(.bind socket #(ADDRESS PORT))
(.listen socket 10)
(.debug log "socket bound")
(while True
(try
(.start
(Thread
:target handle-connection
:args #(#* (socket.accept))))
(except [e Exception]
(.warn log (format-exc)))))
(except [e Exception]
(.critical log (format-exc)))
(finally
(.close socket)
(.info log "server shut down")))))