/
http.clj
68 lines (64 loc) · 2.32 KB
/
http.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
(ns ancient-clj.io.http
(:require [ancient-clj.io.xml :as xml]
[clj-http.client :as http]))
(def ^:private error-messages
{401 "authorization needed."
403 "access forbidden."
500 "server error."
502 "upstream server error."
503 "server unavailable."
504 "server timeout."})
(def ^:private valid-content-types
#{"text/xml" "application/xml"})
(defn- base-opts
[]
(let [timeout (if-let [v (System/getenv "http_timeout")]
(if (not= v "0")
(Long/parseLong v)
(* 60 60 1000))
(if (some
#(System/getenv %)
["http_proxy" "https_proxy"])
30000
5000))]
{:socket-timeout timeout
:conn-timeout timeout
:throw-exceptions false
:as :text}))
(defn http-loader
"Create version loader for a HTTP repository."
[repository-uri & [{:keys [username passphrase timeout]}]]
(let [opts (merge
(base-opts)
(when (string? username)
{:basic-auth [username passphrase]})
(when timeout
{:socket-timeout timeout
:conn-timeout timeout}))]
(fn [group id]
(try
(let [uri (xml/metadata-uri repository-uri group id)
{:keys [status headers body error]} (http/get uri opts)
content-type (some-> headers
(some [:content-type "content-type"])
(.split ";")
(first))]
(if-not error
(if (= status 200)
(if (contains? valid-content-types content-type)
(if (string? body)
(xml/metadata-xml->versions body)
(Exception. "invalid response body."))
(Exception.
(format "response content-type is not XML (%s): %s"
(pr-str valid-content-types)
content-type)))
(if (or (< status 300) (= status 404))
[]
(Exception.
(format "[status=%d] %s"
status
(error-messages status "request failed.")))))
error))
(catch Throwable ex
ex)))))