Current section
Files
Jump to
Current section
Files
src/http.request.lfe
(defmodule http.request
(export
(new 1) (new 2) (new 3) (new 4)
(->list 1)
(->erlang 1) (->erlang 3)))
(defun new
((url) (when (is_list url))
(new (list_to_binary url)))
((url)
(let ((parsed-url (yuri:parse url)))
`#m(method get
version ,(http:default-version)
remote-addr #""
headers ,(http:default-headers)
body #""
url ,url
url-parsed ,(maps:merge parsed-url (yuri.user:parse parsed-url))
path-segments ()
query-parsed #m()))))
(defun new (method url)
(new method url #""))
(defun new (method url body)
(new method url body (http:default-headers)))
(defun new (method url body headers)
(let* ((init (new url))
(url (mref init 'url-parsed)))
(maps:merge init
`#m(method ,method
body ,body
headers ,headers
path-segments ,(yuri.path:->segments (mref url 'path))
query-parsed ,(yuri.query:parse (mref url 'query))))))
(defun ->list (req)
(let* ((h (maps:get 'headers req #m()))
(q (maps:get 'query-parsed req #m()))
(u (maps:get 'url-parsed req #m()))
(req2 (maps:merge req `#m(headers ,(lists:sort (maps:to_list h))
query-parsed ,(lists:sort (maps:to_list q))
url-parsed ,(lists:sort (maps:to_list u))))))
(lists:sort (maps:to_list req2))))
(defun ->erlang (req)
"Convert an LFE HTTP library request to args that can be supplied to Erlang's
`httpc:request/4` function."
(->erlang
req
`(#(version ,(http-version req))) ; default `HttpOptions`
`(#(sync true) #(full_result true)) ; default `Options`
))
(defun ->erlang (req http-options options)
(->erlang (mref req 'method) req http-options options))
;; Private functions
(defun ->erlang
;; Without body
(('delete req http-options options)
(->erlang-no-body 'delete req http-options options))
(('get req http-options options)
(->erlang-no-body 'get req http-options options))
(('head req http-options options)
(->erlang-no-body 'head req http-options options))
(('options req http-options options)
(->erlang-no-body 'options req http-options options))
(('trace req http-options options)
(->erlang-no-body 'trace req http-options options))
;; With body
(('patch req http-options options)
(->erlang-with-body 'patch req http-options options))
(('post req http-options options)
(->erlang-with-body 'post req http-options options))
(('put req http-options options)
(->erlang-with-body 'put req http-options options)))
(defun ->erlang-no-body (method req http-options options)
(let ((headers (mref req 'headers)))
(list
method
`#(,(mref req 'url)
,(maps:to_list headers))
http-options
options)))
(defun ->erlang-with-body (method req http-options options)
(let ((headers (mref req 'headers)))
(list
method
`#(,(mref req 'url)
,(maps:to_list headers)
,(binary_to_list (maps:get #"Content-Type" headers (http.mimetype:text/html)))
,(mref req 'body))
http-options
(lists:append options '(#(body_format binary))))))
(defun http-version (req)
(io_lib:format "HTTP/~p" (list (mref req 'version))))