Files
natalieee.net/srv/http_utils/request.hy
2025-05-07 17:13:30 -07:00

58 lines
2.0 KiB
Hy

(import hyrule.collections [assoc])
(require hyrule.control [branch])
(require hyrule.argmove [doto])
(require hyrule.collections :readers [s])
(import urllib.parse [urlsplit unquote-plus parse-qs])
(defn parse-url-encoded [query]
(dfor pair (.items (parse-qs (unquote-plus query) :keep-blank-values True))
(get pair 0)
(cond
(get pair 1 0) (get pair 1 0)
True "")))
(defn parse-data [data]
(setv request {})
(setv [head #* body] (.split data b"\r\n\r\n"))
(setv [request-line #* headers] (.split head b"\r\n"))
(setv [http-method route http-version] (.split (.decode request-line "utf-8") " "))
(doto request
(assoc :method http-method)
(assoc :route (let
[[_ _ path query _] (urlsplit route)]
(dict
:path (.join "/"
(do
(setv segments [])
(for [segment (.split (unquote-plus path) "/")]
(cond
(!= segment "..") (.append segments segment)
(and segments (!= (get segments -1) "..")) (.pop segments)))
segments))
:parameters (parse-url-encoded query))))
(assoc :version http-version)
(assoc :headers (dict
(dfor header
(map (fn [x]
(.split (.decode x "utf-8") ": ")) headers)
(get header 0)
(get header 1))))
(assoc :body (branch (in it (. request (get "headers") (get "Content-Type" "")))
"application/x-www-form-urlencoded" (parse-url-encoded (.decode (.join b"\n" body) "utf-8"))
"" ""
;;"multipart/form-data" ;(do
;; (setv content-type-header (. request (get "headers") (get "Content-Type")))
;; (when (in "=" content-type-header) (do
;; (setv boundary (get (.split content-type-header "=") -1))
;; (print "boundary" boundary)
;; (print (.split (.join b"\n" body) (.encode boundary "utf-8"))))))
else (raise (NotImplementedError f"{(get (.split (. request (get "headers") (get "Content-Type")) ";") 0)} parsing is TODO"))))))