pax_global_header00006660000000000000000000000064134731213160014513gustar00rootroot0000000000000052 comment=b25f8cc9f2ae04493ea0b0ec574acd11e54b3771 ring-codec-1.1.2/000077500000000000000000000000001347312131600135265ustar00rootroot00000000000000ring-codec-1.1.2/.gitignore000066400000000000000000000002111347312131600155100ustar00rootroot00000000000000/target /lib /classes /checkouts /codox pom.xml pom.xml.asc *.jar *.class .lein-deps-sum .lein-failures .lein-plugins .lein-repl-history ring-codec-1.1.2/.travis.yml000066400000000000000000000000501347312131600156320ustar00rootroot00000000000000language: clojure script: lein test-all ring-codec-1.1.2/CONTRIBUTING.md000066400000000000000000000020331347312131600157550ustar00rootroot00000000000000# Contributing Guidelines **Do** follow [the seven rules of a great Git commit message][1]. **Do** follow [the Clojure Style Guide][2]. **Do** include tests for your change when appropriate. **Do** ensure that the CI checks pass. **Do** squash the commits in your PR to remove corrections irrelevant to the code history, once the PR has been reviewed. **Do** feel free to pester the project maintainers about the PR if it hasn't been responded to. Sometimes notifications can be missed. **Don't** overuse vertical whitespace; avoid multiple sequential blank lines. **Don't** include more than one feature or fix in a single PR. **Don't** include changes unrelated to the purpose of the PR. This includes changing the project version number, adding lines to the `.gitignore` file, or changing the indentation or formatting. **Don't** open a new PR if changes are requested. Just push to the same branch and the PR will be updated. [1]: https://chris.beams.io/posts/git-commit/#seven-rules [2]: https://github.com/bbatsov/clojure-style-guide ring-codec-1.1.2/LICENSE000066400000000000000000000021211347312131600145270ustar00rootroot00000000000000Copyright (c) 2009-2010 Mark McGranaghan Copyright (c) 2009-2018 James Reeves Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ring-codec-1.1.2/README.md000066400000000000000000000010341347312131600150030ustar00rootroot00000000000000# Ring-Codec [![Build Status](https://travis-ci.org/ring-clojure/ring-codec.svg?branch=master)](https://travis-ci.org/ring-clojure/ring-codec) Functions for encoding and decoding data into formats commonly used in web applications. ## Installation To install, add the following to your project `:dependencies`: [ring/ring-codec "1.1.2"] ## Documentation * [API Docs](http://ring-clojure.github.com/ring-codec/ring.util.codec.html) ## License Copyright © 2019 James Reeves Distributed under the MIT License, the same as Ring. ring-codec-1.1.2/project.clj000066400000000000000000000016241347312131600156710ustar00rootroot00000000000000(defproject ring/ring-codec "1.1.2" :description "Library for encoding and decoding data" :url "https://github.com/ring-clojure/ring-codec" :license {:name "The MIT License" :url "http://opensource.org/licenses/MIT"} :dependencies [[org.clojure/clojure "1.5.1"] [commons-codec "1.11"]] :plugins [[lein-codox "0.10.3"]] :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.6:+1.7:+1.8:+1.9:+1.10" "test"]} :profiles {:dev {:dependencies [[criterium "0.4.4"]]} :1.6 {:dependencies [[org.clojure/clojure "1.6.0"]]} :1.7 {:dependencies [[org.clojure/clojure "1.7.0"]]} :1.8 {:dependencies [[org.clojure/clojure "1.8.0"]]} :1.9 {:dependencies [[org.clojure/clojure "1.9.0"]]} :1.10 {:dependencies [[org.clojure/clojure "1.10.0"]]}}) ring-codec-1.1.2/src/000077500000000000000000000000001347312131600143155ustar00rootroot00000000000000ring-codec-1.1.2/src/ring/000077500000000000000000000000001347312131600152545ustar00rootroot00000000000000ring-codec-1.1.2/src/ring/util/000077500000000000000000000000001347312131600162315ustar00rootroot00000000000000ring-codec-1.1.2/src/ring/util/codec.clj000066400000000000000000000111321347312131600177760ustar00rootroot00000000000000(ns ring.util.codec "Functions for encoding and decoding data." (:require [clojure.string :as str]) (:import java.io.File java.util.Map [java.net URLEncoder URLDecoder] org.apache.commons.codec.binary.Base64)) (defn assoc-conj "Associate a key with a value in a map. If the key already exists in the map, a vector of values is associated with the key." [map key val] (assoc map key (if-let [cur (get map key)] (if (vector? cur) (conj cur val) [cur val]) val))) (defn- double-escape [^String x] (.replace (.replace x "\\" "\\\\") "$" "\\$")) (def ^:private string-replace-bug? (= "x" (str/replace "x" #"." (fn [x] "$0")))) (defmacro ^:no-doc fix-string-replace-bug [x] (if string-replace-bug? `(double-escape ~x) x)) (defn percent-encode "Percent-encode every character in the given string using either the specified encoding, or UTF-8 by default." ([unencoded] (percent-encode unencoded "UTF-8")) ([^String unencoded ^String encoding] (->> (.getBytes unencoded encoding) (map (partial format "%%%02X")) (str/join)))) (defn- parse-bytes [encoded-bytes] (->> (re-seq #"%[A-Za-z0-9]{2}" encoded-bytes) (map #(subs % 1)) (map #(.byteValue (Integer/valueOf % 16))) (byte-array))) (defn percent-decode "Decode every percent-encoded character in the given string using the specified encoding, or UTF-8 by default." ([encoded] (percent-decode encoded "UTF-8")) ([^String encoded ^String encoding] (str/replace encoded #"(?:%[A-Za-z0-9]{2})+" (fn [chars] (-> ^bytes (parse-bytes chars) (String. encoding) (fix-string-replace-bug)))))) (defn url-encode "Returns the url-encoded version of the given string, using either a specified encoding or UTF-8 by default." ([unencoded] (url-encode unencoded "UTF-8")) ([unencoded encoding] (str/replace unencoded #"[^A-Za-z0-9_~.+-]+" #(double-escape (percent-encode % encoding))))) (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] (url-decode encoded "UTF-8")) ([encoded encoding] (percent-decode encoded encoding))) (defn base64-encode "Encode an array of bytes into a base64 encoded string." [unencoded] (String. (Base64/encodeBase64 unencoded))) (defn base64-decode "Decode a base64 encoded string into an array of bytes." [^String encoded] (Base64/decodeBase64 (.getBytes encoded))) (defprotocol ^:no-doc FormEncodeable (form-encode* [x encoding])) (extend-protocol FormEncodeable String (form-encode* [^String unencoded ^String encoding] (URLEncoder/encode unencoded encoding)) Map (form-encode* [params encoding] (letfn [(encode [x] (form-encode* x encoding)) (encode-param [k v] (str (encode (name k)) "=" (encode v)))] (->> params (mapcat (fn [[k v]] (cond (sequential? v) (map #(encode-param k %) v) (set? v) (sort (map #(encode-param k %) v)) :else (list (encode-param k v))))) (str/join "&")))) Object (form-encode* [x encoding] (form-encode* (str x) encoding)) nil (form-encode* [x encoding] "")) (defn form-encode "Encode the supplied value into www-form-urlencoded format, often used in URL query strings and POST request bodies, using the specified encoding. If the encoding is not specified, it defaults to UTF-8" ([x] (form-encode x "UTF-8")) ([x encoding] (form-encode* x encoding))) (defn form-decode-str "Decode the supplied www-form-urlencoded string using the specified encoding, or UTF-8 by default." ([encoded] (form-decode-str encoded "UTF-8")) ([^String encoded ^String encoding] (try (URLDecoder/decode encoded encoding) (catch Exception _ nil)))) (defn form-decode "Decode the supplied www-form-urlencoded string using the specified encoding, or UTF-8 by default. If the encoded value is a string, a string is returned. If the encoded value is a map of parameters, a map is returned." ([encoded] (form-decode encoded "UTF-8")) ([^String encoded encoding] (if-not (.contains encoded "=") (form-decode-str encoded encoding) (reduce (fn [m param] (if-let [[k v] (str/split param #"=" 2)] (assoc-conj m (form-decode-str k encoding) (form-decode-str (or v "") encoding)) m)) {} (str/split encoded #"&"))))) ring-codec-1.1.2/test/000077500000000000000000000000001347312131600145055ustar00rootroot00000000000000ring-codec-1.1.2/test/ring/000077500000000000000000000000001347312131600154445ustar00rootroot00000000000000ring-codec-1.1.2/test/ring/util/000077500000000000000000000000001347312131600164215ustar00rootroot00000000000000ring-codec-1.1.2/test/ring/util/test/000077500000000000000000000000001347312131600174005ustar00rootroot00000000000000ring-codec-1.1.2/test/ring/util/test/codec.clj000066400000000000000000000043511347312131600211520ustar00rootroot00000000000000(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") "$"))) (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"))) (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 "%") "%"))) (deftest test-base64-encoding (let [str-bytes (.getBytes "foo?/+" "UTF-8")] (is (Arrays/equals str-bytes (base64-decode (base64-encode str-bytes)))))) (deftest test-form-encode (testing "strings" (are [x y] (= (form-encode x) y) "foo bar" "foo+bar" "foo+bar" "foo%2Bbar" "foo/bar" "foo%2Fbar") (is (= (form-encode "foo/bar" "UTF-16") "foo%FE%FF%00%2Fbar"))) (testing "maps" (are [x y] (= (form-encode x) y) {"a" "b"} "a=b" {:a "b"} "a=b" {"a" 1} "a=1" {"a" nil} "a=" {"a" "b" "c" "d"} "a=b&c=d" {"a" "b c"} "a=b+c" {"a" ["b" "c"]} "a=b&a=c" {"a" ["c" "b"]} "a=c&a=b" {"a" (seq [1 2])} "a=1&a=2" {"a" #{"c" "b"}} "a=b&a=c") (is (= (form-encode {"a" "foo/bar"} "UTF-16") "a=foo%FE%FF%00%2Fbar")))) (deftest test-form-decode-str (is (= (form-decode-str "foo=bar+baz") "foo=bar baz")) (is (nil? (form-decode-str "%D")))) (deftest test-form-decode (are [x y] (= (form-decode x) y) "foo" "foo" "a=b" {"a" "b"} "a=b&c=d" {"a" "b" "c" "d"} "foo+bar" "foo bar" "a=b+c" {"a" "b c"} "a=b%2Fc" {"a" "b/c"} "a=b&c" {"a" "b" "c" ""} "a=&b=c" {"a" "" "b" "c"} "a&b=c" {"a" "" "b" "c"}) (is (= (form-decode "a=foo%FE%FF%00%2Fbar" "UTF-16") {"a" "foo/bar"})))