diff --git a/project.clj b/project.clj index 7cd47c7..7d9cd77 100644 --- a/project.clj +++ b/project.clj @@ -9,7 +9,7 @@ :codox {:output-path "codox" :source-uri "http://github.com/ring-clojure/ring-codec/blob/{version}/{filepath}#L{line}"} - :aliases {"test-all" ["with-profile" "default:+1.4:+1.5:+1.6:+1.7:+1.8" "test"]} + :aliases {"test-all" ["with-profile" "+1.4:+1.5:+1.6:+1.7:+1.8" "test"]} :profiles {:dev {:dependencies [[criterium "0.4.4"]]} :1.4 {:dependencies [[org.clojure/clojure "1.4.0"]]} diff --git a/src/ring/util/codec.clj b/src/ring/util/codec.clj index de57108..340a9b4 100644 --- a/src/ring/util/codec.clj +++ b/src/ring/util/codec.clj @@ -4,7 +4,8 @@ (:import java.io.File java.util.Map [java.net URLEncoder URLDecoder] - org.apache.commons.codec.binary.Base64)) + org.apache.commons.codec.binary.Base64 + org.apache.commons.codec.net.URLCodec)) (defn assoc-conj "Associate a key with a value in a map. If the key already exists in the map, @@ -57,16 +58,15 @@ "Returns the url-encoded version of the given string, using either a specified encoding or UTF-8 by default." [unencoded & [encoding]] - (str/replace - unencoded - #"[^A-Za-z0-9_~.+-]+" - #(double-escape (percent-encode % encoding)))) + (let [codec (URLCodec. (or encoding "UTF-8"))] + (.encode codec unencoded))) (defn ^String url-decode "Returns the url-decoded version of the given string, using either a specified encoding or UTF-8 by default. If the encoding is invalid, nil is returned." [encoded & [encoding]] - (percent-decode encoded encoding)) + (let [codec (URLCodec. (or encoding "UTF-8"))] + (.decode codec encoded))) (defn base64-encode "Encode an array of bytes into a base64 encoded string." @@ -112,7 +112,8 @@ or UTF-8 by default." [^String encoded & [encoding]] (try - (URLDecoder/decode encoded (or encoding "UTF-8")) + (let [codec (URLCodec. (or encoding "UTF-8"))] + (.decode codec encoded)) (catch Exception _ nil))) (defn form-decode diff --git a/test/ring/util/test/codec.clj b/test/ring/util/test/codec.clj index 36e51f6..fb76087 100644 --- a/test/ring/util/test/codec.clj +++ b/test/ring/util/test/codec.clj @@ -1,30 +1,19 @@ (ns ring.util.test.codec - (:use clojure.test - ring.util.codec) - (:import java.util.Arrays)) - -(deftest test-percent-encode - (is (= (percent-encode " ") "%20")) - (is (= (percent-encode "+") "%2B")) - (is (= (percent-encode "foo") "%66%6F%6F"))) - -(deftest test-percent-decode - (is (= (percent-decode "%s/") "%s/")) - (is (= (percent-decode "%20") " ")) - (is (= (percent-decode "foo%20bar") "foo bar")) - (is (= (percent-decode "foo%FE%FF%00%2Fbar" "UTF-16") "foo/bar")) - (is (= (percent-decode "%24") "$"))) + (:require [clojure.test :refer :all] + [ring.util.codec :refer :all]) + (:import java.util.Arrays + org.apache.commons.codec.DecoderException)) (deftest test-url-encode (is (= (url-encode "foo/bar") "foo%2Fbar")) - (is (= (url-encode "foo/bar" "UTF-16") "foo%FE%FF%00%2Fbar")) - (is (= (url-encode "foo+bar") "foo+bar")) - (is (= (url-encode "foo bar") "foo%20bar"))) + (is (= (url-encode "foo/bar" "UTF-16") "%FE%FF%00f%00o%00o%00%2F%00b%00a%00r")) + (is (= (url-encode "foo+bar") "foo%2Bbar")) + (is (= (url-encode "foo bar") "foo+bar"))) (deftest test-url-decode (is (= (url-decode "foo%2Fbar") "foo/bar" )) - (is (= (url-decode "foo%FE%FF%00%2Fbar" "UTF-16") "foo/bar")) - (is (= (url-decode "%") "%"))) + (is (= (url-decode "%FE%FF%00f%00o%00o%00%2F%00b%00a%00r" "UTF-16") "foo/bar")) + (is (thrown? DecoderException (url-decode "%")))) (deftest test-base64-encoding (let [str-bytes (.getBytes "foo?/+" "UTF-8")] @@ -58,5 +47,5 @@ "foo+bar" "foo bar" "a=b+c" {"a" "b c"} "a=b%2Fc" {"a" "b/c"}) - (is (= (form-decode "a=foo%FE%FF%00%2Fbar" "UTF-16") + (is (= (form-decode "%FE%FF%00a=%FE%FF%00f%00o%00o%00%2F%00b%00a%00r" "UTF-16") {"a" "foo/bar"})))