Skip to content

Commit cbbf102

Browse files
Richard NewmanRichard Newman
authored andcommitted
Type annotations and minor tidying.
1 parent c917372 commit cbbf102

File tree

1 file changed

+32
-22
lines changed

1 file changed

+32
-22
lines changed

src/clojure/http/client.clj

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
(:use [clojure.contrib.java-utils :only [as-str]]
33
[clojure.contrib.duck-streams :only [read-lines spit]]
44
[clojure.contrib.str-utils :only [str-join]])
5-
(:import (java.net URL URLEncoder)
5+
(:import (java.net URL
6+
URLEncoder
7+
HttpURLConnection)
68
(java.io StringReader InputStream)))
79

810
(def default-headers {"User-Agent" (str "Clojure/" *clojure-version*
@@ -28,10 +30,10 @@ representation of argument, either a string or map."
2830
(URLEncoder/encode (as-str arg) "UTF-8")))
2931

3032
(defn- send-body
31-
[body connection headers]
33+
[body #^HttpURLConnection connection headers]
3234
(.setDoOutput connection true)
33-
;; this isn't perfect, since it doesn't account for
34-
;; different capitalization etc
35+
;; This isn't perfect, since it doesn't account for
36+
;; different capitalization etc.
3537
(when (and (map? body)
3638
(not (contains? headers "Content-Type")))
3739
(.setRequestProperty connection
@@ -44,14 +46,16 @@ representation of argument, either a string or map."
4446
(cond
4547
(string? body) (spit out body)
4648
(map? body) (spit out (url-encode body))
47-
(instance? InputStream body) (let [bytes (make-array Byte/TYPE 1000)]
48-
(loop [bytes-read (.read body bytes)]
49-
(when (pos? bytes-read)
50-
(.write out bytes 0 bytes-read)
51-
(recur (.read body bytes))))))
49+
(instance? InputStream body)
50+
(let [bytes (make-array Byte/TYPE 1000)]
51+
(loop [#^InputStream stream body
52+
bytes-read (.read stream bytes)]
53+
(when (pos? bytes-read)
54+
(.write out bytes 0 bytes-read)
55+
(recur stream (.read stream bytes))))))
5256
(.close out)))
5357

54-
(defn url
58+
(defn #^URL url
5559
"If u is an instance of java.net.URL then returns it without
5660
modification, otherwise tries to instantiate a java.net.URL with
5761
url as its sole argument."
@@ -63,44 +67,49 @@ url as its sole argument."
6367
(defn- body-seq
6468
"Returns a lazy-seq of lines from either the input stream
6569
or the error stream of connection, whichever is appropriate."
66-
[connection]
70+
[#^HttpURLConnection connection]
6771
(read-lines (or (if (>= (.getResponseCode connection) 400)
6872
(.getErrorStream connection)
6973
(.getInputStream connection))
7074
(StringReader. ""))))
7175

7276
(defn- parse-headers
7377
"Returns a map of the response headers from connection."
74-
[connection]
78+
[#^HttpURLConnection connection]
7579
(let [hs (.getHeaderFields connection)]
7680
(into {} (for [[k v] hs :when k] [k (first v)]))))
7781

7882
(defn- parse-cookies
7983
"Returns a map of cookies when given the Set-Cookie string sent
8084
by a server."
81-
[cookie-string]
85+
[#^String cookie-string]
8286
(when cookie-string
8387
(into {}
84-
(for [cookie (.split cookie-string ";")]
85-
(let [keyval (map #(.trim %) (.split cookie "="))]
88+
(for [#^String cookie (.split cookie-string ";")]
89+
(let [keyval (map (fn [#^String x] (.trim x)) (.split cookie "="))]
8690
[(first keyval) (second keyval)])))))
8791

8892
(defn- create-cookie-string
8993
"Returns a string suitable for sending to the server in the
9094
\"Cookie\" header when given a clojure map of cookies."
9195
[cookie-map]
9296
(str-join "; " (map (fn [cookie]
93-
(str (as-str (key cookie))
97+
(str #^String (as-str (key cookie))
9498
"="
95-
(as-str (val cookie))))
99+
#^String (as-str (val cookie))))
96100
cookie-map)))
97101

98102
(defn request
99-
"Perform an HTTP request on url u. "
103+
"Perform an HTTP request on URL u."
100104
[u & [method headers cookies body]]
101-
(let [connection (.openConnection (url u))
102-
method (.toUpperCase (as-str (or method
103-
"GET")))]
105+
106+
;; This function *should* throw an exception on non-HTTP URLs.
107+
;; This will happen if the cast fails.
108+
(let [#^HttpURLConnection connection
109+
(cast HttpURLConnection (.openConnection (url u)))
110+
111+
method (.toUpperCase #^String (as-str (or method
112+
"GET")))]
104113
(.setRequestMethod connection method)
105114

106115
(doseq [header (conj default-headers (or headers {}))]
@@ -112,6 +121,7 @@ by a server."
112121
(.setRequestProperty connection
113122
"Cookie"
114123
(create-cookie-string cookies)))
124+
115125
(if body
116126
(send-body body connection headers)
117127
(.connect connection))
@@ -123,6 +133,6 @@ by a server."
123133
:method method
124134
:headers (dissoc headers "Set-Cookie")
125135
;; This correctly implements case-insensitive lookup.
126-
:get-header #(.getHeaderField connection (as-str %))
136+
:get-header #(.getHeaderField connection #^String (as-str %))
127137
:cookies (parse-cookies (headers "Set-Cookie"))
128138
:url (str (.getURL connection))})))

0 commit comments

Comments
 (0)