diff options
Diffstat (limited to 'compojure-3.2/src/compojure/http/response.clj')
| -rwxr-xr-x | compojure-3.2/src/compojure/http/response.clj | 106 |
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)) |
