58 lines
2.0 KiB
Hy
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"))))))
|
|
|