Blame


1 1d126b15 2021-10-13 op (ns gemini.core
2 1d126b15 2021-10-13 op (:require
3 1d126b15 2021-10-13 op [clojure.java.io :as io])
4 5243b9ac 2021-10-13 op (:import
5 5243b9ac 2021-10-13 op (com.omarpolo.gemini Request)))
6 1d126b15 2021-10-13 op
7 1d126b15 2021-10-13 op (defmacro ^:private request->map [& args]
8 1d126b15 2021-10-13 op `(try
9 1d126b15 2021-10-13 op (let [req# (Request. ~@args)]
10 1d126b15 2021-10-13 op {:request req#
11 1d126b15 2021-10-13 op :code (.getCode req#)
12 1d126b15 2021-10-13 op :meta (.getMeta req#)
13 1d126b15 2021-10-13 op :body (.body req#)})
14 1d126b15 2021-10-13 op (catch Throwable e#
15 1d126b15 2021-10-13 op {:error e#})))
16 1d126b15 2021-10-13 op
17 1d126b15 2021-10-13 op (defn fetch
18 1d126b15 2021-10-13 op "Make a gemini request. `uri` may be a URI, URL or string, and
19 1d126b15 2021-10-13 op represent the request to perform. `host` and `port` are extracted
20 1d126b15 2021-10-13 op from the given `uri` in not given, and port defaults to 1965. The
21 1ef4128a 2021-10-13 op returned request needs to be closed when done."
22 1d126b15 2021-10-13 op ([uri]
23 1d126b15 2021-10-13 op (request->map uri))
24 1d126b15 2021-10-13 op ([host uri]
25 1d126b15 2021-10-13 op (fetch host 1965 uri))
26 1d126b15 2021-10-13 op ([host port uri]
27 1d126b15 2021-10-13 op (request->map host port uri)))
28 1d126b15 2021-10-13 op
29 5243b9ac 2021-10-13 op (defn body-as-string!
30 1d126b15 2021-10-13 op "Read all the response into a strings and returns it. The request
31 1d126b15 2021-10-13 op will be closed."
32 5243b9ac 2021-10-13 op [{r :request}]
33 1d126b15 2021-10-13 op (let [sw (java.io.StringWriter.)]
34 1d126b15 2021-10-13 op (with-open [r r]
35 1d126b15 2021-10-13 op (io/copy (.body r) sw)
36 1d126b15 2021-10-13 op (.toString sw))))
37 1d126b15 2021-10-13 op
38 5243b9ac 2021-10-13 op (defn close
39 5243b9ac 2021-10-13 op "Close a request."
40 5243b9ac 2021-10-13 op [{r :request}]
41 1d126b15 2021-10-13 op (.close r))
42 1d126b15 2021-10-13 op
43 5243b9ac 2021-10-13 op (defmacro with-request
44 1d126b15 2021-10-13 op "Make a request, eval `body` when it succeed and automatically close
45 5243b9ac 2021-10-13 op the request, or throw an exception if the request fails."
46 5243b9ac 2021-10-13 op [[var req] & body]
47 53bc5bb6 2021-10-13 op `(let [~var ~req]
48 53bc5bb6 2021-10-13 op (when-let [e# (:error ~var)]
49 1d126b15 2021-10-13 op (throw e#))
50 53bc5bb6 2021-10-13 op (with-open [req# (:request ~var)]
51 1d126b15 2021-10-13 op ~@body)))
52 1d126b15 2021-10-13 op
53 1d126b15 2021-10-13 op
54 1d126b15 2021-10-13 op ;; helpers
55 1d126b15 2021-10-13 op
56 1d126b15 2021-10-13 op (def code-description
57 1d126b15 2021-10-13 op "Human description for every response code."
58 1d126b15 2021-10-13 op {10 "input"
59 1d126b15 2021-10-13 op 11 "sensitive input"
60 1d126b15 2021-10-13 op 20 "success"
61 1d126b15 2021-10-13 op 30 "temporary redirect"
62 1d126b15 2021-10-13 op 31 "permanent redirect"
63 1d126b15 2021-10-13 op 40 "temporary failure"
64 1d126b15 2021-10-13 op 41 "server unavailable"
65 1d126b15 2021-10-13 op 42 "CGI error"
66 1d126b15 2021-10-13 op 43 "proxy error"
67 1d126b15 2021-10-13 op 44 "slow down"
68 1d126b15 2021-10-13 op 50 "permanent failure"
69 1d126b15 2021-10-13 op 51 "not found"
70 1d126b15 2021-10-13 op 52 "gone"
71 1d126b15 2021-10-13 op 53 "proxy request refused"
72 1d126b15 2021-10-13 op 59 "bad request"
73 1d126b15 2021-10-13 op 60 "client certificate required"
74 1d126b15 2021-10-13 op 61 "certificate not authorized"
75 1d126b15 2021-10-13 op 62 "certificate not valid"})
76 1d126b15 2021-10-13 op
77 1d126b15 2021-10-13 op (defn is-input? [{c :code}] (= 1 (/ c 10)))
78 1d126b15 2021-10-13 op (defn is-success? [{c :code}] (= 2 (/ c 10)))
79 1d126b15 2021-10-13 op (defn is-redirect? [{c :code}] (= 3 (/ c 10)))
80 1d126b15 2021-10-13 op (defn is-temporary-failure? [{c :code}] (= 4 (/ c 10)))
81 1d126b15 2021-10-13 op (defn is-permanent-failure? [{c :code}] (= 5 (/ c 10)))
82 1d126b15 2021-10-13 op (defn is-client-cert-required? [{c :code}] (= 6 (/ c 10)))