Files
natalieee.net/srv/main.hy

52 lines
1.8 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])
(import asyncio)
(import concurrent.futures [ThreadPoolExecutor])
(require hyrule.control [defmain])
(require hyrule.oop [meth])
(setv data-handler-threadpool (ThreadPoolExecutor))
(defclass http-server-protocol [asyncio.Protocol]
(meth connection-made [@transport])
(meth data-received [data]
(setv loop (asyncio.get-running-loop))
(loop.run-in-executor data-handler-threadpool (fn []
(setv thread-loop (asyncio.new-event-loop))
(asyncio.set-event-loop thread-loop)
(setv parsed-request (http.request.parse-data 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 (.get-extra-info @transport "peername") 1))) f": {(. parsed-request (get "method"))} {(. parsed-request (get "route") (get "path"))}"))
(setv response-task (asyncio.ensure-future (match-request parsed-request)))
(. response-task (add-done-callback (fn [future]
(.write @transport (http.response.send #** (future.result)))
(when (= (. parsed-request (get "headers") (get "Connection")) "close")
(@transport.close)))))
(thread-loop.run-until-complete response-task)))))
(try
(import srv-config [ADDRESS PORT])
(except [ModuleNotFoundError]
(setv [ADDRESS PORT] ["127.0.0.1" 5000])))
(defmain []
(asyncio.run ((fn :async []
(setv loop (asyncio.get-running-loop))
(with [:async server (await (loop.create-server
http-server-protocol ADDRESS PORT))]
(await (server.serve-forever)))))))