52 lines
1.8 KiB
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)))))))
|