Permalink
Browse files

Workaround for Clojure issue CLJ-885

  • Loading branch information...
1 parent 3a71ae3 commit 31e1447b2e0318dec04f46a6ca7fc25705dad2c4 @weavejester weavejester committed Dec 18, 2011
View
26 ring-core/src/ring/util/response.clj
@@ -1,7 +1,8 @@
(ns ring.util.response
"Generate and augment Ring responses."
(:import java.io.File)
- (:require [clojure.java.io :as io]))
+ (:require [clojure.java.io :as io]
+ [clojure.string :as str]))
(defn redirect
"Returns a Ring response for an HTTP 302 redirect."
@@ -62,6 +63,27 @@
(if-let [file (get-file filepath opts)]
(response file)))
+;; In Clojure versions 1.2.0, 1.2.1 and 1.3.0, the as-file function
+;; in clojure.java.io does not correctly decode special characters in
+;; URLs (e.g. '%20' should be turned into ' ').
+;;
+;; See: http://dev.clojure.org/jira/browse/CLJ-885
+;;
+;; As a work-around, we'll backport the fix from the Clojure master
+;; branch into url-as-file.
+
+(defn- url-as-file [u]
+ (io/as-file
+ (str/replace
+ (.replace (.getFile u) \/ File/separatorChar)
+ #"%.."
+ (fn [escape]
+ (-> escape
+ (.substring 1 3)
+ (Integer/parseInt 16)
+ (char)
+ (str))))))
+
(defn resource-response
"Returns a Ring response to serve a packaged resource, or nil if the
resource does not exist.
@@ -73,7 +95,7 @@
(.replaceAll "^/" ""))]
(if-let [resource (io/resource path)]
(if (= "file" (.getProtocol resource))
- (let [file (io/as-file resource)]
+ (let [file (url-as-file resource)]
(if-not (.isDirectory file)
(response file)))
(response (io/input-stream resource))))))
View
1 ring-core/test/ring/assets/hello world.txt
@@ -0,0 +1 @@
+Hello World
View
9 ring-core/test/ring/util/test/response.clj
@@ -69,4 +69,11 @@
(is (.contains (slurp body) "clojure.java.io"))))
(testing "resource is a directory"
- (is (nil? (resource-response "/ring/assets")))))
+ (is (nil? (resource-response "/ring/assets"))))
+
+ (testing "resource is a file with spaces in path"
+ (let [resp (resource-response "/ring/assets/hello world.txt")]
+ (is (= (:body resp)
+ (.getAbsoluteFile (File. "test/ring/assets/hello world.txt"))))
+ (is (= (slurp (:body resp))
+ "Hello World\n")))))

0 comments on commit 31e1447

Please sign in to comment.