summaryrefslogtreecommitdiff
path: root/compojure-3.2/src/compojure/http/response.clj
diff options
context:
space:
mode:
Diffstat (limited to 'compojure-3.2/src/compojure/http/response.clj')
-rwxr-xr-xcompojure-3.2/src/compojure/http/response.clj106
1 files changed, 106 insertions, 0 deletions
diff --git a/compojure-3.2/src/compojure/http/response.clj b/compojure-3.2/src/compojure/http/response.clj
new file mode 100755
index 0000000..269e71d
--- /dev/null
+++ b/compojure-3.2/src/compojure/http/response.clj
@@ -0,0 +1,106 @@
+;; Copyright (c) James Reeves. All rights reserved.
+;; The use and distribution terms for this software are covered by the Eclipse
+;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which
+;; can be found in the file epl-v10.html at the root of this distribution. By
+;; using this software in any fashion, you are agreeing to be bound by the
+;; terms of this license. You must not remove this notice, or any other, from
+;; this software.
+
+(ns compojure.http.response
+ "Parse a Compojure route return value into a HTTP response map."
+ (:use clojure.contrib.def
+ compojure.http.helpers)
+ (:import clojure.lang.Fn
+ clojure.lang.IPersistentVector
+ java.util.Map
+ clojure.lang.ISeq
+ java.io.File
+ java.io.InputStream
+ java.net.URL
+ clojure.lang.Keyword))
+
+(defmulti update-response
+ "Update a response with an object. The type of object determines how the
+ response is updated."
+ (fn [request reponse update]
+ (class update)))
+
+(defmethod update-response Integer
+ [request response status]
+ (assoc response :status status))
+
+(defmethod update-response String
+ [request response body]
+ (let [headers (merge (:headers (content-type "text/html")) (:headers response))
+ response (assoc response :headers headers)]
+ (if (string? (:body response))
+ (merge-with str response {:body body})
+ (assoc response :body body))))
+
+(defmethod update-response ISeq
+ [request response sequence]
+ (assoc response :body sequence))
+
+(defmethod update-response File
+ [request response file]
+ (assoc response :body file))
+
+(defmethod update-response InputStream
+ [request response stream]
+ (assoc response :body stream))
+
+(defmethod update-response URL
+ [request response url]
+ (assoc response :body (.openStream url)))
+
+(defmethod update-response IPersistentVector
+ [request response updates]
+ (reduce (partial update-response request) response updates))
+
+(defmethod update-response Keyword
+ [request response kw]
+ (if (not= kw :next)
+ (update-response request response (str kw))))
+
+(defmethod update-response Fn
+ [request response func]
+ (update-response request response (func request)))
+
+(defmethod update-response nil
+ [request response _]
+ response)
+
+(defn- merge-map
+ "Merges an inner map in 'from' into 'to'"
+ [to key from]
+ (merge-with merge to (select-keys from [key])))
+
+(defn- merge-bodies
+ "Merge the bodies in 'from' into 'to'."
+ [to from]
+ (let [from (select-keys from [:body])]
+ (if (and (-> to :body string?) (-> from :body string?))
+ (merge-with str to from)
+ (merge to from))))
+
+(defn- merge-rest
+ "Merge everything but the headers, session and body."
+ [to from]
+ (merge to (dissoc from :headers :session :body)))
+
+(defmethod update-response Map
+ [request response update-map]
+ (-> response
+ (merge-map :headers update-map)
+ (merge-map :session update-map)
+ (merge-bodies update-map)
+ (merge-rest update-map)))
+
+(defvar default-response
+ {:status 200, :headers {}}
+ "Default HTTP response map.")
+
+(defn create-response
+ "Create a new response map from an update object, x."
+ [request x]
+ (update-response request default-response x))