summaryrefslogtreecommitdiff
path: root/compojure-3.2/src/compojure/http/middleware.clj
diff options
context:
space:
mode:
Diffstat (limited to 'compojure-3.2/src/compojure/http/middleware.clj')
-rwxr-xr-xcompojure-3.2/src/compojure/http/middleware.clj131
1 files changed, 131 insertions, 0 deletions
diff --git a/compojure-3.2/src/compojure/http/middleware.clj b/compojure-3.2/src/compojure/http/middleware.clj
new file mode 100755
index 0000000..f9a2dab
--- /dev/null
+++ b/compojure-3.2/src/compojure/http/middleware.clj
@@ -0,0 +1,131 @@
+;; 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.middleware
+ "Various middleware functions."
+ (:use compojure.http.routes
+ compojure.str-utils
+ clojure.contrib.def
+ clojure.contrib.str-utils))
+
+(defn header-option
+ "Converts a header option KeyValue into a string."
+ [[key val]]
+ (cond
+ (true? val) (str* key)
+ (false? val) nil
+ :otherwise (str* key "=" val)))
+
+(defn header-options
+ "Converts a map into an HTTP header options string."
+ [m delimiter]
+ (str-join delimiter
+ (remove nil? (map header-option m))))
+
+(defn with-headers
+ "Merges a map of header name and values into the response. Overwrites
+ existing headers."
+ [handler headers]
+ (fn [request]
+ (if-let [response (handler request)]
+ (assoc response :headers
+ (merge (:headers response) headers)))))
+
+(defn with-cache-control
+ "Middleware to set the Cache-Control http header. Map entries with boolean
+ values either write their key if true, or nothing if false.
+ Example:
+ {:max-age 3600 :public false :must-revalidate true}
+ => Cache-Control: max-age=3600, must-revalidate"
+ [handler header-map]
+ (with-headers handler
+ {"Cache-Control" (header-options header-map ", ")}))
+
+(defn with-uri-rewrite
+ "Rewrites a request uri with the result of calling f with the
+ request's original uri. If f returns nil the handler is not called."
+ [handler f]
+ (fn [request]
+ (let [uri (:uri request)
+ rewrite (f uri)]
+ (if rewrite
+ (handler (assoc request :uri rewrite))
+ nil))))
+
+(defn- remove-or-nil-context
+ "Removes a context string from the front of a uri. If it wasn't there,
+ returns nil."
+ [uri context]
+ (if (.startsWith uri context)
+ (if-not (= uri context)
+ (subs uri (count context))
+ "/")
+ nil))
+
+(defn with-context
+ "Removes the context string from the beginning of the request uri
+ such that route matching is done without it. If the context is not
+ present, the handler will not be called."
+ [handler context]
+ (with-uri-rewrite handler #(remove-or-nil-context % context)))
+
+(defn- uri-snip-slash
+ "Removes a trailing slash from all uris except \"/\"."
+ [uri]
+ (if (and (not (= "/" uri))
+ (.endsWith uri "/"))
+ (chop uri)
+ uri))
+
+(defn ignore-trailing-slash
+ "Makes routes match regardless of whether or not a uri ends in a slash."
+ [handler]
+ (with-uri-rewrite handler uri-snip-slash))
+
+(defvar default-mimetypes
+ {"css" "text/css"
+ "gif" "image/gif"
+ "gz" "application/gzip"
+ "htm" "text/html"
+ "html" "text/html"
+ "jpg" "image/jpeg"
+ "js" "text/javascript"
+ "pdf" "application/pdf"
+ "png" "image/png"
+ "swf" "application/x-shockwave-flash"
+ "txt" "text/plain"
+ "xml" "text/xml"
+ "zip" "application/zip"}
+ "Default mimetype map used by with-mimetypes.")
+
+(defn- extension
+ "Returns the text after the last . of a String or nil."
+ [s]
+ (second (re-find #"\.(\w*$)" s)))
+
+(defn- request-mimetype
+ "Derives the mimetype from a request. See with-mimetypes for options."
+ [request options]
+ (let [default (or (:default options) "text/html")]
+ (if-let [ext (extension (:uri request))]
+ (let [mimetypes (or (:mimetypes options) default-mimetypes)]
+ (get mimetypes ext default))
+ default)))
+
+(defn with-mimetypes
+ "Middleware to add the proper Content-Type header based on the uri of
+ the request. options is a map containing a :mimetype map of extension
+ to type and a :default mime type. If :mimetype is not provided, a default
+ map with common mime types will be used. If :default is not provided,
+ \"text/html\" is used."
+ ([handler]
+ (with-mimetypes handler {}))
+ ([handler options]
+ (fn [request]
+ (let [mimetype (request-mimetype request options)]
+ ((with-headers handler {"Content-Type" mimetype}) request)))))