Skip to content

Commit da44a38

Browse files
committed
Replace charset String type with Charset type
By providing the default encoding as Charset, repeated lookups can be avoided in hot paths. Fixes #40.
1 parent 84a7f6f commit da44a38

2 files changed

Lines changed: 36 additions & 25 deletions

File tree

src/ring/util/codec.clj

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
(:require [clojure.string :as str])
44
(:import java.util.Map
55
clojure.lang.MapEntry
6+
java.nio.charset.Charset
67
[java.net URLEncoder URLDecoder]
78
[java.util Base64 StringTokenizer]))
89

@@ -28,13 +29,18 @@
2829
`(double-escape ~x)
2930
x))
3031

32+
(def ^:private ^Charset utf-8 (Charset/forName "UTF-8"))
33+
34+
(defn- ^Charset to-charset [s]
35+
(if (nil? s) utf-8 (if (string? s) (Charset/forName s) s)))
36+
3137
(defn percent-encode
3238
"Percent-encode every character in the given string using either the specified
3339
encoding, or UTF-8 by default."
3440
([unencoded]
35-
(percent-encode unencoded "UTF-8"))
36-
([^String unencoded ^String encoding]
37-
(->> (.getBytes unencoded encoding)
41+
(percent-encode unencoded utf-8))
42+
([^String unencoded encoding]
43+
(->> (.getBytes unencoded (to-charset encoding))
3844
(map (partial format "%%%02X"))
3945
(str/join))))
4046

@@ -53,33 +59,35 @@
5359
"Decode every percent-encoded character in the given string using the
5460
specified encoding, or UTF-8 by default."
5561
([encoded]
56-
(percent-decode encoded "UTF-8"))
57-
([^String encoded ^String encoding]
58-
(str/replace encoded
59-
#"(?:%[A-Fa-f0-9]{2})+"
60-
(fn [chars]
61-
(-> (parse-bytes chars)
62-
(String. encoding)
63-
(fix-string-replace-bug))))))
62+
(percent-decode encoded utf-8))
63+
([^String encoded encoding]
64+
(let [encoding (to-charset encoding)]
65+
(str/replace encoded
66+
#"(?:%[A-Fa-f0-9]{2})+"
67+
(fn [chars]
68+
(-> (parse-bytes chars)
69+
(String. encoding)
70+
(fix-string-replace-bug)))))))
6471

6572
(defn url-encode
6673
"Returns the url-encoded version of the given string, using either a specified
6774
encoding or UTF-8 by default."
6875
([unencoded]
69-
(url-encode unencoded "UTF-8"))
76+
(url-encode unencoded utf-8))
7077
([unencoded encoding]
71-
(str/replace
72-
unencoded
73-
#"[^A-Za-z0-9_~.+-]+"
74-
#(double-escape (percent-encode % encoding)))))
78+
(let [encoding (to-charset encoding)]
79+
(str/replace
80+
unencoded
81+
#"[^A-Za-z0-9_~.+-]+"
82+
#(double-escape (percent-encode % encoding))))))
7583

7684
(defn ^String url-decode
7785
"Returns the url-decoded version of the given string, using either a specified
7886
encoding or UTF-8 by default. If the encoding is invalid, nil is returned."
7987
([encoded]
80-
(url-decode encoded "UTF-8"))
88+
(url-decode encoded utf-8))
8189
([encoded encoding]
82-
(percent-decode encoded encoding)))
90+
(percent-decode encoded (to-charset encoding))))
8391

8492
(defn base64-encode
8593
"Encode an array of bytes into a base64 encoded string."
@@ -97,7 +105,7 @@
97105
(extend-protocol FormEncodeable
98106
String
99107
(form-encode* [^String unencoded ^String encoding]
100-
(URLEncoder/encode unencoded encoding))
108+
(URLEncoder/encode unencoded (to-charset encoding)))
101109
Map
102110
(form-encode* [params encoding]
103111
(letfn [(encode [x] (form-encode* x encoding))
@@ -121,7 +129,7 @@
121129
URL query strings and POST request bodies, using the specified encoding.
122130
If the encoding is not specified, it defaults to UTF-8"
123131
([x]
124-
(form-encode x "UTF-8"))
132+
(form-encode x utf-8))
125133
([x encoding]
126134
(form-encode* x encoding)))
127135

@@ -132,12 +140,11 @@
132140
"Decode the supplied www-form-urlencoded string using the specified encoding,
133141
or UTF-8 by default."
134142
([encoded]
135-
(form-decode-str encoded "UTF-8"))
143+
(form-decode-str encoded utf-8))
136144
([^String encoded encoding]
137145
(if (form-encoded-chars? encoded)
138146
(try
139-
(let [^String encoding (or encoding "UTF-8")]
140-
(URLDecoder/decode encoded encoding))
147+
(URLDecoder/decode encoded (to-charset encoding))
141148
(catch Exception _ nil))
142149
encoded)))
143150

@@ -162,7 +169,7 @@
162169
or UTF-8 by default. If the encoded value is a string, a string is returned.
163170
If the encoded value is a map of parameters, a map is returned."
164171
([encoded]
165-
(form-decode encoded "UTF-8"))
172+
(form-decode encoded utf-8))
166173
([^String encoded encoding]
167174
(if-not (.contains encoded "=")
168175
(form-decode-str encoded encoding)

test/ring/util/test/codec.clj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
(ns ring.util.test.codec
22
(:use clojure.test
33
ring.util.codec)
4-
(:import java.util.Arrays))
4+
(:import java.util.Arrays
5+
java.nio.charset.Charset))
56

67
(deftest test-percent-encode
78
(is (= (percent-encode " ") "%20"))
@@ -17,7 +18,10 @@
1718

1819
(deftest test-url-encode
1920
(is (= (url-encode "foo/bar") "foo%2Fbar"))
21+
(is (= (url-encode "foo/bar" nil) "foo%2Fbar"))
22+
(is (= (url-encode "foo/bar" "UTF-8") "foo%2Fbar"))
2023
(is (= (url-encode "foo/bar" "UTF-16") "foo%FE%FF%00%2Fbar"))
24+
(is (= (url-encode "foo/bar" (Charset/forName "UTF-16")) "foo%FE%FF%00%2Fbar"))
2125
(is (= (url-encode "foo+bar") "foo+bar"))
2226
(is (= (url-encode "foo bar") "foo%20bar")))
2327

0 commit comments

Comments
 (0)