application/octet-stream
•
1.88 KB
•
48 lines
(defn http/get* (host path)
(def req (fmt "GET {path} HTTP/1.0\r\n\r\n"))
(def buf (buffer/allocate 0))
(def fh (socket/connect host 80))
(file/write* fh req (:length req))
(file/flush* fh)
(def bytes-read 0)
(def bytes-read-now 1)
(while (not (zero? bytes-read-now))
(:length! buf (+ 65536 (:length buf)))
(set! bytes-read-now (file/read* fh buf 65536 bytes-read))
(set! bytes-read (+ bytes-read bytes-read-now)))
(file/close* fh)
(def raw-res (buffer->string buf bytes-read))
(def eosl (:index-of raw-res "\r\n"))
(when (< eosl 0) (return #nil))
(def eoh (:index-of raw-res "\r\n\r\n"))
(when (< eoh 0) (return #nil))
(def status-line (buffer->string buf eosl))
(def status-list (split status-line " "))
(def headers {})
(def header-raw (buffer->string buf eoh (+ 2 eosl)))
(def header-lines (split header-raw "\r\n"))
(doseq (header header-lines)
(def eok (:index-of header ":"))
(when (>= eok 0)
(def key (string->keyword (:cut header 0 eok)))
(def v (trim (:cut header (inc eok))))
(set! headers key v)))
(def body (:cut buf (+ 4 eoh)))
{ :http-version (car status-list)
:status-code (read/int (cadr status-list))
:status-message (join (cddr status-list) " ")
:headers headers
:body body})
(defn http/get (url)
(when (>= (:index-of url "https://") 0)
(error "https is unsupported right now"))
(when (>= (:index-of url "http://") 0)
(set! url (:cut url 7))
(def path-start (:index-of url "/"))
(return (if (>= path-start 0)
(http/get* (:cut url 0 path-start)
(:cut url path-start))
(http/get* url "/"))))
(error "unsupported scheme"))