Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b10592e

Browse files
committed
add J11 native http/send
1 parent 497b44e commit b10592e

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

src/sentry_tiny/impl/http.clj

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
(ns sentry-tiny.impl.http
2+
(:require [clojure.string :as str])
3+
(:import (java.net.http HttpRequest
4+
HttpResponse
5+
HttpClient
6+
HttpClient$Version
7+
HttpRequest$Builder
8+
HttpRequest$BodyPublishers
9+
HttpResponse$BodyHandlers)
10+
(java.util.function Supplier)
11+
(java.time Duration)
12+
(java.net URI)
13+
(java.io InputStream)))
14+
15+
(def ^:private ^HttpClient default-client
16+
(delay (HttpClient/newHttpClient)))
17+
18+
(def ^:private bh->string (HttpResponse$BodyHandlers/ofString))
19+
(def ^:private bh->istream (HttpResponse$BodyHandlers/ofInputStream))
20+
(def ^:private bh->bytes (HttpResponse$BodyHandlers/ofByteArray))
21+
22+
(def ^:private convert-headers-xf
23+
(mapcat
24+
(fn [[k v :as p]]
25+
(if (sequential? v)
26+
(interleave (repeat k) v)
27+
p))))
28+
29+
(def ^:private bytes-class
30+
(Class/forName "[B"))
31+
32+
(defn- convert-body-handler [mode]
33+
(case mode
34+
nil bh->string
35+
:string bh->string
36+
:input-stream bh->istream
37+
:byte-array bh->bytes))
38+
39+
(defn- version-enum->version-keyword [^HttpClient$Version version]
40+
(case (.name version)
41+
"HTTP_1_1" :http1.1
42+
"HTTP_2" :http2))
43+
44+
(defn- version-keyword->version-enum [version]
45+
(case version
46+
:http1.1 HttpClient$Version/HTTP_1_1
47+
:http2 HttpClient$Version/HTTP_2))
48+
49+
(defn- method-keyword->str [method]
50+
(str/upper-case (name method)))
51+
52+
(defn- convert-timeout [t]
53+
(if (integer? t)
54+
(Duration/ofMillis t)
55+
t))
56+
57+
(defn- input-stream-supplier [s]
58+
(reify Supplier
59+
(get [this] s)))
60+
61+
(defn- convert-body-publisher [body]
62+
(cond
63+
(nil? body)
64+
(HttpRequest$BodyPublishers/noBody)
65+
66+
(string? body)
67+
(HttpRequest$BodyPublishers/ofString body)
68+
69+
(instance? InputStream body)
70+
(HttpRequest$BodyPublishers/ofInputStream (input-stream-supplier body))
71+
72+
(instance? bytes-class body)
73+
(HttpRequest$BodyPublishers/ofByteArray body)))
74+
75+
(defn request-builder ^HttpRequest$Builder [opts]
76+
(let [{:keys [expect-continue?
77+
headers
78+
method
79+
timeout
80+
uri
81+
version
82+
body]} opts]
83+
(cond-> (HttpRequest/newBuilder)
84+
(some? expect-continue?) (.expectContinue expect-continue?)
85+
(seq headers) (.headers (into-array String (eduction convert-headers-xf headers)))
86+
method (.method (method-keyword->str method) (convert-body-publisher body))
87+
timeout (.timeout (convert-timeout timeout))
88+
uri (.uri (URI/create uri))
89+
version (.version (version-keyword->version-enum version)))))
90+
91+
(defn- build-request
92+
(^HttpRequest [] (.build (request-builder {})))
93+
(^HttpRequest [req-map] (.build (request-builder req-map))))
94+
95+
(defn- response->map [^HttpResponse resp]
96+
{:status (.statusCode resp)
97+
:body (.body resp)
98+
:version (-> resp .version version-enum->version-keyword)
99+
:headers (into {}
100+
(map (fn [[k v]] [k (if (> (count v) 1) (vec v) (first v))]))
101+
(.map (.headers resp)))})
102+
103+
(defn- convert-request [req]
104+
(cond
105+
(map? req) (build-request req)
106+
(string? req) (build-request {:uri req})
107+
(instance? HttpRequest req) req))
108+
109+
(defn send
110+
([req]
111+
(send req {}))
112+
([req {:keys [as client raw?] :as opts}]
113+
(let [^HttpClient client (or client @default-client)
114+
req' (convert-request req)
115+
resp (.send client req' (convert-body-handler as))]
116+
(if raw? resp (response->map resp)))))

0 commit comments

Comments
 (0)