Skip to content

Instantly share code, notes, and snippets.

@grav
Last active December 13, 2017 22:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grav/1d9ea8d5cf08f014999273be3db6dfa5 to your computer and use it in GitHub Desktop.
Save grav/1d9ea8d5cf08f014999273be3db6dfa5 to your computer and use it in GitHub Desktop.
(ns xhr-client
(:refer-clojure :exclude [get])
(:require [httpurr.protocols]
[clojure.string :as str]
[httpurr.protocols :as p]
[httpurr.client :as c]))
(defn normalize-headers
[headers]
(reduce-kv (fn [acc k v]
(assoc acc (str/lower-case k) v))
{} headers))
(defn- parse-header-string [hs]
(->> hs
clojure.string/split-lines
(map #(clojure.string/split % ": "))
(into {})))
(deftype Xhr [xhr]
p/Request
(-listen [_ cb]
(set! (.-onreadystatechange xhr)
(fn []
(when (= (.-readyState xhr)
js/XMLHttpRequest.DONE)
(cb (Xhr. xhr))))))
p/Response
(-success? [_]
(#{200 201 202 204 206 304 1223} (.-status xhr)))
(-response [_]
{:status (.-status xhr)
:body (.-response xhr)
:headers (-> (.getAllResponseHeaders xhr)
parse-header-string
(normalize-headers))})
(-error [this]
(ex-info "Error" {:status (.-status xhr)
:status-text (.-statusText xhr)
:body (.-response xhr)
:headers (-> (.getAllResponseHeaders xhr)
parse-header-string
(normalize-headers))})))
(defn- make-uri
[url qs qp]
(prn "WARN: ignoring query params! and we prolly need to escape something!")
(str url (when qs (str "?" qs))))
(def client
(reify p/Client
(-send [_ request options]
(let [{:keys [timeout with-credentials?] :or {timeout 0 with-credentials? false}} options
{:keys [method url query-string query-params headers body]} request
uri (make-uri url query-string query-params)
method (c/keyword->method method)
xhr (js/XMLHttpRequest.)]
(.open xhr method uri)
(set! (.-timeout xhr) timeout)
(set! (.-withCredentials xhr) with-credentials?)
(doseq [[k v] headers]
(.setRequestHeader xhr k v))
(.send xhr body)
(Xhr. xhr)))))
(def send! (partial c/send! client))
(def head (partial (c/method :head) client))
(def options (partial (c/method :options) client))
(def get (partial (c/method :get) client))
(def post (partial (c/method :post) client))
(def put (partial (c/method :put) client))
(def patch (partial (c/method :patch) client))
(def delete (partial (c/method :delete) client))
(def trace (partial (c/method :trace) client))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment